이전에 gunicorn을 이용해 서버 가동을 했다면 이제는 웹서버인 Nginx와 연동해 서비스를 꾸려나가볼 것입니다.
우선 Nginx는 트래픽이 많은 웹사이트의 서버(WAS)를 도와주는 고성능 경량 웹 서버입니다.
apache의 단점들을 보완해 나온 것이 Nginx인데, 장점을 이야기해보면 크게 3가지가 있습니다.
- 높은 성능
- 높은 동시성
- 낮은 자원 사용
- 메모리 생성 속도 ↑, 적은 쓰레드로 많은 클라이언트 처리
Nginx는 아래의 명령어로 설치 가능합니다.
# CentOS
sudo yum install nginx
Nginx 기본 설정 파일은 /etc/nginx/nginx.conf
경로에 있습니다. 성능이나 로깅, 접속 처리 등 커스텀 할 예정이면 아래 정보를 수정해주면 됩니다. 이번에는 연동이 주 목적이니 따로 건들지 않고 패스하겠습니다.
# vi /etc/nginx/nginx.conf
# worker 프로세스를 실행할 사용자 설정
# - 이 사용자에 따라 권한이 달라질 수 있다.
user nginx;
# 실행할 worker 프로세스 설정
# - 서버에 장착되어 있는 코어 수 만큼 할당하는 것이 보통, 더 높게도 설정 가능
worker_processes 1;
# 오류 로그를 남길 파일 경로 지정
error_log /var/log/nginx/error.log warn;
# NGINX 마스터 프로세스 ID 를 저장할 파일 경로 지정
pid /var/run/nginx.pid;
# 접속 처리에 관한 설정을 한다.
events {
# 워커 프로레스 한 개당 동시 접속 수 지정 (512 혹은 1024 를 기준으로 지정)
worker_connections 1024;
}
# 웹, 프록시 관련 서버 설정
http {
# mime.types 파일을 읽어들인다.
include /etc/nginx/mime.types;
# MIME 타입 설정
default_type application/octet-stream;
# 엑세스 로그 형식 지정
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
# 엑세스 로그를 남길 파일 경로 지정
access_log /var/log/nginx/access.log main;
# sendfile api 를 사용할지 말지 결정
sendfile on;
#tcp_nopush on;
# 접속시 커넥션을 몇 초동안 유지할지에 대한 설정
keepalive_timeout 65;
# (추가) nginx 버전을 숨길 수 있다. (보통 아래를 사용해서 숨기는게 일반적)
server_tokens off
#gzip on;
# /etc/nginx/conf.d 디렉토리 아래 있는 .conf 파일을 모두 읽어 들임
include /etc/nginx/conf.d/*.conf;
}
sites-available
디렉토리에 설정파일 저장해주면 됩니다.
vi /etc/nginx/sites-available/<장고 프로젝트 이름>
server {
listen 80;
server_name <IP주소>;
location / {
include proxy_params;
proxy_pass http://<IP주소>:8000;
}
}
이는 클라이언트가 IP주소:80
으로 요청을 보내면 http://<IP주소>:8000;
으로, 즉 gunicorn으로 연결되어 요청이 처리된다는 의미입니다.
위의 sites-available
에서 설정했던 파일을 sites-enabled
디렉토리로 파일 복사해줍니다.
sites-available 폴더는 설정을 저장하는 곳이며, 이 안의 설정 파일은 실제로 반영이 되지는 않습니다. 따라서 실제로 반영이 되는 폴더인 sites-enabled 폴더로 복사해주어야 하는데, 파일이 2개면 동기화의 어려움이 있을 수 있으니 심볼릭 링크를 이용해 연동해줄 것입니다.
sudo ln -s /etc/nginx/sites-available/<장고 프로젝트 이름> /etc/nginx/sites-enabled
sudo nginx -t
문법 오류가 없다면 다음과 같이 출력됩니다.
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
설정 파일에 문제가 없다면, nginx를 재시작해서 설정 파일을 적용시켜줍니다.
sudo systemctl restart nginx
해당 명령을 입력하면 현재 상태 확인 가능합니다.
systemctl status nginx.service
에러 로그는 다음 경로에서 확인 가능합니다.
sudo vi /var/log/nginx/error.log
우선 아직 해보지는 않았지만 대략적인 방법 적어놔야지
collectstatic을 실행하기 위해서는 먼저 파일들을 모을 경로를 지정해주어야 하며 이 경로는 settings.py 의 STATIC_ROOT
라는 변수로 지정한다.
프로젝트 루트의 상위 폴더에 .static_root 라는 숨김 폴더를 생성하고 그곳으로 모든 정적 파일들을 모으도록 설정하였다.
import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
ROOT_DIR = os.path.dirname(BASE_DIR)
# static files
STATIC_URL = '/static/'
STATIC_DIR = os.path.join(BASE_DIR, 'static')
STATICFILES_DIRS = [
STATIC_DIR,
]
STATIC_ROOT = os.path.join(ROOT_DIR, '.static_root') # 요기
해당 명령을 입력하면 프로젝트 내에 css, font 등 Static file
들을 몽땅 모아준다고 합니다.
python manage.py collectstatic
runserver는 STATIC_URL
에 지정된 URL을 통해 정적 파일 요청을 받아온다.
하지만 서버에 배포를 하고나면 Nginx가 요청을 받게되므로 정적 파일 요청을 처리할 수 있도록 정적 파일 URL을 지정해주어야 한다.
mysite.conf
파일을 열어 아래와 같이 새로운 location 을 추가해주자.
server {
listen 80;
server_name *.compute.amazonaws.com *.che1.kr;
charset utf-8;
client_max_body_size 128M;
location / {
uwsgi_pass unix:///tmp/mysite.sock;
include uwsgi_params;
}
location /static/ {
alias /home/ubuntu/Project_name/.static_root/; # 경로는 각자 알맞게 적어주어야 함
}
}
이제 /static/ URL로 정적 파일 요청이 들어오면 모든 정적 파일을 모아놓은 폴더인 /.static_root/ 폴더에서 찾아 되돌려보낸다.
systemctl restart nginx
Nginx와 Gunicorn 사이의 통신을 socket 방식으로 구성하면 overhead가 적기 때문에 더 효율적입니다.
우선 HTTP 요청을 사용해 구성하는 방법을 알아봤고 추후에 socket 방식으로 구성해보겠습니다.
참고자료 📩