How to Gracefully Stop uWSGI Without PID File When Running on Socket


3 views

When running uWSGI with socket configuration but without explicitly defining a pidfile, developers often face challenges stopping the service gracefully. The standard uwsgi --stop command requires a pidfile, leading to frustration when trying to terminate the process.

Simply using kill or pkill often results in uWSGI respawning due to its master-worker architecture. For example:

# This might cause respawn
pkill -f "uwsgi --ini config.ini"

Here are three reliable approaches to stop uWSGI without a pidfile:

1. Using Master FIFO

Modify your uWSGI configuration to include master FIFO:

[uwsgi]
socket = 127.0.0.1:3000
master-fifo = /tmp/uwsgi-fifo

Then stop it with:

echo q > /tmp/uwsgi-fifo

2. Leveraging TCP Connection

If you're using TCP socket, you can connect and send the stop command:

# Python example
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('127.0.0.1', 3000))
s.send(b'q')
s.close()

3. Smart Process Identification

Find and terminate the master process specifically:

# Linux/Unix
MASTER_PID=$(ps aux | grep "[u]wsgi --ini config.ini" | awk '{print $2}')
kill -s QUIT $MASTER_PID

To avoid this issue in future deployments, always add pidfile configuration:

[uwsgi]
socket = 127.0.0.1:3000
pidfile = /tmp/uwsgi.pid

This enables standard stop commands:

uwsgi --stop /tmp/uwsgi.pid

For production systems, consider using systemd which handles process management automatically:

[Unit]
Description=uWSGI Service

[Service]
ExecStart=/path/to/uwsgi --ini config.ini
Restart=always
KillSignal=SIGQUIT

[Install]
WantedBy=multi-user.target

When running uWSGI without explicitly defining a pidfile in your configuration, stopping the service becomes non-trivial. Unlike traditional daemons, uWSGI doesn't automatically create a PID file unless configured to do so.

First, identify the uWSGI master process:

ps aux | grep uwsgi
# Output example:
# user   1234  0.0  0.5  44572 12345 ?        S    14:30   0:00 uwsgi --ini config.ini

Method 1: Using Master FIFO

If you have access to restart the instance, add FIFO configuration:

[uwsgi]
socket = 127.0.0.1:3000
master-fifo = /tmp/uwsgi_fifo

Then stop using:

echo q > /tmp/uwsgi_fifo

Method 2: Signal-based Termination

Send SIGTERM to the master process:

kill -TERM 1234  # Replace with actual PID

For stubborn instances, use SIGINT:

kill -INT 1234

Method 3: TCP Connection

For Emperor-mode instances:

uwsgi --connect-and-read /tmp/uwsgi_emperor.sock

If uWSGI keeps respawning, ensure you're killing the master process (usually the one with lowest PID). Use:

pstree -p | grep uwsgi

Always include these in your config:

[uwsgi]
pidfile = /run/uwsgi/%n.pid
daemonize = /var/log/uwsgi/%n.log

For production systems, consider using systemd:

[Unit]
Description=uWSGI Emperor
After=syslog.target

[Service]
ExecStart=/path/to/uwsgi --emperor /etc/uwsgi/vassals
Restart=always
KillSignal=SIGQUIT

[Install]
WantedBy=multi-user.target