uWSGI
uWSGI is a fast, self-healing and developer/sysadmin-friendly application container server coded in pure C.
There are alternatives written in Python such as gunicorn.
Installation
Install the uwsgi package. Plugins need to be installed separately (their package names start with uwsgi-plugin-).
Configuration
Web applications served by uWSGI are configured in /etc/uwsgi/, where each of them requires its own configuration file (ini-style). Details can be found in the uWSGI documentation.
Alternatively, you can run uWSGI in Emperor mode (configured in /etc/uwsgi/emperor.ini). It enables a single uWSGI instance to run a set of different apps (called vassals) using a single main supervisor (called emperor).
--plugins command-line option or with the plugins variable in the configuration file.Web applications
uWSGI supports many different languages and thus also many web applications.
As an example the configuration file /etc/uwsgi/example.ini and the prior installation of the plugin needed for your web application is assumed.
Python
The following is a simple example for a Python application.
/etc/uwsgi/example.ini
[uwsgi] chdir = /srv/http/example module = example plugins = python
It is also possible to run uWSGI separately with the following syntax for instance:
$ uwsgi --socket 127.0.0.1:3031 --plugin python2 --wsgi-file ~/foo.py --master --processes 4 --threads 2 --stats 127.0.0.1:9191 --uid --gid
You should avoid running this command as root.
PHP
The following is a simple example for a PHP based website.
/etc/uwsgi/example.ini
[uwsgi] ; maximum number of worker processes processes = 4 ; the user and group id of the process once it’s started uid = http gid = http socket = /run/uwsgi/%n.sock master = true chdir = /srv/http/%n ; php plugins = php ; jail our php environment php-docroot = /srv/http/%n php-index = index.php ; clear environment on exit vacuum = true
Web server
uWSGI can be the backend to many web servers, that support the forwarding of access. The following are examples for configurations.
Nginx
nginx can redirect access towards unix sockets or ports (on localhost or remote machine), depending on your web application.
Nginx (in chroot)
First create ini file that will point to your application:
Since we are chrooting to above configuration will result in following unix socket being created /srv/http/run/application1.sock
You will need to disable notifications within your service file:
/etc/systemd/system/multi-user.target.wants/uwsgi\@application1.service
[Unit] Description=uWSGI service unit After=syslog.target [Service] PIDFile=/run/%I.pid RemainAfterExit=yes ExecStart=/usr/bin/uwsgi --ini /etc/uwsgi/%I.ini ExecReload=/bin/kill -HUP $MAINPID ExecStop=/bin/kill -INT $MAINPID Restart=always StandardError=syslog KillSignal=SIGQUIT [Install] WantedBy=multi-user.target
After modification make sure to reload to incorporate the new or changed units.
You are then free to enable and start .
Edit and add new section within it that would contain at least following:
Make sure to now restart nginx.service to have your be served at .
Running uWSGI
If you plan on using a web application all the time (without it being activated on demand), you can simply start and enable .
If you plan on having your web application be started on demand you can start and enable uwsgi@example.socket.
Tips and tricks
Some functionality, that uWSGI offers is not accessible by using the systemd service files provided in the official repositories. Changes to them are explained in the following sections. For further information see .
Socket activation
Using socket activation, you want to
- direct your web server to a unix socket and thereby start your uWSGI instance running the application
- you most likely want to have the application be closed by uWSGI after a certain idle time
- you want your web server be able to start the application again, once it is accessed
uWSGI offers settings, with which you can have the instance close the application:
The current file however does not allow this, because systemd treats non-zero exit codes as failure and thereby marking the unit as failed and additionally the directive makes a closing after idle time useless. A fix for this is to add the exit codes, that uWSGI may provide after closing an application by itself to a list, that systemd will treat as success by using the directive (for further information see ).
/etc/systemd/system/uwsgi-socket@.service
[Unit] Description=uWSGI service unit After=syslog.target [Service] ExecStart=/usr/bin/uwsgi --ini /etc/uwsgi/%I.ini ExecReload=/bin/kill -HUP $MAINPID ExecStop=/bin/kill -INT $MAINPID Type=notify SuccessExitStatus=15 17 29 30 StandardError=syslog NotifyAccess=all KillSignal=SIGQUIT [Install] WantedBy=multi-user.target
This will allow for proper socket activation with kill-after-idle functionality.
Hardening uWSGI service
Web applications are exposed to the wild and depending on their quality and the security of their underlying languages, some are more dangerous to run, than others. A good way to start dealing with possible unsafe web applications is to jail them. systemd has some functionality, that can be put to use. Have a look at the following example (and for further information see and ):
Accessibility of uWSGI socket
The default (per application) socket unit () in uwsgi allows read and write access to any user on the system. However, systemd allows for a more finely granulated access management (see ), with which the access to a unix socket can be made more restrictive.
By creating it below a webapp specific directory below (needs to be created using tmpfiles beforehand - for reference see Web application package guidelines) and modifying its group and file permissions, the socket is only accessible to root and the web server and allows the web application to run as its own user: