documentation: update systemd deploy unit examples (#1950)

There's no need for PIDFile=, especially not for Type=notify services.
systemd knows the correct pid of the process it manages.

No need for the `--bind` option either, since gunicorn supports the
LISTEN_FDS environment variable and will use all of the sockets that systemd
provides. This way, it's also more flexible, since we can specify several
sockets in a .socket unit.

The .socket unit should specify User=www-data so that nginx can connect to the socket.
The service (gunicorn process) will inherit the file descriptor so it
doesn't even need permissions for the socket (it's nginx which needs
permissions).

tmpfiles.d is not needed.

replace ExecStop=/bin/kill with KillMode=mixed
This commit is contained in:
Дамјан Георгиевски 2019-01-11 13:52:06 +01:00 committed by Benoit Chesneau
parent 9184ae8898
commit ba0d784960

View File

@ -212,12 +212,15 @@ Using Gunicorn with upstart is simple. In this example we will run the app
Systemd Systemd
------- -------
A tool that is starting to be common on linux systems is Systemd_. Below are A tool that is starting to be common on linux systems is Systemd_. It is a
configurations files and instructions for using systemd to create a unix socket system services manager that allows for strict process management, resources
for incoming Gunicorn requests. Systemd will listen on this socket and start and permissions control.
gunicorn automatically in response to traffic. Later in this section are
instructions for configuring Nginx to forward web traffic to the newly created Below are configurations files and instructions for using systemd to create
unix socket: a unix socket for incoming Gunicorn requests. Systemd will listen on this
socket and start gunicorn automatically in response to traffic. Later in
this section are instructions for configuring Nginx to forward web traffic
to the newly created unix socket:
**/etc/systemd/system/gunicorn.service**:: **/etc/systemd/system/gunicorn.service**::
@ -228,14 +231,18 @@ unix socket:
[Service] [Service]
Type=notify Type=notify
# the specific user that our service will run as
User=someuser User=someuser
Group=someuser Group=someuser
# another option for an even more restricted service is
# DynamicUser=yes
# see http://0pointer.net/blog/dynamic-users-with-systemd.html
RuntimeDirectory=gunicorn RuntimeDirectory=gunicorn
WorkingDirectory=/home/someuser/applicationroot WorkingDirectory=/home/someuser/applicationroot
ExecStart=/usr/bin/gunicorn --pid /run/gunicorn/pid \ ExecStart=/usr/bin/gunicorn applicationname.wsgi
--bind unix:/run/gunicorn.sock applicationname.wsgi
ExecReload=/bin/kill -s HUP $MAINPID ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID KillMode=mixed
TimeoutStopSec=5
PrivateTmp=true PrivateTmp=true
[Install] [Install]
@ -248,33 +255,47 @@ unix socket:
[Socket] [Socket]
ListenStream=/run/gunicorn.sock ListenStream=/run/gunicorn.sock
User=someuser # Our service won't need permissions for the socket, since it
Group=someuser # inherits the file descriptor by socket activation
# only the nginx daemon will need access to the socket
User=www-data
# Optionally restrict the socket permissions even more.
# Mode=600
[Install] [Install]
WantedBy=sockets.target WantedBy=sockets.target
**/etc/tmpfiles.d/gunicorn.conf**::
d /run/gunicorn 0755 someuser somegroup - Next enable and start the socket (it will autostart at boot too)::
Next enable the socket so it autostarts at boot:: systemctl enable --now gunicorn.socket
systemctl enable gunicorn.socket
Either reboot, or start the services manually::
systemctl start gunicorn.socket
After running ``curl --unix-socket /run/gunicorn.sock http``, Gunicorn Now let's see if the nginx daemon will be able to connect to the socket.
should start and you should see some HTML from your server in the terminal. Running ``sudo -u www-data curl --unix-socket /run/gunicorn.sock http``,
our Gunicorn service will be automatically started and you should see some
HTML from your server in the terminal.
.. note::
systemd employs cgroups to track the processes of a service, so it doesn't
need pid files. In the rare case that you need to find out the service main
pid, you can use ``systemctl show --value -p MainPID gunicorn.service``, but
if you only want to send a signal an even better option is
``systemctl kill -s HUP gunicorn.service``.
.. note::
``www-data`` is the default nginx user in debian, other distriburions use
different users (for example: ``http`` or ``nginx``). Check you distro to
know what to put for the socket user, and for the sudo command.
You must now configure your web proxy to send traffic to the new Gunicorn You must now configure your web proxy to send traffic to the new Gunicorn
socket. Edit your ``nginx.conf`` to include the following: socket. Edit your ``nginx.conf`` to include the following:
**/etc/nginx/nginx.conf**:: **/etc/nginx/nginx.conf**::
user www-data;
... ...
http { http {
server { server {
@ -292,15 +313,15 @@ socket. Edit your ``nginx.conf`` to include the following:
The listen and server_name used here are configured for a local machine. The listen and server_name used here are configured for a local machine.
In a production server you will most likely listen on port 80, In a production server you will most likely listen on port 80,
and use your URL as the server_name. and use your URL as the server_name.
Now make sure you enable the nginx service so it automatically starts at boot:: Now make sure you enable the nginx service so it automatically starts at boot::
systemctl enable nginx.service systemctl enable nginx.service
Either reboot, or start Nginx with the following command:: Either reboot, or start Nginx with the following command::
systemctl start nginx systemctl start nginx
Now you should be able to test Nginx with Gunicorn by visiting Now you should be able to test Nginx with Gunicorn by visiting
http://127.0.0.1:8000/ in any web browser. Systemd is now set up. http://127.0.0.1:8000/ in any web browser. Systemd is now set up.