Nginx를 Proxy server로 사용하고
GUnicorn을 Web Server와 Gateway Interface, 즉 WSGI로 사용하고
Flask를 Web application로 사용하여 Web service를 제작해보았다.
NaverCloudPlatform의 Ubuntu 18.04 서버로 진행했다.
1. 환경
1-1. 먼저 apt를 업데이트하고 필요한 라이브러리를 설치한다.
$ sudo apt update sudo apt install python3-pip python3-dev build-essential libssl-dev libffi-dev python3-setuptools
2. venv
2-1. venv를 구성하기위한 라이브러리를 설치한다.
$ sudo apt install python3-venv
2-2. 프로젝트를 진행할 디렉터리를 만들고 이동한다.
$ mkdir ~/myproject
$ cd ~/myproject
2-3. venv를 만들고 활성화한다.
$ python3 -m venv venv
$ source venv/bin/activate
3. Flask
3-1. venv에서 flask에 필요한 라이브러리를 설치한다.
# In venv
$ pip install wheel pip install gunicorn flask
3-2. 프로젝트 폴더의 main 코드를 실행한다. 만약 없다면 간단히 app.py를 만들어 준다.
$ vi ~/myproject/app.py
from flask import *
app = Flask(__name__)
@app.route("/")
def hello():
return "<h1 style='color:blue'>Hello There!</h1>"
if __name__ == "__main__":
app.run(host='0.0.0.0')
3-3. 외부에서 접속할 것이라면, 5000 port를 개방해준다.
$ sudo ufw allow 5000
3-4. 실행한다.
$ python myproject.py
http://localhost:5000 로 접속해본다.
4. GUnicorn
4-1. 편의를 위해, wsgi.py를 만들어서 관리한다.
$ vi ~/myproject/wsgi.py
from myproject import app
if __name__ == "__main__":
app.run()
4-2. gunicorn을 통해 실행시켜준다.
$ cd ~/myproject
$ gunicorn --bind 0.0.0.0:5000 wsgi:app
http://localhost:5000 로 접속해본다.
4-3. 잘 실행된다면 우선 venv를 비활성화합니다.
$ deactivate
4-4. myproject에 대해 service를 만들어준다. myproject 의 venv를 활성화하고, guincorn을 옵션과 함께 실행시키는 기능을 하게 된다.
$ sudo vi /etc/systemd/system/myproject.service
[Unit]
Description=Gunicorn instance to serve
myproject After=network.target
[Service]
User=ubuntu
Group=www-data
WorkingDirectory=/home/ubuntu/myproject
Environment="PATH=/home/ubuntu/myproject/venv/bin"
ExecStart=/home/ubuntu/myproject/venv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app [Install] WantedBy=multi-user.target
실제 프로젝트의 서버에서 나는 아래와 같이 설정했다. root 파일 경로를 찾고 실행하는 것이 어려웠다.
# /etc/systemd/system/gunicorn.service
[Unit]
Description=Gunicorn instance to serve gunicorn
After=network.target
[Service]
User=root
Group=www-data
WorkingDirectory=/root/{프로젝트경로}
Environment="PATH=/root/{프로젝트경로}/venv/bin"
ExecStart=/root/{프로젝트경로}/venv/bin/gunicorn --workers 3 --bind unix:recobook.sock -m 007 wsgi:app
[Install]
WantedBy=multi-user.target
4-5. myproject service를 실행하고 상태를 검사한다. 만약 변경사항이 있다면 systemctl daemon-reload로 변경사항을 불러온 뒤 처음부터 실행한다.
실행 실패가 뜬다면 프로젝트를 실행하면 보이는 Error와 journalctl과 같은 명령어를 입력해서 Error를 확인하고 해결하는 게 도움이 된다.
$ sudo systemctl start myproject
$ sudo systemctl enable myproject
$ sudo systemctl status myproject
$ systemctl daemon-reload
5. Nginx
5-1. Nginx에 대한 환경을 설정해준다.
이전에 Nginx SSL 인증(HTTPS 적용)에 관한 글을 쓴 적이 있어서 공유한다.
https://nali.tistory.com/58?category=947474
Nginx를 설정하는 방법에는 sites-available 폴더에 새롭게 파일을 작성하고 sites-enabled 폴더와 연결해서 실행하는 방법이 있고, 바로 default파일을 설정하는 방법이 있는데 나의 경우 후자를 선호한다.
아래는 프로젝트에서 사용하는 코드이다.
$ sudo vi /etc/nginx/sites-available/default
server { # redirection
listen 80;
server_name domain.shop www.domain.shop ip;
return 301 https://www.domain.shop$request_uri;
}
server {
listen 443 ssl http2;
server_name domain.shop www.domain.shop;
root /var/www/html;
ssl_certificate "/etc/letsencrypt/live/domain.shop/fullchain.pem";
ssl_certificate_key "/etc/letsencrypt/live/domain.shop/primarykey.pem";
ssl_dhparam "/etc/ssl/certs/dhparam.pem";
location / { try_files $uri @app}
location @app {
include proxy_params;
proxy_pass http://unix:/root/{프로젝트경로}/gunicorn.sock;
}
location @application {
proxy_pass http://ip:5001;
}
}
server {
listen 5001;
server_name domain.shop www.domain.shop;
ssl on;
ssl_certificate "/etc/letsencrypt/live/recobook.shop/fullchain.pem";
ssl_certificate_key "/etc/letsencrypt/live/recobook.shop/primarykey.pem";
ssl_dhparam "/etc/ssl/certs/dhparam.pem";
location / {
proxy_pass http://ip:5001;
proxy_pass http://unix:/root/{프로젝트경로}/gunicorn.sock;
}
}
5-3. nginx 에 -t 옵션을 통해 test 해본다.
$ sudo nginx -t
5-4. 문제가 없다면 nginx를 재실행한다.
$ sudo systemctl restart nginx
5-5. Nginx Full에 관해 방화벽을 개방해준다.
$ sudo ufw allow 'Nginx Full'
$ sudo ufw allow 80
$ sudo ufw allow 443
6. log
6-1. error 에 관한 log 는 다음과 같이 생성된다.
less, journalctl 등 의 명령어를 통해 분석할 수 있다.
# Nginx error logs
$ sudo less /var/log/nginx/error.log
#Nginx access logs
$ sudo less /var/log/nginx/access.log
#Nginx process logs
$ sudo journalctl -u nginx
#Flask app’s Gunicorn logs
$ sudo journalctl -u myproject
설정하면서 생각보다 시간을 많이 썼고 삽질도 했지만 다시 개념을 잡고 실습도 할 수 있어서 좋았다.
현재 443 포트에서 gunicorn 서버 자동실행하는 부분이 잘 되지 않아 일단 5001번 포트를 계속 쓰고 있는데, 443 포트로도 실행이 되도록 Nginx 포트포워딩 설정을 계속 수정해볼 생각이다.
참고
https://m.blog.naver.com/na_qa/221912986971
https://m.blog.naver.com/shino1025/221842199178
'👩💻 Web Programming > Backend' 카테고리의 다른 글
[Node.js] Nodemon, PM2를 이용한 수정 사항 자동 반영 서버 (0) | 2021.10.16 |
---|---|
[Flask] nohup bacground 실행하기 (0) | 2021.10.02 |
[Node.js] 정규표현식 정리(이메일, 비밀번호, 날짜, 전화번호, 날짜, 닉네임, URL, 위도, 경도) (0) | 2021.07.24 |
[Node.js] 오답노트 (0) | 2021.07.22 |
[Flask] SecretKey 비밀키 설정 (0) | 2021.07.21 |