Debian Jessie, Nginx, PHP, UWSGI quick start

I had to host a potential unsecure PHP web application. So I though
writing a small c programm which creates a network, filesystem, pid,
uts, and ipc namespace and run php-fpm inside it. I needd from the PHP
web application access to a mysql database, mailserver and ftp server of
the localhost. I stumbled across uwsgi and thought less programming for
me, but it took me several hours to get it finally running so I write up
this quickstart guide for others who will face the same problem. I would
also like feedback from others who are doing the same. Maybe you can add
this quickstart guide to the uwsgi website after reviewing it.

  • First it is necessary to setup a debootstrap of the distribution you
    want to use. For me it was Debian Jessie amd64. And add the php5-mysql
    package and any other php5 extensions you might need. I also searched
    for any user writable directories, deleted them and symlinked them to

/usr/sbin/debootstrap --arch amd64 jessie /distro/jessie
cd /distro/jessie
chroot .
mount -t proc none /proc
apt-get --no-install-recommends install php5-mysql
find . -type d -perm -o+w -exec ls -adl {} ;
rm ./var/lib/php5/sessions
ln -s /tmp ./var/lib/php5/sessions


  • Than I installed on the host the uwsgi-emperor and uwsgi-plugin-php

apt-get install uwsgi-emperor uwsgi-plugin-php

  • Next is the configuration. I tried to create a root from the existing
    system without using debootstrap which always failed at the chroot
    step for me. So at one point I decided to go with debootstrap. I
    changed one other challenge: I needed to be able to reach the socket
    of uwsgi-plugin-php and have communication to mysql, postfix, and the
    ftp server. As soon as I enabled network namespaces that communication
    was gone. The options are: Don’t do network namespaces (not an option
    for me), use unix sockets (not an option for ftp and mail) or use
    veth, macvlan or the uwsgi TunTap Router (I did not want to go the
    network communication through userland). So I used veth. Note that the
    new network namespace does not get a default route. For the network
    configuration I used a /30 but I probably should have used
    One problem I faces is reaching the socket of uwsgi after enable
    network namespaces. Is there a way to let the emperor listen and
    forward the communication channel to the vassals using two
    filedescriptors so that I don’t need shared filesystem for the unix
    socket or an ip address to communicate from the host to the vassal?

(infra) [~] cat /etc/uwsgi-emperor/emperor.ini
emperor = /etc/uwsgi-emperor/vassals
emperor-use-clone = ipc,uts,pid,net
master = true

exec-as-emperor = ip link del veth0
exec-as-emperor = ip link add veth0 type veth peer name veth1
exec-as-emperor = ifconfig veth0 netmask up
exec-as-emperor = ip link set veth1 netns $UWSGI_VASSAL_PID

(infra) [~] cat /etc/uwsgi-emperor/vassals/shell.ini
socket =

uid = www-data
gid = 33
unshare = fs
hook-post-jail = mount:none /distro/jessie /ns bind,ro
pivot_root = /ns /ns/.old
hook-as-root = mount:proc none /proc nodev hidepid=2
hook-as-root = mount:tmpfs none /tmp
hook-as-root = mount:none /.old/srv/www/shell /srv/www/shell bind
hook-as-root = mount:none /.old/dev/pts /dev/pts bind
hook-as-root = umount:/.old rec,detach

wait-for-interface = veth1
exec-as-root = hostname vassal001
exec-as-root = ifconfig lo up
exec-as-root = ifconfig veth1 netmask up

plugin = 0:php
php-allowed-ext = .php
php-docroot = /srv/www/shell
php-index = index.php
php-set =

processes = 10
cheaper = 2

(infra) [~] cat /etc/nginx/nginx.conf

server {

    server_name; # the host is gone . :-)

    root /srv/www/shell;

    disable_symlinks on;
    autoindex off;

    index index.php;

    location ~ \.php$ {
            include /etc/nginx/uwsgi_params;


Here are some useful sources that I used during the process:

I appreciate any tips to improve the above configuration, errors that I
might did and also if there is another tool which is probably easier
than uwsgi to configure which can do the same thing. I like uwsgi, but
it took me yesterday several hours to get it running and I found the
documentation to be very confusing.


Am 02.01.2016 um 08:37 schrieb Thomas G. [email protected]:

I had to host a potential unsecure PHP web application. So I though about
writing a small c programm which creates a network, filesystem, pid,
uts, and ipc namespace and run php-fpm inside it.

Excuse me if I’m blunt, but: can’t you just use php-fpm’s chroot
What’s the advantage of using uwsgi for php, apart from some tricks you
really cannot do with php-fpm (running multiple PHPs at the same time).

I’ve chrooted all my php-fpm instances (under FreeBSD) and it works very

Of course, you can’t talk to any socket directly anymore. But that’s a
minor issue IMO.