Nginx 를 이용한 Django 배포 (feat. Docker)

runserver로만 장고 서버를 구동하고 있었는데, 성능이나 안정성 이슈가 있다고 한다. django의 runserver 커맨드는 주로 테스트용으로 사용되며, production 용도로는 WAS(Nginx, gunicorn)과 연동하여 배포하는 것이 일반적인 방법이다. 따라서 프로젝트를 진행하면서 django에 웹 서버인 nginx를 연동하는 과정이 있었다.

Docker를 이용하여 nginx를 쉽게 연동하는 방법이 있어 소개해보자 한다.

기존 장고 프로젝트가 있는 상태를 가정하고 진행하겠다. 우분투 기준으로 설명하려한다.

  1. 가상환경으로 들어가서 gunicorn을 설치한다. (무거운 uWSGI 대신 gunicorn으로 nginx와 연결하였다)

    • 참고로 uWSGI나 gunicorn같은 웹서버를 쓸 때, static file을 모으지 않으면 css가 적용되지 않은 상태로 나온다. 해결을 위해서,

      1. settings.py에 아래 코드 추가

        STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
      2. collectstatic 명령어를 통해 static file을 모아줌

        python manage.py collectstatic
  2. source venv/bin/activate pip install gunicorn

  3. 도커 설치

    • 설치에 필요한 패키지들 설치
    • sudo apt-get update && sudo apt-get install \ apt-transport-https \ ca-certificates \ curl \ software-properties-common
    • ppa관련 에러가 뜬다면 아래 스크립트 실행
    • sudo add-apt-repository -r ppa:jonathonf/python-3.6 sudo apt update
    • 도커 설치
    • curl -fsSL https://get.docker.com/ | sudo sh
    • 설치된 도커는 아래 스크립트로 확인할 수 있다.permission denied가 난다면, /var/run/docker.sock 파일의 권한을 변경
    • sudo chmod 666 /var/run/docker.sock
    • docker version
  4. 프로젝트의 루트 디렉토리에 Dockerfile 이라는 파일을 추가해준다. 내용은 아래와 같다.

    • 파이썬 버전에 맞게 첫 줄을 작성해주고
    • 도커 내에서 /code 라는 이름의 폴더를 생성
    • 로컬의 requirements.txt 파일을 mount하고 패키지를 설치하는 과정
    • 현재 로컬의 모든 파일, 폴더를 /code/ 로 마운트
  5. FROM python:3.6 RUN mkdir /code WORKDIR /code ADD requirements.txt /code/ RUN pip install -r requirements.txt ADD . /code/

  6. nginx 폴더를 만들고, nginx.conf 파일 생성server_name에는 도메인 주소를 넣으면 된다. (ex> ec2-54-180-94-185.ap-northeast-2.compute.amazonaws.com)

  7. server { location / { proxy_pass http://web:8000/; } location /static/ { alias /static/; } listen 80; server_name <도메인 주소>; }

  8. 프로젝트의 루트 디렉토리에 docker-compose.yml 파일 생성<프로젝트이름> 는 wsgi.py가 속한 폴더의 이름 (커스텀하지 않는다면 프로젝트 이름)

  9. depends_on을 통해 순서가 있게 서비스가 실행될 것이다. (web -> nginx)

  10. version: '3' services: nginx: image: nginx:latest ports: - '80:80' volumes: - .:/code - ./nginx:/etc/nginx/conf.d - ./staticfiles:/static depends_on: - web web: build: context: . dockerfile: Dockerfile command: gunicorn <프로젝트이름>.wsgi:application --bind 0.0.0.0:8000 volumes: - .:/code - ./staticfiles:/staticfiles expose: - '8000'

  11. settings.py의 ALLOWED_HOSTS에 'web'을 추가

  12. ALLOWED_HOSTS = ['web']

  13. 도커를 실행하고, 브라우저에서 도메인명을 입력하여 정상 작동하는지 확인

    • docker-compose 설치
    sudo pip install docker-compose
    docker-compose up --build

    shell을 꺼도 작동을 하도록 백그라운드 실행을 원한다면 -d 옵션을 추가하면 된다.

  14. docker-compose up --build -d

+ Recent posts