Compilare uWsgi con PHP

uWsgi, è un potente Web Gateway Server, il cui compito è interfacciare, il web server (Apache, Nginx), con il nostro applicativo. uWsgi permette l'esecuzione di diversi applicativi in diversi linguaggi e tutti contemporaneamente (Python, Php, Java, Ruby). La gestione degli stessi e molto efficace e efficiente.

La forza di uWsgi sta nell'enorme modularità. È molto facile scrivere un plugin per aggiungere nuove funzionalità o supporto a nuovi linguaggi. Visto l'ottimo build system è semplice, ricompilare e installare l'applicativo, sul nostro sistema.

Pacchetti necessari

# C compiler
yum groupinstall 'Development Tools'

# lib required for compile uwsgi
yum install git php-embedded php-devel bzip2-devel zlib-devel libxml2-devel krb5-devel ncurses-devel gmp-devel openssl-devel libedit-devel python-devel

# additional pakages
yum install wget vim htop

Scarichiamo uWsgi

cd /tmp
# go to https://github.com/unbit/uwsgi/releases and check last release
# back to old stable version
git clone https://github.com/unbit/uwsgi.git
git checkout (LAST_VERSION)

Configurare uWsgi per PHP, Python

Il build system copia automaticamente i file nelle cartelle di competenza. Per una maggiore flessibilità gli sviluppatori hanno preferito creare script di installazione custom e non utilizzare i tipici strumenti del caso come autogen/automake.

cd uwsgi/
cd buildconf # Cartella con le configurazioni di base
cp base.ini myconf.ini

Copiamo la configurazione di base, modifichiamo la stessa aggiungendo PHP, e Python. E' possibile compilare i plugin per essere embeddati nell'eseguibile, oppure esterni come shared object.

Se scegliamo un approccio più modulare, si guadagna in flessibilità. Scegliendo invece un approccio statico il server guadagna qualcosa in velocità. E' importante modificare la cartella di destinazione dei plugin:

  • /usr/local/lib/uwsgi_plugin
  • /usr/lib/uwsgi_plugin
# uwsgi-version/buildconf/NomedellaTuaConf.ini
[uwsgi]
xml = auto
yaml = true
json = auto
ssl = auto
pcre = auto
routing = auto
debug = false
unbit = false
malloc_implementation = libc
extras =
plugins =
bin_name = uwsgi
append_version =
plugin_dir = /usr/local/lib/uwsgi_plugin
embedded_plugins = %(main_plugin)s, ping, cache, nagios, rrdtool, carbon, rpc, corerouter, fastrouter, http, ugreen, signal, syslog, rsyslog, logsocket, router_uwsgi, router_redirect, router_basicauth, zergpool, redislog, mongodblog, router_rewrite, router_http, logfile, router_cache, rawrouter, router_static, sslrouter, spooler, cheaper_busyness, symcall, transformation_tofile, transformation_gzip, transformation_chunked, transformation_offload, router_memcached, router_redis, router_hash, router_expires, router_metrics, transformation_template, stats_pusher_socket, router_fcgi,php,python
as_shared_library = false

locking = auto
event = auto
timer = auto
filemonitor = auto

blacklist =
whitelist =

embed_files =

embed_config =

Le principali modifiche sono il percorso di configurazione dei plugin dove uwsgi recupera le sharedlibrary .SO. Per installare e compilare uWsgi, usiamo i seguenti comandi

# compilare e installare uwsgi

# nome della configurazione che vuoi installare, presa da buildconf
export UWSGI_PROFILE="NomeTuaConf.ini" 
python setup.py install

Configurazione di Uwsgi in modalità emperor

Probabilmente se abbiamo fatto questa scelta è perchè desideriamo deploiare sullo stesso server più applicativi di diverso tipo, o molti applicativi tutti simili (Django,Php). In questo caso modalità uWsgi Emperor è quello che serve. Vediamo come configurarla.

Configurazione uWsgi emperor

vim /etc/uwsgi.ini

[uwsgi]
uid=nginx
gid=nginx
pidfile = /run/uwsgi/uwsgi.pid
emperor = /etc/uwsgi.d
plugins-dir = /usr/local/lib/uwsgi_plugin
plugins = php

stats = /run/uwsgi/stats.sock
cap = setgid,setuid

Configurazione del Vassallo

uWsgi ora è avviato e pronto a lanciare dei vassalli. Ogni vassallo è un applicativo che viene lanciato da uWsgi. Ogni applicativo è avviato come processo separato, ed è possibile ridurre i permessi per ogni vassallo che viene configurato per utilizzare il relativo plugin. In questo modo è possibile creare un vassallo PHP, oppure un vassallo Python-Django.

Questo è un esempio, di file di configurazione per lanciare un vassallo  PHP.

[uwsgi]
plugin=php
project=test

chdir=/var/www/wordpress
master=True
pidfile=/run/uwsgi/%(project).pid
processes=8
cheaper=1
stats=/run/uwsgi/%(project).st.sock
#heaper=1
harakiri = 120
vacuum=true
logto=/var/log/uwsgi/%(project).log
socket = /run/uwsgi/%(project).sock

# php-allowed-ext=.php
# php-allowed-ext=.inc

Questo file di configurazione, va salvato nella cartella /etc/uwsg.d/

Un utile suggerimento, è quello di conservare tutti i file di configurazione, di uWsgi all'interno della cartella stessa del progetto e linkare questi con un link simbolico.

I file all'interno della cartella /etc/uwsgi.d sono monitorati da uWsgi. Per riavviare un vassallo è sufficiente, eseguire touch del relativo file.

Configurazione di Nginx

server {
        server_name test.blog.it;
        root /var/www/wordpress;
        index index.php;

        location = /favicon.ico {
                log_not_found off;
                access_log off;
        }

        location = /robots.txt {
                allow all;
                log_not_found off;
                access_log off;
        }

        location / {
                try_files $uri $uri/ /index.php?$args;
        }

        location ~ \.php$ {
            root /var/www/wordpress;
	        include uwsgi_params;
            uwsgi_modifier1 14;
            uwsgi_pass unix:///run/uwsgi/test.sock;        
        }

        location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
                expires max;
                log_not_found off;
        }
}

La configurazione di Nginx è molto standard.