[Django]Docker-compose로 Django 환경 구축하기 5 - Nginx
SW개발/Django

[Django]Docker-compose로 Django 환경 구축하기 5 - Nginx

Nginx

Django는 Web Framework이며 Web Server로서의 기능을 하지 못한다. Production 환경을 구성할 경우에 Web Server가 필요하게 되는데 이 때 주로 Nginx를 사용하게 된다. 이번 포스팅에서는 Nginx를 Docker Container 환경에 띄우는 과정을 다뤄볼 것이다.

마찬가지로 docker-compose.yml에 내용을 추가하면서 시작해보자.

 

Web Server는 주로 웹 페이지를 클라이언트로 전달하는 기능(css, html 문서 등)을 담당하며 부가적으로 Proxy, Reverse Proxy와 같은 기능들도 지원한다.

 

docker-compose.yml 추가
# yml 파일 포맷의 version 설정
version: "3"

# docker-compose 볼륨 정의 (이 볼륨은 도커가 관리함)
volumes:
  postgres_db_dev: {}

# 띄울 컨테이너 목록
services:
  # Database container, 추후에 설명
  postgres:
    container_name : postgres_service
    # dockerhub의 postgres9.5 이미지 사용
    image: postgres:9.5
    # postgres_db_dev를 컨테이너 ~/data에 마운트
    volumes:
      - postgres_db_dev:/var/lib/postgresql/data
    # postgres 환경 변수
    environment: 
      - POSTGRES_DB=leffedb
      - POSTGRES_USER=leffe
      - POSTGRES_PASSWORD=leffe
      - POSTGRES_INITDB_ARGS=--encoding=UTF-8\

  # Django container
  django:
    # 컨테이너 명
    container_name : django_service
    # docker build 옵션
    build:
      # docker build 명령어를 실행할 디렉토리 경로
      context: .
      # 지정할 Dockerfile 경로
      dockerfile: ./Dockerfile
    # 환경 변수 설정  
    environment: 
      - POSTGRES_DB=leffedb
      - POSTGRES_USER=leffe
      - POSTGRES_PASSWORD=leffe
      - POSTGRES_HOST=postgres
      - POSTGRES_PORT=5432
      - RABBITMQ_USER=guest
      - RABBITMQ_PASSWORD=guest
      - RABBITMQ_HOST=rabbitmq
    # 현재 디렉토리를 컨테이너 내의 /home/에 mount
    volumes: 
      - ./:/home/
    # 작업 폴더 지정
    working_dir : /home/
    # 실행할 명령어
    command: > 
      bash -c "
      chmod +x /wait-for-it.sh
      && /wait-for-it.sh postgres:5432 -t 10
      && python3 manage.py migrate
      && python3 manage.py runserver"
    # 호스트 OS와 컨테이너의 포트를 바인딩
    ports: 
      - "8000:8000"
    # 호스트 OS에 포트를 공개하지 않고 컨테이너만 포트를 공개 (현재는 주석)
    #expose : 
    #  - "8000"
    # 컨테이너를 실행하는 종속성을 정의
    depends_on:
      - redis
      - rabbitmq
    
  # Redis
  redis:
    container_name: redis_service
    image: redis
    ports:
      - "6379:6379"
      
  # RabbitMQ
  rabbitmq:
    container_name: rabbitmq_service
    image: rabbitmq:3.7.14-management-alpine # 웹 UI management 툴 포함
    # 환경변수 설정
    environment: 
      - RABBITMQ_USER=guest
      - RABBITMQ_PASSWORD=guest
    ports:
      - "5672:5672" # rabbitMQ default port
      - "15672:15672" # UI를 위한 port
      
  # Nginx
  nginx:
    image: nginx
    container_name : nginx_service
    volumes: 
      # nginx.conf 설정을 위한 파일 -> /etc/nginx/conf.d/leffe.conf 에 mount
      - ./leffe.conf:/etc/nginx/conf.d/leffe.conf
    ports:
      - "80:80" # Nginx default port
    depends_on : 
      - django

이번에도 역시 이미지는 docker hub에 존재하는 nginx 이미지를 사용한다. 다른 부분은 타 서비스의 작성방법과 거의 유사하다.

한 가지 다른점은 nginx.conf에 대한 설정을 지정하기 위해 leffe.conf 라는 파일을 volumes에 적어주었다. 이를 통해 nginx의 설정값을 제어할 수 있게 되어 reverse proxy 기능과 같은 것을 이용할 수 있다.

 

leffe.conf 파일 추가

해당 파일을 현재 프로젝트의 루트 디렉토리에 추가한다.

server {
    # listen -> 포트 80번으로 설정 (default)
    listen 80; 
    # reverse proxy를 위한 서버 주소
    server_name 127.0.0.1;
    
    # http://127.0.0.1/chat 의 경우 
    location /chat {
        # proxy 헤더 설정
        proxy_http_version 1.1;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
        proxy_set_header Host $http_host;
        proxy_set_header X-NginX-Proxy true;
        proxy_set_header Content-Type $content_type;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        # 프록시 할 주소, django -> 서비스명, 8080 -> 8080번 포트로 프록시
        proxy_pass http://django:8080;
    }
    # http://127.0.0.1/ 의 경우 
    location / {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
        proxy_set_header Host $http_host;
        proxy_set_header X-NginX-Proxy true;
        proxy_set_header Content-Type $content_type;
        # 프록시 할 주소, django -> 서비스명, 8000 -> 8000번 포트로 프록시
        proxy_pass http://django:8000;
    }
}

대부분의 설명은 주석을 통해 적어 두었다. 한 가지 중요한 부분은 proxy_pass 부분에 주소명 대신 django 라는 이름을 적어두었는데, 이는 docker-compose.yml 에 명시한 service를 뜻한다. 따라서 저렇게 적으면 docker가 내부에서 django 이름을 가진 service 의 호스트를(IP주소) 찾아 자동으로 변환해준다.

 

필자의 경우 /chat 의 주소로 웹소켓을 활용하기 때문에 이를 reverse proxy하기 위한 용도로 포트 번호를 websocket 포트인 8080번으로 설정해 주었다. 또한, 기본적인 / 로 들어오는 요청의 경우에는 Gunicorn의 8000번 포트로 설정해 주었다. 각자의 상황에 맞는 설정 파일을 만들어 작성하면 될 것이다. (현재 설정파일은 reverse proxy 용도로 작성되었습니다.)

 

위의 과정을 모두 거친 후 $ docker-compose up -d --build 명령어를 통해 빌드를 재 진행한다.

$ docker-compose ps 명령어를 이용해 띄워진 5개의 컨테이너(django, postgres, redis, rabbitMQ,. Nginx)를 확인할 수 있다.

 

다음 포스팅에서는 위의 과정에 Celery를 붙이는 방법을 알아볼 것이다.

 

공부하면서 정리한 내용이니 틀린 부분이 있을 수 있습니다. 댓글로 남겨주시면 감사하겠습니다.

 

728x90