
솔직히 말하자면 여기서 부터는 내가 한 것이 거의 없다. 남이 만든 코드들을 보면서 내용을 추론하고 기여붙인 것 밖에 없다. 이게 정상적인 과정인지도 잘 모르고, 무슨 일이 일어날지 모른다. 다만 작동 자체는 문제 없었다.
미리 보여주는 최종 디렉토리 구성. django project와 mysql, nginx를 각각 분리하였고, docker-compose.yml은 최상위 디렉토리에, Dockerfile은 각 디렉토리에 배치했다. db 폴더속에 .env는 db 연결시 필요한 계정 정보를 분리한 것이다.
nginx 폴더에 있는 두 .conf 파일은 서버 설정을 위해 작성한 것이다. 프로젝트를 만들 당시에 이게 무슨 의미일지 알아볼 생각도 못했으나 지금은 이해할 수 있는 범위까지 무슨 의미인지 살펴볼 것이다.
#ngnix.conf
# Nginx 서버의 소유자 및 실행 사용자를 정의합니다.
user nginx;
# 사용할 작업 프로세스 수를 정의합니다.
# 권장 값은 서버에서 사용하는 코어 수입니다
worker_processes 1;
# 오류 로그의 파일 시스템 위치와 로그 메시지의 최소 심각도를 정의합니다.
error_log /var/log/nginx/error.log warn;
# 메인 Nginx 프로세스의 프로세스 ID를 저장할 파일을 정의합니다.
pid /var/run/nginx.pid;
# 이벤트 블록: 연결 처리에 영향을 주는 매개 변수 정의
events {
# 작업 프로세스에서 동시에 열 수 있는 최대 연결 수를 정의합니다
worker_connections 1024;
}
# HTTP 블록: Nginx가 HTTP 웹 트래픽을 처리하는 방법에 대한 매개 변수 정의
http {
# Nginx에서 지원하는 파일 유형 목록을 정의하는 파일을 포함시킵니다.
include /etc/nginx/mime.types;
# 사용자에게 반환되는 기본 파일 유형을 정의합니다.
default_type text/html;
# 로그 메시지의 형식을 정의합니다.
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
# NGINX에 대한 액세스 시도 로그의 위치를 정의합니다.
access_log /var/log/nginx/access.log main;
# 정적 콘텐츠 전송 최적화를 위한 매개 변수를 정의합니다.
sendfile on;
tcp_nopush on;
tcp_nodelay on;
# 클라이언트와의 keep-alive 연결에 대한 타임아웃 값을 정의합니다.
keepalive_timeout 65;
# 데이터 전송량을 줄이기 위해 gzip 압축 알고리즘 사용을 정의합니다.
#gzip on;
# 가상 호스트/서버에 대한 추가 매개 변수를 포함시킵니다.
# /etc/nginx/conf.d/ 디렉토리 내의 모든 .conf 파일들이 포함됩니다.
include /etc/nginx/conf.d/*.conf;
}
- user : nginx 가 실행되는 권한이다. user 값이 root로 되어있으면 악의적인 유저가 탈취시 문제가 발생할 수 있어 'nginx','www','www-data' 와 같은 명칭으로 바꿔준다고 한다.
- worker_process : 워커 프로세스를 몇개 실행할지 지정하는 것.
- worker_connections : 워커 프로세스당 몇 개의 동시 접속을 처리할지 지정한다. 설정대로라면 우리는 한번에 1024개의 접속을 처리할 수 있다.
#project.conf
server {
# Nginx가 수신 대기할 포트를 설정합니다. 여기서는 80 포트를 사용합니다.
# 서버 도메인 또는 IP 주소를 설정합니다. 이 경우 IP 주소가 사용되었습니다.
listen 80;
server_name ***.***.***.***;
location / {
# 모든 요청을 django_app이라는 다른 컨테이너로 프록시 전달합니다.
proxy_pass http://django_app:80;
# Do not change this
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# 정적 파일에 대한 요청을 처리하기 위한 경로를 설정합니다.
# 이 경우, 요청이 /media/ 경로로 들어오면 /media/ 경로에서 파일을 찾습니다.
location /static/ {
alias /statics/;
}
# 미디어 파일에 대한 요청을 처리하기 위한 경로를 설정합니다.
# 이 경우, 요청이 /media/ 경로로 들어오면 /media/ 경로에서 파일을 찾습니다.
location /media/{
alias /media/;
}
}
당시에 내가 봤던 자료를 따라 nginx.conf 와 project.conf로 나누어서 웹서버 전반에 대한 설정과 프로젝트 웹 서버의 설정을 담았다. 아마 여러개의 프로젝트를 돌린다면 nginx.conf와 복수의 project.conf로 구성되지 않을까? 싶다.
- listen 80 : 실제로 서비스할 것을 가정했기 때문에 포트 80으로 설정 했다.
- server_name : 서버의 ip 주소를 설정하는 곳이다. 나의 경우에는 도메인이 없어서 AWS에서 탄력적 IP를 받아 기입했다.
- proxy_pass : reverse proxy를 사용하여 대신 연결해줄 곳 -> 내가 만든 app의 80번 포트
- location 설정 : 정적 파일과 미디어 파일에 대한 참조, 기준은 docker-compose를 따른다.
#dockerfile
FROM nginx:1.15.8
RUN rm /etc/nginx/nginx.conf
COPY nginx.conf /etc/nginx/
RUN rm /etc/nginx/conf.d/default.conf
COPY project.conf /etc/nginx/conf.d/
docker-compose 빌드시 실행되는 nginx 쪽 dockerfile. 서버 설정이 적용이 안되어서 매 빌드마다 conf를 붙여넣기 하도록 하였다.
# start from an official image
FROM python:3.8
# arbitrary location choice: you can change the directory
WORKDIR /app
# install our two dependencies
COPY ./django/requirements.txt requirements.txt
RUN pip install --upgrade pip
RUN pip install gunicorn
RUN pip install -r requirements.txt
# copy our project code
COPY . .
django app의 dockerfile. pip을 최신화 한뒤 nginx와 django 앱 사이의 wsgi 인 gunicorn을 설치하고 requirements.txt 내용대로 모듈을 모두 설치한다. 마지막으로 django-app 폴더를 전부 복사한다.
#docker-compose.yml
version: '3.8'
services:
nginx:
container_name: nginx
image: nginx:latest
build:
context: ./config/nginx
dockerfile: Dockerfile
ports:
- "80:80"
volumes:
- ./django:/app
- ./config/nginx:/etc/nginx.conf.d
- ./django/staticfiles:/statics
- ./django/media:/media
depends_on:
- django_app
mysql:
image: mysql:8.0.29
container_name: mysql
expose:
- "3306"
env_file:
- "./config/db/.env"
environment:
TZ: Asia/Seoul
volumes:
- ./config/db/data:/var/lib/mysql
command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
django_app:
container_name: django_app
build:
context: .
dockerfile: ./django/Dockerfile
command: bash -c "
python3 manage.py collectstatic --no-input &&
python3 manage.py makemigrations &&
python3 manage.py migrate &&
gunicorn MyCommunity.wsgi:application --bind 0.0.0.0:80"
depends_on:
- mysql
links:
- mysql:mysql
restart: always
volumes:
- ./django:/app
위에서부터 설명하자면 python 3.8을 기준으로 3개의 컨테이너를 설치하여 각각 설정에 맞게 실행하게끔 docker-compose를 설정하였다. 위에서 설명한 각 설정과 연동하여 짜주었다. nginx에서 정적파일과 미디어파일에 대한 폴더도 기입했고,포트 번호를 적어넣는다던가, mysql에서는 db 계정 정보가 들어있는 .env 파일도 경로로 지정하는 등 말이다.
depends_on은 컨테이너의 실행 순서이다. 위와 같은 순서라면 mysql이 먼저 실행된 뒤 django_app이 마지막으로는 nginx가 실행될 것이다.
command는 실행될 때 실행할 커맨드를 설정한다. mysql에서는 charset 관련 설정을, django_app은 정적파일을 모으는 것과 migrate 등 내부 변동사항을 반영한 뒤 gunicorn을 통해 80포트로 웹서버를 실행한다.
이제 AWS 웹에 putty 같은걸로 들어가서 docker와 docker-compose를 설치한뒤 어떻게든 실행했던것 같은데, 기억이 나질 않는다. 오늘은 여기까지 회고하고 다음 글을 통해 docker_compose를 어떻게 옮기고 실행했는지 써야겠다.
'Python > Django' 카테고리의 다른 글
django : Signal (0) | 2023.04.17 |
---|---|
Django : 역참조, queryset (0) | 2023.04.07 |
나의 첫 Django Project : community - break - (0) | 2023.03.21 |
나의 첫 Django Project : community - 4 - (0) | 2023.03.21 |
나의 첫 Django Project : community - 3 - (0) | 2022.08.22 |