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.