본문 바로가기

Programming/Django

Gunicorn

GUnicorn의 필요

 

django 는 manage.py runserver 를 통해 앱서버를 동작시킬 수 있음

그런데, 이 서버는 local 에서 test server 용이지, 배포용은 아님

즉 django 내장 server 를 사용해서 배포하지 말 것을 django 공식 doc에서 명시

django 는 단일 쓰레드로, request가 많이 들어올 때 현저히 느려지고, 전반적인 퍼포먼스가 낮음

manage.py runserver 대신 서버를 실행시켜줄 것을 찾아야함

 

1. WSGI (Web Server Gateway Interface)

기본적으로 서버는 크게, 웹서버와 앱서버가 있음

nginx 나 apache 같이, 서버로 들어오는 http request 를 앞단 에서 가장 먼저 처리하는 것이 웹서버

그리고 django 내장 서버와 같이 어플리케이션을 위한 서버가 앱서버

클라이언트(예를 들어 브라우저)에서 서버 80포트로 http request 가 오면, 웹서버는 이를 해석하여, 적당한 포트로 요청을 보내, 의도한 특정 앱서버에다가 요청을 전달

이 때, 웹서버와 앱서버간의 요청에는 http와 같은 일종의 인터페이스가 필요한데, python에서는 wsgi 라는 인터페이스를 사용한다고 한다.

 

2. Gunicorn

gunicorn은 manage.py runsever 를 대신하여 실행할 wsgi 서버

