[PYTHON] UWSGI setting memo when operating properly

I made a backend for a certain app with Flask + uWSGI + Nginx, so I summarized what I did.

Cooperation with Nginx

How to connect with wsgi protocol

nginx.conf


location / {
    include uwsgi_params;
    uwsgi_pass 127.0.0.1:3031;
}

uwsgi.ini


socket=127.0.0.1:3031

By the way, with this setting, I can't see anything even if I hit http://127.0.0.1:3031 with a browser saying debug debug only for uWSGI. I was addicted to uwsgi for a few minutes without knowing the difference between the optional socket and http.

How to connect as an http proxy

nginx.conf


location / {
    include uwsgi_params;
    proxy_pass http://127.0.0.1:3031;
}

uwsgi.ini


http=127.0.0.1:3031

Intuitive proxy. At first I thought this was the only way. This is the one you can see at http://127.0.0.1:3031.

Method of connecting with socket (adopted)

Basically, this is fine because it does not consume an extra port number when publishing multiple apps. This is adopted.

nginx.conf


location / {
    include uwsgi_params;
    uwsgi_pass unix:/path/to/app/app.sock;
}

uwsgi.ini


socket=/path/to/app/app.sock

uWSGI Emperor

Use it because it is convenient when managing multiple apps with uWSGI.

Reference: http://qiita.com/5t111111/items/e170fead91261621b054#1-8

Automatic startup has also become easier!

Fine tuning parameters

processes, limit-as, max-requests, harakiri, etc. harakiri.

Reference: http://docs.djangoproject.jp/en/latest/howto/deployment/wsgi/uwsgi.html

It's a Django site, but if it's a wsgi app, Flask is also helpful. By the way, daemonize and master use Emperor, so they are not turned on. I think that's probably the case, but I'm sorry if it's different. I'm waiting for Tsukkomi.

Tweak the settings while doing load tests.

UWSGI reload on deployment

Even if the file is changed, it will not be reflected, so

uwsgi.ini


touch-reload=/path/to/app/reload.trigger

Anyway, if you touch /path/to/app/reload.trigger at the time of deployment, uWSGI will reload at the next request reception. I decided to put touch in the deployment script.

Reference: http://field-notes.hatenablog.jp/entry/2012/05/09/115600

(Another solution) Monitor files. Reference: http://d.hatena.ne.jp/dayflower/20121017/1350447805

Don't lose track of log files with log rotation

The guy who becomes a girl after the release.

uwsgi.ini


touch-logreopen=/path/to/app/logreopen.trigger

Anyway,

/path/to/uwsgi.log {
    daily
    rotate 7
    missingok
    notifempty
    compress
    sharedscripts
    size 1M
    postrotate
        touch /path/to/app/logreopen.trigger
    endscript
}

Reference: http://taichino.com/memo/3843

(Addition) After all, I wrote that it looks like this

/etc/nginx/conf.d/sample_nginx.conf

sample_nginx.conf


#I hate it when I get hit by IP. You don't have to
server {
    listen  80 default_server;
    server_name _;
    root    /var/app/dummy;
    index index.html;
}

server {
    listen      80;
    server_name sample.com;
    charset     utf-8;
    client_max_body_size 75M;

    location / { try_files $uri @uwsgi; }
    #Let's leave static to Nginx
    location /static/ {
        root /var/app/sample/webapp;
    }
   location @uwsgi {
        include uwsgi_params;
        uwsgi_pass unix:/var/app/sample/sample_uwsgi.sock;
    }
}

/etc/uwsgi/vassals/sample_uwsgi.ini

Put uwsgi.ini in / etc / uwsgi / vassals / for uWSGI Emperor.

sample_uwsgi.ini


[uwsgi]
base = /var/app/sample

app = main #Flask starts main.If it is py, main
#Sample for Django.wsgi:It feels like an application

module = %(app)

#The path to the virtualenv that runs this app
#If you're using raw Python, is it the path to the Python directory?
home = /home/www-data/venvs/sampleapp

pythonpath = %(base)

socket = %(base)/%n.sock

chmod-socket    = 666

#the variable that holds a flask application inside the module imported at line #6
callable = app

#Logging
logto = /var/log/uwsgi/%n.log
#The guy who puts in the postrotate of logrotate
touch-logreopen = %(base)/.logreopen_trigger

#Trigger to reload uwsgi
touch-reload = %(base)/.uwsgi_touch

max-requests = 1000
harakiri = 60

#I used it from emperor so I commented it out
#master=True
#daemonize=/var/log/uwsgi/sample.log

/etc/init/uwsgi.conf (for starting uWSGI Emperor) (for CentOS6)

uwsgi.conf


description "uWSGI"
start on runlevel [2345]
stop on runlevel [06]
respawn

#I installed only uwsgi for uwsgi emperor and turned off the virtualenv named uwsgi. I.
#If not, you should specify the uwsgi installation destination and it will work.
env UWSGI=/home/www-data/venvs/uwsgi/bin/uwsgi
env LOGTO=/var/log/uwsgi/emperor.log

#Change uid and gid accordingly
exec $UWSGI --master --emperor /etc/uwsgi/vassals --die-on-term --uid www-data --gid www-data --logto $LOGTO
start uwsgi

Start all uwsgi apps under / etc / uwsgi / vassals. Do automatic startup as appropriate

/etc/systemd/system/uwsgi.service (for starting uWSGI Emperor) (for CentOS7)

uwsgi.service


[Unit]
Description=uWSGI
After=syslog.target

[Service]
#I installed only uwsgi for uwsgi emperor and turned off the virtualenv named uwsgi. I.
#If not, you should specify the uwsgi installation destination and it will work.
#Also change uid and gid as appropriate
ExecStart=/home/www-data/venvs/uwsgi/bin/uwsgi --master --emperor /etc/uwsgi/vassals --die-on-term --uid www-data --gid www-data --logto /var/log/uwsgi/emperor.log
Restart=always
KillSignal=SIGQUIT
Type=notify
StandardError=syslog
NotifyAccess=all

[Install]
WantedBy=multi-user.target
systemctl start uwsgi

Start all uwsgi apps under / etc / uwsgi / vassals. Automatic startup is appropriate.

Recommended Posts

UWSGI setting memo when operating properly
Memo of how to use properly when combining pandas.DataFrame
Pycharm setting memo writing
Work memo when introducing mitmproxy
[WSL2] CentOS 8 VScode setting memo