1. 개요
Django Project 배포 시 구성 방법 중 하나는 Nginx를 Reverse Proxy로 두고 중간에 WSGI로 Nginx와 Django Project 간 연결하는 방법이다. 이 때 WSGI를 지원하는 소프트웨어 중 uWSGI를 사용하게 될 경우 socket을 이용하여 상호 통신할 수 있도록 구성하는 방법이 존재하는데 이번 포스팅은 이런 환경을 Docker를 이용해 구성할 수 있도록 시도했던 내용들이다.
본 포스팅에 사용된 대략적인 Django Project Tree의 일부분이다.
.
├── Dockerfile
├── config
│ ├── __init__.py
│ ├── asgi.py
│ ├── exception.py
│ ├── settings
│ ├── type_defined.py
│ ├── urls.py
│ └── wsgi.py
├── deployment
│ ├── nginx.conf
│ └── uwsgi_sock.ini
├── docker-compose.yml
├── manage.py
├── requirements.txt
2. Nginx와 uWSGI 설정 파일
우선 deployment 밑에 nginx.conf와 uwsgi_sock.ini 파일에 대한 부분이다.
nginx.conf는 nginx 컨테이너에 volumes 설정으로 nginx 설정 파일을 호스트에서 컨테이너 내부로 넣어주기 위함이고 uwsgi_sock.ini는 django project 소스 코드로 컨테이너를 실행했을때 docker-compose에서 django를 uwsgi 실행 명령을 날리기 위해 생성해둔 파일이다.
글로만 이해하기엔 확 와닿지 않을 수 있다. 이 부분은 docker-compose.yml 부분을 기술할 때 작성된 내용을 보면 이해가 될 것이다.
2.1 nginx.conf
#user nobody;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 9901;
server_name localhost;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location / {
uwsgi_pass unix:/tmp/mysite.sock;
include uwsgi_params;
}
}
include servers/*;
}
2.2 uwsgi_sock.ini
[uwsgi]
chdir=/usr/src/app
module=config.wsgi
buffer-size = 8129
stats=0.0.0.0:3031
stats-http=true
master = true
processes = 10
socket = /tmp/mysite.sock
chmod-socket = 777
vacuum = true
chdir에 명시된 경로는 django project 소스가 위치하는 docker 컨테이너 안의 경로이다.
3. docker-compose.yml 작성하기
docker-compose.yml 작성하기에 앞서 사실 필자는 이 부분에서 생각이 꼬였었다. docker로 uwsgi socket을 사용하는 환경을 테스트하기 위해 일반적으로 uwsgi+nginx를 사용하는 순서를 생각해보자. 단순하게 나열해보면 다음과 같다.
- uWSGI 실행하면서..
- uwsgi.sock이 만들어진다.
- 기타 등등
- Nginx 실행하면서..
- 생성된 uwsgi.sock 위치를 nginx.conf에 넣어 실행한다.
정리하면 reverse proxy 역할을 해주는 nginx에서 uwsgi.sock을 찾는 과정은 이미 앞에서 uwsgi가 실행되어져 socket 생성이 끝난 시점이니 자연스럽게 nginx를 실행해도 문제가 없으며 이는 동일한 환경에서 수행된다는 점이다.
docker-comopse.yml에 위와 같은 순서를 기술하기 위해서 uwsgi 역할을 해주는 image를 실행한 다음 nginx를 실행하게 해주는 방법은 알고 대강 알고 있어도 uwsgi.sock을 서로 독립된 환경의 컨테이너일 텐데 어떻게 공유하지라는 문제가 남아있다.
3.1 docker-compose.yml
구글링하면서 알아낸건 docker-compose에 컨테이너간 데이터를 공유하기 위해 volumes을 이용할 수 있다는 점이었다. 이제 docker-compose.yml 파일을 다음과 같이 작성하자.
version: '3'
services:
django:
build:
context: .
volumes:
- uwsgi_data:/tmp
command: uwsgi -i /usr/src/app/deployment/uwsgi_sock.ini
reverse_proxy:
image: nginx:1.21.6-alpine
ports:
- "8001:9901"
volumes:
- ./deployment/nginx.conf:/etc/nginx/nginx.conf
- uwsgi_data:/tmp/
depends_on:
- django
volumes:
uwsgi_data:
volumes가 services 밖에 정의되어있다는 점에 주의하자.
3.2 Dockerfile
django.build.context에 있는 Dockerfile 즉 django를 컨테이너로 올리기 위해 사용한 Dockerfile은 다음과 같다.
FROM python:3.8-buster
ENV PYTHONUNBUFFERED=1
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY . /usr/src/app
RUN pip install -r requirements.txt
'Frame Work > Django' 카테고리의 다른 글
Django project를 src layout으로 구성하기 (0) | 2023.01.30 |
---|---|
[Django] auth_group 다루기 (0) | 2022.12.18 |
uWSGI를 알아보자 (0) | 2022.11.05 |
[Django] OneToOne Relation (0) | 2022.06.06 |
django.db.utils.IntegrityError: (1215, 'Cannot add foreign key constraint') (0) | 2022.05.07 |