안녕세계

[Django] Docker 컨테이너 배포 (nginx & gunicorn) 본문

[Django] Docker 컨테이너 배포 (nginx & gunicorn)

Junhong Kim 2019. 1. 1. 22:02
728x90
반응형

안녕하세요.

이번 포스팅에서는 Docker Compose를 활용하여 Django 애플리케이션을 배포하는 방법에 대해 알아봅니다.

Dockerfile 작성

# <django_project>/Dockerfile

FROM python:3.6.4
RUN mkdir /code
WORKDIR /code

ADD requirements.txt /code/
RUN pip install -r requirements.txt
ADD . /code/

 

(1) FROM python:3.6.4

- 파이썬 3.6.4버전을 베이스 이미지로 사용합니다.

(2) RUN mkdir /code

- 컨테이너에 /code 디렉토리를 생성합니다.

(3) WORKDIR /code 

- /code 디렉토리로 워킹 디렉토리를 변경합니다.

(4) ADD requirements.txt /code/

- 로컬 위치의 requirements.txt 파일을 /code 디렉토리 하위로 복사합니다.

(5) pip install -r requirements.txt

- 프로젝트에 필요한 파이썬 패키지를 설치합니다.

(6) . /code/

- 로컬 위치의 모든 파일 및 디렉토리를 /code/ 디렉토리 하위로 복사합니다.

docker-compse.yml 작성

docker-compose를 활용하여 Dockerfile을 build할 준비를 합니다.

# <django_project>/docker-compose.yml

version: '3'
services:
  web:
    build:
      context: .
      dockerfile: Dockerfile
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/code
    ports:
      - "8000:8000"

 

(1) version

- doceker compose 정의 파일의 버전

(2) services

- 서비스 정의

(3) web

- 서비스명

(4) build

- 빌드 지정

(5) context

- Dockerfile이 있는 디렉토리의 경로

(6) dockerfile

- 도커파일명

(7) command

- 컨테이너 안에서 작동하는 명령 지정

- 베이스 이미지에 지정 되어있을 경우 덮어씁니다.

(8) volumes

- 컨테이너에 볼륨을 마운트합니다.

(9) ports

- 컨테이너가 공개하는 포트는 ports로 지정합니다.

- <호스트 머신의 포트 번호>:<컨테이너의 포트 번호>

docker-compose 명령어로 이미지를 빌드하여 실행

$ docker-compose up --build

위 명령어를 실행한 뒤 웹 브라우저에서 django 애플리케이션이 정상적으로 실행되었는지 확인합니다.

nginx & gunicorn + django

nginx와 gunicorn을 이용하여 django 애플리케이션을 배포하는 과정을 알아봅니다.

위에서 작성한 docker-compose.yml 파일을 다음과 같이 수정합니다.

# <django_project>/docker-compose.yml

version: '3'
services:
  nginx:
    image: nginx:latest
    ports:
      - "80:80"
    volumes:
      - .:/code
      - ./config/nginx:/etc/nginx.conf.d
    depends_on:
      - web
  web:
    build:
      context: .
      dockerfile: Dockerfile
    command: gunicorn <django_project>.wsgi:application --bind 0.0.0.0:8000
    # settings.py 환경분리 되어있어 settings를 지정해야하는 경우 다음과 같이 추가 입력
    # [--env DJANGO_SETTINGS_MODULE='<django_project>.settings.production']
    volumes:
      - .:/code
    expose:
      - "8000"

(1) version

- docker compose 정의 파일의 버전

(2) services

- 서비스 정의

(3) nginx

- 서비스명

(4) image

- 도커 이미지 (d2hub에서 최신 버전)

(5) ports

- <호스트 머신의 포트 번호>:<컨테이너의 포트 번호>

(6) volumes

- 컨테이너에 볼륨을 마운트할 때 사용됩니다.

- <호스트의 디렉토리 경로>:<컨테이너의 디렉토리 경로>

(7) depends_on

- 서비스의 의존관계 정의

- ngix 컨테이너를 시작하기 전에 web 컨테이너를 시작합니다.

- depends_on은 컨테이너의 시작 순서만 제어

- 컨테이너상의 애플리케이션이 이용 가능해 질 때까지 기다리고 제어를 하지 않습니다.

(8) web

- 서비스명

(9) build

- 빌드 지정

(10) context

- Dockerfile이 있는 디렉토리의 경로

(11) dockerfile

- 도커파일명

(12) command

- 컨테이너 안에서 작동하는 명령 지정

- 여기서는 gunicorn으로 django 서버를 실행합니다

(13) volumes

- 현재 디렉토리 전부를 컨테이너의 /code에 마운트합니다.

(14) ports

- 컨테이너 포트 번호만 지정합니다.

- 호스트 머신의 포트는 랜덤한 값으로 설정됩니다.

- 호스트 머신에서 직접 접근하지 않고 웹 서버 기능을 갖고 있는 컨테이너를 경유해서 접근하기 때문

nginx.conf 파일 생성

# <django_project>/config/nginx/nginx.conf
# proxy_pass 지시자를 통해 nginx가 받은 요청을 넘겨줄 서버를 정의

upstream web {
  # 클라이언트 IP를 hash 후 특정 클라이언트는 특정 서버로 연결
  ip_hash;
  server web:8000;
}

server {
  # static 파일을 제공해야할 경우
  location /static/ {
    alias /code/static;
  }

  # 프록시 설정, nginx 뒤에 WAS가 있을 경우  
  location / {
    proxy_pass http://web/;
  }

  # 포트 설정
  listen 80;
  server_name localhost;
}

gunicorn 설치

$ pip install gunicorn
$ pip freeze > requirements.txt

django 설정 수정

# <django_project>/settings.py

...
ALLOWED_HOSTS = ['web']
...

docker-compose 명령어로 이미지를 빌드하여 실행

$ docker-compose up --build

웹 브라우저에 localhost를 입력하여 정상적으로 작동하는지 확인합니다.


참고

https://aws.amazon.com/ko/docker/

https://www.slideshare.net/raccoonyy/docker-compose-usages

http://nberserk.github.io/default/2016/02/23/docker-django.html

http://ruddra.com/2016/08/14/docker-django-nginx-postgres/

https://teamlab.github.io/jekyllDecent/blog/tutorials/docker%EB%A1%9C-django-%EA%B0%9C%EB%B0%9C%ED%95%98%EA%B3%A0-%EB%B0%B0%ED%8F%AC%ED%95%98%EA%B8%B0(+-nginx,-gunicorn)

728x90
반응형
Comments