Progetto

Generale

Profilo

Configurare nginx e uWSGI per l'uso del protocollo nativo

A partire dalla versione 0.8.40 ngnix supporta direttamente il protocollo uwsgi, che consente di utilizzarlo come proxy per uWSGI in maniera ottimizzata. Per poterlo utilizzare in tal modo occorre però modificare opportunamente la sezione location. Una configurazione ordinaria, infatti prevede l'uso della direttiva proxy_pass, che dovrà essere sostituita da uwsgi_pass, un esempio delle modifiche da effettuare è il seguente:

upstream mio-servizio {
       server 127.0.0.1:8000;
}
server {
        listen IL.MIO.IP.PUB:443 ssl;
        server_name miosito.it;
[...]
        location / {
# removed
#           proxy_pass http://mio-servizio;
#           proxy_http_version 1.1;
#           proxy_pass_header Server;
# added
            uwsgi_pass        mio-servizio;
            include           uwsgi_params;
# unchanged
            proxy_redirect off;
            proxy_set_header Host $http_host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Scheme $scheme;
            proxy_set_header X-Forwarded-Proto $thescheme;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }       

Si abbia cura di verificare che il file uwsgi_params, fornito con l'installazione di uWSGI, sia correttamente installato in /etc/nginx/.

Ovviamente occorrerà anche lanciare il comando uwsgi per indicargli di utilizzare nativamente il protocollo uwsgi, per questo invece di usare la direttiva --http occorrerà utilizzare la direttiva --socket; in particolare una configurazione usata per la comunicazione in maniera ordinaria con proxy_pass come la seguente:

/usr/local/bin/uwsgi --http 127.0.0.1:8000 --stats 127.0.0.1:8001 \
  --http-websockets --gevent 100 --module  mymodule.uwsgi

dovrà essere modificata in:

/usr/local/bin/uwsgi --socket 127.0.0.1:8000  --stats 127.0.0.1:8001 \
  --http-websockets --gevent 100 --module mymodule.uwsgi

Come ulteriore ottimizzazione, se come negli esempi precedenti si sta facendo riferimento ad un servizio che gira sulla stessa macchina, è preferibile anche evitare l'ulteriore overhead di utilizzare socket TCP, ed usare direttamente un socket locale. In questo caso è necessario modificare opportunamente (rispetto all'esempio precedente) la direttiva server nella sezione upstream di ngnix per fargli utilizzare il socket, con qualcosa del tipo:

upstream mio-servizio {
       server unix:///tmp/my-application.sock;
}

mentre dall'altro lato si dovrà modificare la modalità con cui si avvia uwsgi per fargli usare un socket locale lanciandolo come:

/usr/local/bin/uwsgi --socket /tmp/my-application.sock  --stats 127.0.0.1:8001 \
  --chmod-socket=640 --chown-socket=www-data \
  --http-websockets --gevent 100 --module mymodule.uwsgi

in modo da creare il socket con i giusti permessi ed un proprietario che ne consenta l'accesso da nginx.