728x90

docker를 사용해서 프로젝트를 배포하는 방법에 대해 리뷰해보겠습니다.

크게 django, nginx, postgresql 컨테이너를 생성하여 튜토리얼을 진행해보겠습니다.

 

1. django 컨테이너

서버 컨테이너의 경우, docker hub의 오피셜한것이 아닌 직접 빌드를 해야하기 때문에 Dockerfile 작성이 선행되어야합니다.

dockerfile에서는 프로젝트 copy, 패키지 설치 및 collectstatic만 진행합니다. 

# /Dockerfile
FROM python:3.11.4

RUN apt-get -y update
RUN apt-get -y install vim

RUN pip install --upgrade pip

COPY . /server

WORKDIR /server

RUN pip install -r requirements.txt
RUN echo yes | poetry run python manage.py collectstatic

EXPOSE 8000

기존에 만약에 static 디렉터리가 존재할경우, django에서는 overwrite할지의 여부를 묻기 때문에 echo yes를 붙여주게 되었습니다.

--> 보통, aws s3를 사용하기 때문에 대부분 존재할 경우가 있을것입니다.

 

docker-compose.yml

version: '3'

services:
  server:
    build:
      context: .
    command: >
      bash -c "python3 manage.py makemigrations --settings=config.settings.deploy
      && gunicorn --bind 0.0.0.0:8000 config.wsgi.local:application"
    ports:
      - "8000:8000"
    volumes:
      - ./server:/server

migration 과정을 dockerfile이 아닌 docker-compose에서 빌드를 하는 이유는 현재의 경우, postgresql 컨테이너가 뜨기전 미리 docker image 생성 -> postgresql up -> server up의 과정을 거치게 됩니다. 때문에 순서상의 이유로 db가 올라오지 않은 상태로 migration을 진행하게 되어 제대로 빌드가 되질 않습니다.

 

2. postgresql 컨테이너

 

postgres - Official Image | Docker Hub

Note: the description for this image is longer than the Hub length limit of 25000, so has been trimmed. The full description can be found at https://github.com/docker-library/docs/tree/master/postgres/README.md. See also docker/hub-feedback#238 and docker/

hub.docker.com

postgresql의 경우, dockerhub에 있는 이미지를 가져와 컨테이너로 활용하기 때문에 별도의 dockerfile은 필요없이 compose에 업데이트 후 django의 세팅만 수정해주신 후 의존성만 명시해주면 쉽게 해결가능합니다.

 

- docker-compose 파일 수정

version: '3'

services:
  postgres:
    image: postgres
    hostname: postgres
    restart: always
    ports:
      - "5432:5432"
    environment:
      POSTGRES_DB: "postgres"
      POSTGRES_USER: "postgres"
      POSTGRES_PASSWORD: "postgres"

  server:
    build:
      context: .
    command: >
      bash -c "python3 manage.py makemigrations --settings=config.settings.deploy
      && gunicorn --bind 0.0.0.0:8000 config.wsgi.local:application"
    ports:
      - "8000:8000"
    volumes:
      - ./server:/server
    depends_on:
      - postgres

environment 값의 경우, 만약 실제로 사용하신다면 시스템 환경변수를 이용해 설정해주시기 바랍니다.

 

- django settings.py 변경

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql",
        "NAME": "postgres",
        "HOST": "postgres",
        "USER": "postgres",
        "PASSWORD": "postgres",
        "PORT": 5432,
    }
}

docker-compose파일에 명시해준 내용과 매칭을 하게 된다면 POSTGRES_DB=NAME, POSTGRES_USER=USER, POSTGRES_PASSWORD=PASSWORD, hostname=HOST가 됩니다. 기본적으로 django에서 postgresql을 사용하기 위해선 psycopg2 설치가 선행되어야합니다.

docker에서는 기본적으로 service명=host 입니다. 위의 docker-compose에서 명시적으로 hostname을 명시하기는 했지만 만약 안했어도 기본적으로 postgres로 설정 되게 됩니다.

 

