Gunicorn+Nginx 리눅스 서버에서 배포하기

‍한지영·2022년 3월 2일
5
post-thumbnail

Django나 Flask와 같이 파이썬 기반 프레임워크를 사용한 웹을 배포할 때, 주로 Gunicorn과 Nginx, Django/Flask로 만든 앱을 엮어서 배포하는 것이 정석이라 여겨진다.

물론, 로컬 환경에서 개발하는 것처럼, 메인 서버에 올릴 때 python manage.py runserver로 뚫린 포트를 지정해서 서버에 켜 놓을수도 있다.(Django 기준) runserver nohup으로 백그라운드에 돌게 만들 수도 있다. 다만 예상할 수 있듯 보안의 취약성 때문에 테스팅/디버깅 외 메인서버에서 돌릴때는 runserver는 당연히 당연히 당연히 지양해야 한다.🤚 아래는 친절히 runserver로 메인 서버를 켜놓지 말라는 django package django.core.servers.base_http.py 내의 주석이다.

django.core.servers.base_http.py

"""
HTTP server that implements the Python WSGI protocol (PEP 333, rev 1.21).

Based on wsgiref.simple_server which is part of the standard library since 2.5.

This is a simple server for use in testing or debugging Django apps. It hasn't
been reviewed for security issues. DON'T USE IT FOR PRODUCTION USE!
"""

이 글에서는 django의 Runserver의 동작을 찬찬히 뜯어보며 왜 runserver 하지 말아야 하는지를 알아 볼 수 있다. 본 포스트는 해당 글을 참조하여 작성되었다.

그러면, 대강 runserver 하지 말고🤚 Gunicorn+Nginx로 리눅스 서버에서 배포하는 법을 알아보자. 아래 코드에서 <>는 각자 환경에 따라 바꿔주어야 하는 부분! <> 빼고 생각할 것.

Gunicorn

1. 테스트 서버 구동/접속 확인

$ (venv) $ python manage.py runserver 0.0.0.0:8000

로컬에서 띄우듯 서버에서 runserver를 시켜본다. http://해당서버아이피:8000 포트로 접속해서 기능이 잘 작동하는지를 확인해본다.

2. pip install Django gunicorn

$ (venv) $ pip install Django gunicorn

3. Gunicorn으로 서버 구동/접속 확인

$ (venv) $ gunicorn --bind 0.0.0.0:8000 <wsgi.py가 있는 디렉토리 이름>.wsgi:application

Gunicorn으로 서버를 구동시켜본다. 아까 테스트 서버를 구동했던 것과 마찬가지로, http://해당서버아이피:8000 포트로 접속해서 기능이 잘 작동하는지를 똑같이 확인해본다

deactivate

잘 동작하면 deactivate!

4. gunicorn.service 파일 생성

cd /etc/systemd/system
vim gunicorn.service

gunicorn.service 파일을 생성한다. 파일 내용은 아래와 같다.

[Unit]
Description=gunicorn daemon
After=network.target

[Service]
User=<계정명>
Group=<계정명>
WorkingDirectory=<프로젝트 경로. 즉 manage.py가 위치한 디렉토리 pwd>
ExecStart=<gunicorn이 설치된 가상환경 위치> \
        --workers 3 \
        --bind unix:/home/foo/django_test/run/gunicorn.sock \
        <wsgi.py가 있는 디렉토리 이름>.wsgi:application

[Install]
WantedBy=multi-user.target

5. gunicorn 서비스 실행/등록

$ (venv) $ sudo systemctl start gunicorn
$ (venv) $ sudo systemctl enable gunicorn

start gunicorn은 systemd에 작성한 gunicorn.service 파일을 실행하는 명령어, enable gunicorn은 gunicorn.service 파일을 서버를 재시작할 때마다 자동으로 실행하는 명령어이다.

5. gunicorn 서비스 실행 확인

$ (venv) $ systemctl status gunicorn

gunicorn 서비스가 잘 실행되었는지 확인하는 명령어이다. 해당 명령어 실행 시 실행이 잘 되었으면 아래와 같은 출력을 뱉는다.

● gunicorn.service - gunicorn daemon
   Loaded: loaded (/etc/systemd/system/gunicorn.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2022-03-01 12:13:59 KST; 1 day 5h ago

Active: active (running)! 이렇게 하면 gunicorn과 django 연동이 끝났다. manage.py runserver 했을 때와 같이, http://해당서버아이피:8000 으로 접속하면 잘 작동할 것이다.

(번외) 이외 gunicorn 명령어

$ (venv) $ sudo systemctl stop gunicorn #gunicorn.service 중지
$ (venv) $ sudo systemctl restart gunicorn #gunicorn.service 재시작

특히, Django framework 사용 시, views.py 등 django 내부 파일 수정 후에는 sudo systemctl restart gunicorn 명령어로 gunicorn 재시작 해주어야 서버에 반영된다.

Nginx

1. nginx 설치

$ sudo apt-get install nginx

2. nginx-gunicorn-django 연결 : sites-available 디렉토리에 설정파일을 저장

$ vi /etc/nginx/sites-available/<장고 프로젝트 이름>

위와 같이 sites-available 디렉토리에 설정 파일을 생성해서 아래왁 같이 입력 후 저장한다.

server {
    listen 80;
    server_name <IP주소>;

    location / {
        include proxy_params;
        proxy_pass http://<IP주소>:8000;

    }
}

이는 클라이언트가 IP주소.80으로 요청을 보내면 http://<IP주소>:8000;으로, 즉 구니콘으로 연결되어 요청이 처리된다는 의미이다.

3. nginx-gunicorn-django 연결 : sites-enabled 디렉토리로 설정 파일을 복사

sites-available 폴더는 설정을 저장하는 곳이며, 이 안의 설정 파일은 실제로 반영이 되지는 않는다. 따라서 실제로 반영이 되는 폴더인 sites-enabled 폴더로 설정 파일을 복사해주어야 한다.

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

4. 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

5. nginx 재시작

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

$ sudo systemctl restart nginx

6. nginx trouble shooting

$ systemctl status nginx.service

restart nginx에 실패한 경우, 혹은 nginx.service의 Status를 보고 싶은 경우, 위 명령어를 통해 status / error detail을 확인할 수 있다.
nginx 설정 파일 문법에 오류가 없더라도, 다양한 이유로 active: failed가 뜰 수 있다.

혹시나 (code=exited, status=1/FAILURE) 을 제외하고, 별다른 에러메세지를 찾아볼 수 없는 경우!

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

에러 로그를 참조하자.




Gunicorn+Nginx+Django 연동 끗.

profile
NLP 전공 잡식성 문헌정보 석사생

0개의 댓글