0. 들어가며
docker와 django 배포 작업을 안한지 너무 오래되었고, 기억이 잘 안나서 이 참에 블로그로 정리해보려고 한다.
Python으로 rest api 서비스를 오픈할 수 있지만 Django의 runserver는 단순히 테스트만을 위한 기능이기 때문에 운영 배포 목적으로 하는 서비스에서 사용하면 성능상 문제를 겪게 된다.
Web Application은 Django를 사용할 것이며, 앞단에 Web Server인 Nginx를 리버스 프록시로 두고 Django와 Nginx를 Wsgi(Gunicorn)으로 연동하는 작업을 할 것이다.
Gunicorn을 사용하는 이유는 uWSGI나 Gunicorn 등은 Nginx로 들어오는 HTTP Request를 파이썬이 이해할 수 있게 동시 통역하는 존재들이다. 여기서 Gunicorn(Wsgi)는 멀티 쓰레드를 만들 수 있기 때문에 Request가 많아지더라도 효율적으로 처리할 수 있는 즉, 운영 환경에서 python runserver보다 더 적합하다고 할 수 있다.
1. Nginx를 리버스 프록시로 사용
위의 사진처럼 Nginx를 리버스 프록시로 사용할 것이다.
Nginx를 HTTP 서버에 대한 리버스 프록시로 구성하려면 도메인의 서버 블록 구성 파일을 열고 해당 파일 내부에 위치 및 프록시 서버를 지정한다.
본인은 nginx.conf에 nginx 설정 옵션과 server에 대한 옵션을 한번에 설정하였다.
# ${PWD}/nginx/nginx.conf
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events{
worker_connections 1024;
}
http{
server {
listen 80;
server_name localhost;
include mime.types;
location /static/{
alias /data/static/;
}
location / {
proxy_pass http://django:8000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}
프록시 서버 URL은 proxy_pass 옵션을 사용하여 설정되며 프로토콜, 도메인 이름 또는 IP 주소로 HTTP 또는 HTTPS를 사용할 수 있다.
위의 구성은 Nginx에게 모든 요청을 / 위치에 http://django:8000 프록시 서버로 전달하도록 하는 명령어들이다.
여기서 만약 클라이언트가 http://localhost에 접속할 경우, Nginx는 이 요청을 http://django:8000으로 요청을 대신 보내준다는 의미이다.
(Nginx의 옵션에 대한 설명은 다음 글에 정리하도록 하겠음)
2. Django 웹 애플리케이션, Mariadb 설정
# ${PWD}/Dockerfile
FROM python:3.9.0
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED=1
COPY ./ /home/django/
WORKDIR /home/django/
RUN apt-get update
RUN apt-get install -y --no-install-recommends gcc
RUN pip install --upgrade pip
RUN pip install -r requirements.txt
# ${PWD}/docker-compose.yml
version: "3"
services:
mariadb:
image: mariadb:10.5
platform: linux/amd64
container_name: mariadb
networks:
- docker
ports:
- 3306:3306
volumes:
- ${PWD}/database:/var/lib/mysql
environment:
MARIADB_ROOT_PASSWORD: 1234
MARIADB_DATABASE: docker_lab
django:
build: .
container_name: django
command:
- bash
- -c
- |
python manage.py migrate
python manage.py runserver 0.0.0.0:8000
networks:
- docker
ports:
- 8000:8000
volumes:
- ${PWD}:/home/django
depends_on:
- mariadb
expose:
- 8000
restart: always
nginx:
image: nginx:latest
container_name: nginx
ports:
- 80:80
volumes:
- ${PWD}/nginx/nginx.conf:/etc/nginx/nginx.conf
- ${PWD}/data/static:/data/static
networks:
- docker
depends_on:
- django
networks:
docker:
위는 Django의 Dockerfile이고 django, maraidb, nginx를 하나의 도커 컴포즈 파일로 묶어두었다.
nginx 볼륨에 nginx.conf 파일의 경로로 두고 static의 경로는 nginx.conf에 location /static/에 따로 설정한 경로로 둔다.
위의 컴포즈 파일을 실행시키면 :8000번 포트뿐만 아닌 80번 포트로도 접근할 수가 있다.
3. Gunicorn으로 실행
python runserver말고 gunicorn으로 실행시켜야 한다.
django:
build: .
container_name: django
command:
- bash
- -c
- |
python manage.py migrate
gunicorn --bind 0:8000 config.wsgi:application
위 코드처럼 docker-compose.yml 파일에서 command 부분을 수정하면 된다.
'DevOps > Docker' 카테고리의 다른 글
[Docker] 도커의 데이터 관리 및 저장 (volume, mount) (0) | 2022.10.26 |
---|---|
[Docker] ports (docker run -p)와 Dockerfile의 EXPOSE 차이점 (0) | 2022.10.26 |
[Docker] 로컬에서 docker-compose를 이용한 Gunicorn 적용 (2) (0) | 2022.06.02 |
[Docker] 로컬 환경에서 Django와 MySQL을 docker-compose로 구동 (with. .env파일생성) (1) (0) | 2022.06.02 |
[Docker] Docker 이미지 종류 (with. Python) (0) | 2022.06.01 |