3. nginx 컨테이너

- docker-compose 수정

version: '3'

services:
  postgres:
    image: postgres
    hostname: postgres
    restart: always
    ports:
      - "5432:5432"
    environment:
      POSTGRES_DB: "postgres"
      POSTGRES_USER: "postgres"
      POSTGRES_PASSWORD: "postgres"

  server:
    build:
      context: .
    command: >
      bash -c "python3 manage.py makemigrations --settings=config.settings.deploy
      && gunicorn --bind 0.0.0.0:8000 config.wsgi.local:application"
    ports:
      - "8000:8000"
    volumes:
      - ./server:/server
    depends_on:
      - postgres
 
  nginx:
    image: nginx
    depends_on:
      - server
    volumes:
      - ./nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf
    ports:
      - "80:80"

- ./nginx/conf.d/default.conf

server {
        listen 80;
        server_name 본인 서버 호스트;
        charset utf-8;

        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;

        location / {
                proxy_pass http://server:80/;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        location /static/ {
                autoindex on;
                alias /static/;
        }
}

nginx의 기본 설정을 바라보는 경로인 /etc/nginx/conf.d/default.conf와 로컬 경로를 docker volume을 활용하여 공유 하기 때문에 미리 위와같은 default.conf 파일이 작업된상태로 존재해야합니다.

nginx의 경우, 서버가 정상적으로 실행된 이후 마지막에 웹서버가 떠있어야하므로 의존성을 server로 설정해주었고 위에서 말했듯이 docker에서는 서비스명 = 호스트가 되므로 proxy_pass를 http://server:80으로 설정해주었습니다.

 

이후엔 이전 과정의 설정이 문제없었다면 아래 명령어를 통해 배포를 진행해주시면 됩니다.

docker compose up -d --build

 

사실 db의 경우, 실제 배포시엔 따로 데이터베이스 호스트가 이미 존재해있을것이기 때문에 요구사항에 맞춰 참고용으로 봐주시면 감사드리겠습니다 :) 

 

도커를 활용하면서 느끼는점이 물론 배포시에도 큰 이점이 있지만 초기 세팅할때 정말 편하게 활용 가능하다는점이 있다고 생각합니다.

최근, 회사에 신규 입사자가 들어오시면서 도커로 빌드가 안되어있던 프로젝트와 되어 있던 프로젝트 세팅을 하며 확실히 그차이를 느낄수 있었습니다. 초기 환경 설정에 있어서 귀찮고 힘들수도 있지만 이것이 나중을 생각했을때 불러올 스노우볼을 생각해보면 정말 좋은 오픈소스 프로젝트라고 생각합니다!!

728x90
728x90

1. 서버를 관리한다는것

  • 어떠한 프로그램이 동작할때 잘돌고 있지만 뒤 즉, 서버단은 매우복잡한 논리의 집합으로 돌아가고 있는것
  • 수많은 로직들중에 하나라도 잘못되어있을경우, 전체가 돌아가지 않는다
  • 서버를 관리한다는것은 이많은 논리의 집합을 오류없이 잘돌아가도록 관리하는것
    • 하지만 너무 잦은 개발환경의 변화로 인해 리소스의 낭비가 심해졌다
    • 이를 해결하기위해 도커가 등장했다.

2. 서버관리 방식의 변화

  • 전통적인 서버관리방식
    • user추가 -> system환경 -> 방화벽 -> ... -> proxy서버 -> 서버 실행
    • 매우 복잡한 여러 방식들을 하나하나 만들어 서버를 실행시켜야함
    • 이중 하나라도 문제가 생겼을때 전체적으로 오류가 발생함
  • 도커의 등장으로 인해..
    • user컨테이너, chat 컨테이너...와 같이 여러 기능들을 하나의 컨테이너처럼 독립적으로 실행시킬수 있음
    • 하나의 오류가 생기더라도 독립적으로 실행되고 있기때문에 문제가 없고 매우 효율적으로 서버 동작
  • 가상머신과 비교
    • 매우빠르다
    • 초기 환경 세팅을 일일이 할필요가 없다
    • 따라서 매우 효율적이다

