apt remove uwsgi uwsgi-core
rm /usr/bin/uwsgi
rm /usr/local/bin/uwsgi
rm -rf /usr/lib/uwsgi
rm -rf /usr/local/lib/uwsgi
Any config files in /etc
can stay.
Download and extract latest stable uWSGI tarball
wget https://projects.unbit.it/downloads/uwsgi-latest.tar.gz
tar xf uwsgi-latest.tar.gz
From the created directory run:
make PROFILE=nolang
this will build the uWSGI “core” binary.
We now build the plugins we want. The argument on the far right is whatever we want to name the plugin. For python, we generally want the name of the plugin to mirror the binaries installed on the system.
PYTHON=python ./uwsgi --build-plugin "plugins/python python"
PYTHON=python3 ./uwsgi --build-plugin "plugins/python python3"
PYTHON=python3.5 ./uwsgi --build-plugin "plugins/python python35"
PYTHON=python3.6 ./uwsgi --build-plugin "plugins/python python36"
PYTHON=python2 ./uwsgi --build-plugin "plugins/python python2"
PYTHON=python2.7 ./uwsgi --build-plugin "plugins/python python27"
Make sure the python binaries listed above actually exist. UWSGI will not complain if it doesn't and will likely use the default pyhton.
I also want PHP support, so...
./uwsgi --build-plugin "plugins/php"
Now we have uwsgi
, python_plugin.so
, python3_plugin.so
, python2_plugin.so
, etc..
You'll need to install uwsgi for each python version in their respective site-packages dirs.
# (run from inside the uwsgi src dir)
python setup.py install
python3 setup.py install
python3.6 setup.py install
Do this for each version of python installed on your system. If you don't do this, you'll get the error ImportError: No module named 'encodings'
You could, if you want, just run it out of that folder, but it's preferrable to install it in /usr/local
:
sudo mkdir /usr/local/lib/uwsgi/
sudo cp *_plugin.so /usr/local/lib/uwsgi/
sudo cp uwsgi /usr/local/bin/uwsgi
I like to run uwsgi emperor to manage vassals for each app.
Create /etc/systemd/system/uwsgi.service
[Unit]
Description=uWSGI Emperor
After=syslog.target
[Service]
ExecStart=/usr/local/bin/uwsgi --ini /etc/uwsgi/emperor.ini
ExecReload=/usr/bin/kill -HUP $MAINPID
Restart=always
KillSignal=SIGQUIT
Type=notify
StandardError=syslog
NotifyAccess=all
[Install]
WantedBy=multi-user.target
Create the emperor config in /etc/uwsgi/emperor.ini
[uwsgi]
emperor = /etc/uwsgi/vassals/*.ini
show-config = 1
uid = http
gid = http
emperor-stats = /run/uwsgi/emperor-stats.sock
umask = 002
logto = /var/log/uwsgi/emperor.log
Make sure any directories referenced above actually exist.
Enable and start the emperor
sudo systemctl enable uwsgi
sudo systemctl start uwsgi
I like to keep a base config for python apps which I symlink to the vassals
directory.
/etc/uwsgi/python-defaults.ini:
[uwsgi]
plugins = python3
# paths
base = /srv/%n
virtualenv = %(base)
logto = %(base)/log/uwsgi.%n.log
socket = /run/uwsgi/%n.sock
touch-reload = %(base)/reload
# default process settings
buffer-size = 32768
cpu-affinity = 2
workers = 1
harikiri-verbose = 60
max-requests = 5000
limit-as = 1024
show-config = 1
enable-threads = 1
# Trying to avoid OSError: write error
# https://stackoverflow.com/questions/36156887/uwsgi-raises-oserror-write-error-during-large-request
ignore-sigpipe = true
ignore-write-errors = true
disable-write-exception = true
# default environment variables
env = LANG=en_US.utf8
# load environment variables from config file
for-readline = /srv/%n/config.env
env = %(_)
endfor =
# load environment variables based on name in case dir is symlinked
for-readline = /srv/%n/config-%n.env
env = %(_)
endfor =
if-file = /srv/%n/uwsgi.ini
ini = /srv/%n/uwsgi.ini
endif =
Then for each app, I can just make a symlink to enable it:
sudo ln -s /etc/uwsgi/python-defaults.ini /etc/uwsgi/vassals/my-app.ini
Thank you so much!