일단, python manage.py runserver
는 배포할 때는 사용하면 안된다. 간단하게 말하자면 runserver
로 실행하는 것이 보안에 매우 취약하기 때문이다.
"""
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!
"""
더 자세한 내용은 https://twowix.me/85 여기에 참고하면 좋다.
참고로 []
대괄호 안에 있는 것들은 사용자 환경에 맞춰서 다르게 입력해줘야 하는 것이니깐 그대로 복붙하면 안된다.
Spring이랑은 다르게 Django는 gunicorn이라는 wsgi 기술을 사용한다. 그나저나 wsgi가 뭐냐면 파이썬 어플리케이션이 웹 서버와 통신하기 위한 인터페이스다.
쉽게 말해서 웹서버에서 오는 요청을 해석해서 파이썬 애플리케이션으로 던져준다고 생각하면 된다.
대충 뭐 이런 느낌이다.
내가 작업하고 있는 서버의 ip랑 서비스 도메인 주소를 추가로 넣어준다. 아니면 오류 뜸
# setting.py
ALLOWED_HOSTS = ['127.0.0.1','www.recommendu.kro.kr',...]
pip3 install gunicorn
설치한 이후에 gunicorn이 제대로 작동하는지 체크한다.
cd [manage.py 있는 디렉토리]
gunicorn --bind 0.0.0.0:8000 [project name].wsgi:application
이렇게 나오면 잘 작동하는거다. 만약에 실패했으면 Worker failed to boot
라는 메시지가 나온다. 아마 실패했을 때는 디렉토리 위치랑 프로젝트 이름을 잘못 입력한거다
참고로 [project name].wsgi:application
이거는 프로젝트 내의 wsgi.py
안에 있는 application
을 실행하는 코드다.
잘 돌아가는거 확인했으니깐 이제 Gunicorn.service를 통해서 만들어보자 service를 만드는 이유는 nginx를 연결하기 위함이다.
일단 두 가지 방법이 있는데 첫번째 방법은 socket을 사용하는 방법, 나머지 하나는 socket을 사용하지 않는 방법이 있다. socket으로 통신하는 방법이 속도 측면에서 성능이 더 좋기 때문에 먼저 socket으로 해보고 만약에 실행이 안되면 두번째 방법으로 하는 것을 추천한다.
socket 만드는 코드가 없어서 찾는데 진짜 애먹었다. 자동으로 만들어 주는 거인줄 알았는데 사실 내가 만들어야되는거였음..;;; 일단 파일 위치가 굉장히 중요하다. 서버 제일 상위 폴더로 이동하면 etc/
라는 폴더가 있을 텐데 거기서부터 시작하면 된다. (폴더 새로 만드는거 아님)
cd /etc/systemd/system
vi gunicorn.socket
이후에 이렇게 만들어주면 된다. vi 사용법은 여기 참고하면 좋다.https://blockdmask.tistory.com/25
[Unit]
Description=gunicorn socket
[Socket]
ListenStream=/run/gunicorn.sock
[Install]
WantedBy=sockets.target
얘도 마찬가지로 같은 위치에 만들어준다.
cd /etc/systemd/system
vi gunicorn.service
이후에 이렇게 만들어준다.
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket (조금전에 직접 만든 socket 파일 이름)
After=network.target
[Service]
User=user
Group=user
WorkingDirectory=[project directory]
ExecStart=[virtual environment directory] --workers 1 --bind unix:/run/gunicorn.sock
\ [project name].wsgi:application
[Install]
WantedBy=multi-user.target
나는 이렇게 입력했다. 혹시나 []
이 안에 부분이 헷갈리면 참고했으면 좋겠다.
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket (조금전에 직접 만든 socket 파일 이름)
After=network.target
[Service]
User=root
Group=root
WorkingDirectory=/home/recommendu/recommendu
ExecStart=/home/recommendu/first/bin/gunicorn --workers 1 --bind 0.0.0.0:30001 recommendu.wsgi:application
[Install]
WantedBy=multi-user.target
이렇게 다 만들었다면 이렇게 명령어를 입력하면 된다.
sudo systemctl enable gunicorn.socket // socket 실행
sudo systemctl start gunicorn.socket // socket 실행
sudo systemctl daemon-reload // 파일을 변경했을때 변경한 내용 적용
sudo systemctl enable gunicorn //서버 재시작시 자동으로 실행
sudo systemctl start gunicorn // 서비스 실행
sudo systemctl status gunicorn //실행한 서비스 상태
여기서 sudo systemctl status gunicorn
이 명령어를 치면
이렇게 잘뜬다.
gunicorn이 작동하는거 같긴 한데 막상 사이트에 들어가보면 err connection refused
이렇게 뜨는 경우가 있다. 이런 경우에는 socket이 문제인 경우이기 때문에 socket을 꺼주고 service를 수정해야한다.
sudo systemctl stop gunicorn.socket // socket 정지
sudo systemctl stop gunicorn // service 정지
cd /etc/systemd/system
vi gunicorn.service
socket 쓰는거 대신에 바로 url을 박아준다.
[Unit]
Description=gunicorn daemon
After=network.target
[Service]
User=root
Group=root
WorkingDirectory=[project directory]
ExecStart=[virtual environment directory] --workers 1 --bind 0.0.0.0:[port]
\ [project name].wsgi:application
[Install]
WantedBy=multi-user.target
그리고 socket은 냅두고 service만 실행해준다. 대신에 sudo systemctl daemon-reload
이거는 반드시 먼저 입력해줘야지 변경이 적용된다.
sudo systemctl daemon-reload // 파일을 변경했을때 변경한 내용 적용
sudo systemctl enable gunicorn //서버 재시작시 자동으로 실행
sudo systemctl start gunicorn // 서비스 실행
sudo systemctl status gunicorn //실행한 서비스 상태
gunicorn을 연결했으면 거의 다한거다. 사실 gunicorn만 사용해도 되는데 최적화와 정적 파일(img, css 등)을 서비스에 적용하기 위해서 사용한다. 그 외에 이런 역할들을 한다.
정적 파일 제공(이거 때문에 nginx를 사용하긴 했다.)
한 번에 들어오는 많은 요청을 처리
느린 클라이언트 처리
동적 요청을 wsgi에 전달
SSL (https) **(nginx를 사용해야하는 가장 큰이유 중에 하나임)
Python 코드와 비교하여 컴퓨팅 리소스 (CPU 및 메모리) 절약
로드 밸런싱, 캐싱 등
nginx는 pip가 아니라 우분투로 깔아야된다.
sudo apt-get update
sudo apt-get install nginx
nginx는 하나만 생성해주면 된다. sites-available
이라는 폴더안에 [project name]
파일을 생성해준다/
cd /etc/nginx/sites-available
vi [project name]
이 파일 안에 nginx 세팅을 진행하면 된다. socket을 사용해서 gunicorn을 연결한 경우는 아래꺼
server {
listen 80;
server_name [ip address];
location / {
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
}
location /static/ {
alias [project directory]/static/;
}
}
socket을 사용하지 않은 경우는 이렇게 입력한다.
server {
listen 80;
server_name [ip address];
location / {
include proxy_params;
proxy_pass http://0.0.0.0:[port];
}
location /static/ {
alias [project directory]/static/;
}
}
그나저나 /static/
이 부분이 뭐냐면 gunicorn에서는 정적 파일이 적용이 안되기 때문에 nginx에 직접 연결 시켜주기 위한 코드이다.
그 다음으로 sites-enabled
를 만들어줄건데 무조건 아래의 코드로 복붙을 해줘야된다.
sudo ln -s /etc/nginx/sites-available/[project name] /etc/nginx/sites-enabled
그 다음으로 nginx 데몬 재부팅만 해주면 끝이다.
sudo systemctl restart nginx
sudo systemctl status nginx
이렇게 입력하고 나서 아래의 화면이 뜨면 된거다.
만약에 에러가 뜨면 아래 명령어로 확인할 수 있다.
tail -f /var/log/nginx/error.log