3. 도커의 등장 배경

  • 서버 실행 방법 문서화
    • 서버를 실행할때 설치할 과정이나 주의점을 문서화를 통해 후임자나 다른사람에게 공유
    • 이문서가 정확할지? 누락된 부분이 있어 그대로 실행안됨...과 같은 문제점이 있음
  • 상태관리 도구 도입(chef, puppet, ansible...)
    • webserver, library등 문서로만 적혀있는것이 아닌 코드로 관리함으로써 환경을 공유하고 쉽게 설치 하게 개선
    • 각각의 서버, 여러 환경때문에 제대로 적용이 안되는 문제점이 있음
  • 가상머신
    • 여러 기능등을 각각의 가상머신에 설치한뒤 이 가상머신을 관리할수 있는 서버에 띄어둠
    • 한서버에 여러개 설치가 가능하고, 현재의 상태를 저장할수 있는 엄청난 이점
    • 처음부터 다시 셋팅할대 어려움이 있음, 매우느림, 공유하기 어려운 문제점이 있음
  • 도커의 등장!
    • 컨테이너: 격리된 환경에서 작동하는 프로세스
    • 하드웨어 가상화 기술보다 가벼움
    • 이미지 단위의 프로세스 실행 환경을 구성
    • 즉, 위의 여러 문제점을 모두 개선한 컨테이너 기술!

4. 도커의 장점

  • 확장성/이식성
    • 도커가 설치되어 있다면 어디서든 컨테이너 실행 가능
    • 쉽게 개발서버를 만들수 있고 테스트서버 생성또한 간편함
  • 표준성
    • 도커를 사용하지 않는 경우 여러 프레임워크로 만든 서비스들의 배포 방식이 매우 다양함
    • 컨테이너라는 표준으로 서버를 배포하므로 모든 서비스들의 배포 과정이 동일해짐
  • 이미지
    • 컨테이너를 실행하기위한 하나의 압축 파일과 같음
    • 이미지에서 컨테이너를 생성하기 때문에 반드시 이미지를 만드는 과정 필요
    • Dockerfile을 이용하여 이미지를 만들고 처음부터 재현 가능
  • 설정관리
    • 설정은 보통 환경변수로 제어
    • 하나의 컨테이너를 띄울때 환경변수를 같이 지정
  • 자원관리
    • 컨테이너는 삭제 후 새로 만들면 모든 데이터가 초기화됨
    • 업로드 파일을 외부 스토리지와 링크하여 사용하거나 s3같은 별도의 저장소가 필요함

 

ref. 인프런 강의. 초보를 위한 도커 안내서를 보고 참고하여 정리하였습니다.

 

Docker - 도커란 무엇인가

도커, 도커를 사용하는 이유, 도커의 특징 이해

wooody92.github.io

 

초보를 위한 도커 안내서 - 인프런 | 강의

도커를 1도 모르는 입문자, 초보자분들을 위한 도커 안내서 입니다. 복잡한 내용을 제외하고 도커가 왜 인기가 많고 어떻게 사용하는지 빠르게 익힐 수 있도록 집중하였습니다., 데브옵스 입문

www.inflearn.com

 

728x90

'기술 > Devops' 카테고리의 다른 글

aws(2)VPC(Virtual Private Cloud)  (0) 2022.04.19
aws(1)S3(Simple Storage Services)  (0) 2022.04.19
도커(4)-이미지  (0) 2022.01.19
도커(3)-도커 컴포즈  (0) 2022.01.17
도커(2)-도커 설치와 실행  (0) 2022.01.17

+ Recent posts