[Django] - Nginx + Gunicorn 연동 (2)

오동훈·2022년 12월 31일
1

Django

목록 보기
15/23

1. Nginx란

이전에 gunicorn을 이용해 서버 가동을 했다면 이제는 웹서버인 Nginx와 연동해 서비스를 꾸려나가볼 것입니다.

우선 Nginx는 트래픽이 많은 웹사이트의 서버(WAS)를 도와주는 고성능 경량 웹 서버입니다.
apache의 단점들을 보완해 나온 것이 Nginx인데, 장점을 이야기해보면 크게 3가지가 있습니다.

  1. 높은 성능
  2. 높은 동시성
  3. 낮은 자원 사용

특징

  • Single Thread 기반으로 context switching을 하지 않음
  • 이벤트 지향 아키텍처(Event-driven Architecture) 방식 이용
    - 메모리 생성 속도 ↑, 적은 쓰레드로 많은 클라이언트 처리
  • apache가 제공하는 모든 기능 제공 (LB, 메일 프록시 등)

2. 사용법

1. Nginx 설치

Nginx는 아래의 명령어로 설치 가능합니다.

# CentOS

sudo yum install nginx

2. 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;
}

3. nginx-gunicorn-django 연결 (1)

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으로 연결되어 요청이 처리된다는 의미입니다.

4. nginx-gunicorn-django 연결 (2)

위의 sites-available에서 설정했던 파일을 sites-enabled 디렉토리로 파일 복사해줍니다.

sites-available 폴더는 설정을 저장하는 곳이며, 이 안의 설정 파일은 실제로 반영이 되지는 않습니다. 따라서 실제로 반영이 되는 폴더인 sites-enabled 폴더로 복사해주어야 하는데, 파일이 2개면 동기화의 어려움이 있을 수 있으니 심볼릭 링크를 이용해 연동해줄 것입니다.

sudo ln -s /etc/nginx/sites-available/<장고 프로젝트 이름> /etc/nginx/sites-enabled

5. nginx 설정 파일 문법 검사

sudo nginx -t

문법 오류가 없다면 다음과 같이 출력됩니다.

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

6. nginx 재시작

설정 파일에 문제가 없다면, nginx를 재시작해서 설정 파일을 적용시켜줍니다.

sudo systemctl restart nginx

7. 상태 확인

해당 명령을 입력하면 현재 상태 확인 가능합니다.

systemctl status nginx.service

8. log 확인

에러 로그는 다음 경로에서 확인 가능합니다.

sudo vi /var/log/nginx/error.log

9. static file 처리

우선 아직 해보지는 않았지만 대략적인 방법 적어놔야지

1. settings 설정

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') # 요기

2. collectstatic

해당 명령을 입력하면 프로젝트 내에 css, font 등 Static file들을 몽땅 모아준다고 합니다.

python manage.py collectstatic

3. nginx 설정

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/ 폴더에서 찾아 되돌려보낸다.

4. nginx 재실행

systemctl restart nginx

Nginx와 Gunicorn 사이의 통신을 socket 방식으로 구성하면 overhead가 적기 때문에 더 효율적입니다.
우선 HTTP 요청을 사용해 구성하는 방법을 알아봤고 추후에 socket 방식으로 구성해보겠습니다.


참고자료 📩

Nginx 기본 환경 설정 설명
Nginx 배경 및 구조

profile
삽질의 기록들🐥

0개의 댓글