When managing a Django application with uWSGI and Nginx, you might need to reload configurations without causing downtime. While /etc/init.d/nginx reload
works smoothly for Nginx, uWSGI requires a different approach for a graceful reload.
uwsgi.reload Might Not Work /h2>
Calling uwsgi.reload()
in Python or using restart uwsgi
in bash often only affects the current worker process. This is insufficient when hosting multiple sites under a single uWSGI instance.
uWSGI provides a graceful reload mechanism through its master FIFO pipe. Here's how to implement it:
# First, ensure your uWSGI configuration includes:
# master-fifo = /path/to/your/fifo.sock
# Then send the reload command:
echo r > /path/to/your/fifo.sock
Here's a complete bash script that handles both Nginx and uWSGI reloads gracefully:
#!/bin/bash
# Reload Nginx
/etc/init.d/nginx reload
# Graceful uWSGI reload
UWSGI_FIFO="/path/to/your/fifo.sock"
if [ -p "$UWSGI_FIFO" ]; then
echo r > "$UWSGI_FIFO"
echo "Sent graceful reload signal to uWSGI"
else
echo "uWSGI FIFO not found at $UWSGI_FIFO"
exit 1
fi
If you need to trigger this from Django:
import subprocess
def graceful_reload():
try:
# Reload Nginx
subprocess.run(['/etc/init.d/nginx', 'reload'], check=True)
# Graceful uWSGI reload
with open('/path/to/your/fifo.sock', 'w') as fifo:
fifo.write('r')
return True
except Exception as e:
print(f"Reload failed: {str(e)}")
return False
After sending the reload signal, check your uWSGI logs for confirmation. You should see messages like:
gracefully (RE)spawned uWSGI worker
Another common method is using touch-reload:
# In your uWSGI config:
touch-reload = /path/to/trigger/file
# Then trigger reload by:
touch /path/to/trigger/file
When managing Django applications with uWSGI, many developers face a common challenge: how to reload uWSGI gracefully without affecting all running processes. The standard approaches like restart uwsgi
or uwsgi.reload()
in Python often only affect the calling process rather than all hosted sites.
uWSGI provides several methods for graceful reloads:
- Sending SIGHUP to the master process
- Using the
--touch-reload
option - Employing the uWSGI signal framework
Here's a robust bash script solution that properly reloads all uWSGI processes:
#!/bin/bash
# Gracefully reload uWSGI without restarting all processes
UWSGI_PID=$(cat /var/run/uwsgi.pid)
if [ -f "$UWSGI_PID" ]; then
kill -HUP $UWSGI_PID
echo "uWSGI reload signal sent successfully"
else
echo "uWSGI pid file not found at /var/run/uwsgi.pid"
exit 1
fi
For Django applications that need to trigger reloads programmatically:
import os
import signal
def graceful_uwsgi_reload():
try:
with open('/var/run/uwsgi.pid') as f:
pid = int(f.read())
os.kill(pid, signal.SIGHUP)
return True
except Exception as e:
print(f"Failed to reload uWSGI: {str(e)}")
return False
For more control over the reload behavior, consider these uWSGI configuration options:
[uwsgi]
master = true
processes = 4
touch-reload = /path/to/reload.trigger
lazy-apps = true
After sending the reload signal, verify it worked by checking the uWSGI logs:
tail -f /var/log/uwsgi.log | grep -i "reload"
You should see messages indicating successful worker respawning without master process restart.
- Permission issues: Ensure your script has rights to read the pid file and send signals
- Missing master process: The master process must be running for graceful reload to work
- Configuration errors: Verify
lazy-apps
is set correctly for your use case