(gunicorn 외에도 uwsgi 등 다른 wsgi 서버도 있는데, 이게 제일 실행시키기 쉬움

기존 django 서버는 단일 프로세스, 쓰레드인데, gunicorn은 이를 여러개로 만들어줌

즉 request 가 많이와도 이전보다 더 효율적으로 처리할 수 있도록 함

 

$ sudo apt-get install gunicorn

설치가 완료되면 python manage.py runsever 대신 다음과 같이 서버를 실행

 

$ gunicorn --bind 0.0.0.0:8000 프로젝트명.wsgi:application

[2018-09-30 13:31:36 +0000] [10836] [INFO] Starting gunicorn 19.9.0

[2018-09-30 13:31:36 +0000] [10836] [INFO] Listening at: http://127.0.0.1:8000 (10836)

[2018-09-30 13:31:36 +0000] [10836] [INFO] Using worker: sync

[2018-09-30 13:31:36 +0000] [10839] [INFO] Booting worker with pid: 10839

 

 

서비스 등록

sudo vi /etc/systemd/system/gunicorn.service

 

[Unit]

Description=gunicorn daemon

After=network.target

 

[Service]

User=donggyeongroh

Group=donggyeongroh

# ll로 확인하여 프로젝트 디렉토리에 설정된 user와 group으로 작성

WorkingDirectory=/home/donggyeongroh/PycharmProjects/pythonProject/djangoProject

# 프로젝트 디렉토리

ExecStart=./home/donggyeongroh/PycharmProjects/pythonProject/venv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/home/donggyeongroh/PycharmProjects/pythonProject/djangoProject/run/mydjango.sock djangoProject.wsgi:application

# venv/bin/gunicorn

# 소켓을 생성하는 위치는 프로젝트디렉토리/run/

# 프로젝트/wsgi.py 경로

 

[Install]

WantedBy=multi-user.target

 

sudo systemctl stop gunicorn

sudo systemctl daemon-reload

sudo systemctl start gunicorn

# 위 명령어를 실행하면 djangoProject/run/mydjango.sock이 생성됨

 

sudo systemctl enable gunicorn

sudo systemctl status gunicorn

# active확인하기

 

필요하다면 수명이 긴 프로세스인 daemon의 reload와 restart gunicorn 수행

sudo systemctl daemon-reload

sudo systemctl restart gunicorn

 

 

2. Nginx 를 이용한 포트 설정

Nginx 는 서버 앞단에서 request를 가장 먼저 처리하는 웹 서버

비슷한 다른 소프트웨어로는 apache가 있음

Nginx 를 이용하여 기본 포트인 80로 들어와도 우리의 웹사이트를 볼 수 있도록 하기

 

 

 

 

nginx를 설치

$ sudo apt-get install nginx

nginx 는 /etc/nginx 에 설치된다.

 

sudo vi /etc/nginx/conf.d/mydjango.conf

server {

listen 80;

server_name 123.123.123.123;

access_log /var/log/nginx/djangoProject_access.log;

error_log /var/log/nginx/djangoProejct_error.log;

 

location / {

include proxy_params;

proxy_pass http://unix:/home/donggyeongroh/PycharmProjects/pythonProject/djangoProject/run/mydjango.sock;

}

 

location /static/ {

alias /home/donggyeongroh/PycharmProjects/pythonProject/djangoProject/static_files;

expires -1;

}

}

 

site-avilable이랑 site-enable 안보이는 이유는 include /etc/nginx/conf.d/*.conf; 방식으로 설정하기 때문

sudo vi /etc/nginx/nginx.conf

 

user nginx;

worker_processes 1;

 

error_log /var/log/nginx/error.log warn;

pid /var/run/nginx.pid;

 

events {

worker_connections 1024;

}

 

http {

include /etc/nginx/mime.types;

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 on;

#tcp_nopush on;

 

keepalive_timeout 65;

 

#gzip on;

 

include /etc/nginx/conf.d/*.conf;

}

 

 

 

sudo vi /etc/nginx/proxy_params 생성

 

proxy_set_header Host $http_host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_set_header X-Forwarded-Proto $scheme;

 

 

 

/etc/nginx/nginx.conf 에 기본 설정 정보가 담겨있는데, 잘 보면

http { ... include /etc/nginx/site-enable/*; ... }

위의 코드가 보임

즉 우리는 /etc/nginx/sites-enable/ 에서 추가적인 설정 파일을 만들면, nginx.conf 에서 이 파일을 가져와 쓴다는 것

 

/etc/nginx/ 내부 디렉토리를 잘 보면 아래와 같은 두개의 디렉토리가 보임

 

/etc/nginx/sites-available 역할 : 사용 예정인 사이트 및 서버에 대한 설정파일을 보관

다시 말하지만, nginx 은 웹서버 최 앞단에서, request를 어떤 앱서버로 보낼지 정해주는 역할을 함

여기서 어디로 보낼지 등에 대한 설정파일을 여기에 담는 것

하지만 이는 '사용 예정' 에 불과하다.

 

/etc/nginx/sites-enable 역할 : 실제로 설정파일에 적용되는 파일은 이 디렉토리에 들어감

여기다가 직접 설정파일을 넣어도 되지만, 대게 ln -s 명령어(파일 연결, 일종의 바로가기와 같은 기능)를 이용하여 /sites-available/ 에 있는 설정 파일에 연결

예시 $ ln -s /etc/nginx/sites-available/프로젝트명 /etc/nginx/sites-enable/프로젝트명

 

실제 설정파일을 작성

/etc/nginx/sites-enable/ 에서 django-webiste 파일을 만들어서 다음과 같이 작성

server {

listen 80;

# 80포트로 들어오는 요청을 처리하겠음

server_name 123.123.123.123;

# 주소창에 내가 사용하고 싶은 서버 이름

 

location / { proxy_pass http://127.0.0.1:8000/;

# 123.123.123.123에서 발생시킨 request는 127.0.0.1:8000으로 보냄

}

location /static/ {

alias /home/donggyeongroh/PycharmProjects/pythonProject/djangoProject/static_files;

# 123.123.123.12/static/ 으로 들어오는 request는 python manage.py collectstatic 을 통해 모아진 정적파일들이 들어있는 staticfiles를 참고

}

}

 

 

작동하는지 확인

$ sudo nginx -t

 

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

nginx: configuration file /etc/nginx/nginx.conf test is successful

 

$ sudo sevice nginx restart

 

브라우저에서 123.123.123.123을 입력하면, 웹페이지가 뜸

80 포트로 접속하면 nginx 에서 서버 내부의 8000포트 앱서버로 요청을 보내주는 것

 

 

 

html은 바로 수정하면 바로 반영되지만

 

.py를 수정했을 경우 운영서버 내에서 반영하고 싶다면

sudo service gunicorn restart

 

 

 

Can't connect to djangoProject/run/djangoProject.sock 경로 문제 해결

sudo chmod -R 777 run

'Programming > Django' 카테고리의 다른 글

gunicorn, nginx 환경에서 css가 적용되지 않은 이유  (0) 2020.10.12
view, html, js 값 이동  (0) 2020.10.12