Automated graceful reload of gunicorn in production
I have an automated deployment workflow that pushes code out to my production servers and triggers database migrations, static file updates, etc. Problem is, gunicorn doesn't automatically reload code changes without the development option --reload
, which they recommend not using in production. Instead the instruction is to send an HUP
signal to the masterpid
. Problem is, I don't know how to retrieve the masterpid
in an automated script, though it is easy enough to do manually.
How can I retrieve the materpid
value for the gunicorn systemd process in a bash script?
Solution 1:
Add the following to the systemd service file for gunicorn
, or add it as an override:
ExecReload=/bin/kill -HUP $MAINPID
You can then reload with systemctl reload gunicorn
.
Solution 2:
More detailed explanation for editing your gunicorn service file (based on the answer of @jordanm):
Edit your service file /etc/systemd/system/my_task.service
or a similar path
[Unit]
Description=My task running runicorn
After=network.target
[Service]
User=my_user
# [...]
ExecStart=/home/my_user/my_task/.venv/bin/gunicorn --workers 3 --bind unix:my_task.sock -m 007 wsgi:app
ExecReload=/bin/kill -HUP $MAINPID # <------ add this line
[Install]
WantedBy=multi-user.target
Save it, then run the following to reload the config
sudo systemctl enable my_task
Then you can run the following to gracefully restart your gunicorn service (this should be run in your deploy script)
sudo systemctl reload my_task gunicorn restart
If you don't run the systemctl enable my_task
command, you might get the following error:
Failed to reload my_task.service: Job type reload is not applicable for unit my_task.service. See system logs and 'systemctl status my_task.service' for details.