Flask 서비스를 위한 uWSGI + Nginx 설정

1. 필요 패키지 설치

$ sudo apt-get install python3 python3-pip nginx
$ sudo pip3 install virtualenv
$ sudo pip3 install uwsgi

2. Virtualenv 설정

$ virtualenv .server
$ source .server/bin/activate
(.server) $ pip3 install flask
(.server) $ pip3 install uwsgi

uwsgi를 또 설치한 이유는 코드에서 uWSGI decorators를 사용하기 위함임

3. Flask 코드 작성

# server.py
from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello():
    return 'world'

if __name__ == '__main__':
    app.run(host='0.0.0.0')

4. uWSGI 동작 확인

(.server) $ uwsgi --socket 0.0.0.0:5000 --protocol=http -w server --callable app --venv .server --master

5000번 포트 접속시 world 메세지가 잘 나오는지 확인. 잘 나온다면 virtualenv를 나오자

(.server) $ deactivate

5. uWSGI 설정 파일 작성

server.ini 파일을 아래와 같이 작성하자

[uwsgi]
strict = true

chdir = /home/pi/wallpad
venv = /home/pi/wallpad/.server
module = server
callable = app

master = true
processes = 1
threads = 3

socket = /tmp/server.sock
chmod-socket = 664
vacuum = true

die-on-term = true

log-4xx = true
log-5xx = true
disable-logging = true

strict : This option tells uWSGI to only allow valid uWSGI options in the config file
chdir : the base directory (full path)
venv : python virtualenv path
module : python filename
master : Respawns processes when they die and handles much of the built-in prefork+threading multi-worker management, generally always advised
processes : Adds concurrency to the app by adding n additional processes
threads : Adds additional cuncurrency by adding n additional threads
socket : sock file path
chmod-socket : permissions of the socket file
vacuum : Removes the socket when the process stops
die-on-term : If running the uWSGI service with the init system (systemd, upstart), confirms both uWSGI and the init system have the same idea about what each process signal means
log-4xx : log requests with a 4xx response
log-5xx : log requests with a 5xx response
disable-logging : disable request logging

작성이 끝나면 아래 코드 실행후 /tmp/server.sock 파일이 생성되면 OK

$ uwsgi --ini server.ini

6. Emperor 설정

Emperor는 여러개의 ini 파일을 한번에 uWSGI 프로세스로 실행하는 기능이다.
Emperor 사용을 위해 아래 경로에 폴더를 만들고 위에 작성한 설정파일(uwsgi.ini)을 복사하자.
폴더명은 nginx 설정파일 폴더와 유사하게 구성했다.

$ sudo mkdir /etc/uwsgi
$ sudo mkdir /etc/uwsgi/apps-available
$ sudo mkdir /etc/uwsgi/apps-enabled
$ sudo cp server.ini /etc/uwsgi/apps-available/server.ini
$ sudo ln -s /etc/uwsgi/apps-available/server.ini /etc/uwsgi/apps-enabled/

그리고 서버 재부팅시 재시작을 위해 /etc/rc.local에 ‘exit 0’ 바로 상단에 아래 코드를 추가하자.

$ /usr/local/bin/uwsgi --emperor /etc/uwsgi/apps-enabled --uid www-data --gid www-data --daemonize /home/pi/wallpad/uwsgi-emperor.log

emperor : ini 파일이 위치한 경로
uid : 프로세스 사용자
gid : 프로세스 사용자 그룹
daemonize : 백그라운으로 실행하며 로그를 남길 폴더를 지정

끝으로 로그 파일을 쉽게 확인하기 위해 권한을 재설정 하자.

$ chmod 655 /home/pi/wallpad/uwsgi-emperor.log

7. Nginx 설정

우선 default 파일을 삭제

$ sudo rm /etc/nginx/sites-enabled/default

그리고 /etc/nginx/sites-available 경로에 아래 파일 작성

server {
    listen 5000;
    server_name localhost;

    location / { try_files $uri @app; }

    location @app {
        include uwsgi_params;
        uwsgi_pass unix:/tmp/server.sock;
        uwsgi_ignore_client_abort on;
    }
}

작성이 끝나면 /etc/nginx/sites-enabled 경로에 작성한 파일을 심볼릭링크로 걸어줌.

$ sudo ln -s /etc/nginx/sites-available/server /etc/nginx/sites-enabled

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
$ sudo service nginx restart

8. Emperor 모드와 master 옵션간 문제

/home/pi/wallpad/uwsgi-emperor.log 파일을 보다보니 시작지점이 아래와 같은 WARNING 로그를 확인.

*** WARNING: you are running uWSGI without its master process manager ***

분명 나는 /etc/uwsgi/apps-available/server.ini 파일에 ‘master = true’라고 명시해줬다.
그런데 master process manager가 동작하지 않는다고?!
관련 내용을 찾아보니 아래와 같은 내용이 있었다.

The emperor should generally not be run with –master, unless master features like advanced logging are specifically needed.
https://uwsgi-docs.readthedocs.io/en/latest/Emperor.html#notes

그리고 stackoverflow에도 질문 및 답변이 있었다.
https://stackoverflow.com/questions/15055002/uwsgi-master-with-emperor-spawns-two-emperors

그리하여 emperor는 쓰지 않고 /etc/rc.local 파일을 아래와 같이 수정

$ /usr/local/bin/uwsgi --ini /etc/uwsgi/apps-enabled/server.ini

그리고 /etc/uwsgi/apps-available/server.ini 파일에도 아래 3줄을 추가

[uwsgi]
strict = true

chdir = /home/pi/wallpad
venv = /home/pi/wallpad/.server
module = server
callable = app

master = true
processes = 1
threads = 3

socket = /tmp/server.sock
chmod-socket = 664
vacuum = true

die-on-term = true

log-4xx = true
log-5xx = true
disable-logging = true

uid = www-data
gid = www-data

daemonize = /home/pi/wallpad/uwsgi-emperor.log

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다