How to automatically create a runtime folder with a systemd service or tmpfiles.d?
Solution 1
I added in PermissionsStartOnly=True
and set a runtime folder per service, as suggested. I also added 0
to the start of the folder mode.
[Unit]
Description=gunicorn_django daemon
After=network.target
[Service]
PermissionsStartOnly=True
User=gunicorn
Group=www-data
RuntimeDirectory=gunicorn_django
RuntimeDirectoryMode=0775
PIDFile=/run/gunicorn_django/django_test_pid
WorkingDirectory=/vagrant/webapps/django_venv/django_test
ExecStart=/vagrant/webapps/django_venv/bin/gunicorn --pid /run/gunicorn_django/django_test_pid --workers 3 --bind unix:/run/gunicorn_django/django_test_socket django_test.wsgi --error-logfile /var/log/gunicorn/django_test_error.log
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID
[Install]
WantedBy=multi-user.target
It's now creating a folder with the correct permissions.
drwxrwxrw- 2 gunicorn www-data 40 Mar 30 07:11 gunicorn_django/
Thanks @quixotic and @mark-stosberg
Solution 2
My problem was that I had two services using same RuntimeDirectory
(isc-dhcp-server
and isc-dhcp-server6
), but I configured only one to work. So when the second one died, its runtime directory got removed, making it a problem for the first service.
Related videos on Youtube
Comments
-
geonaut over 1 year
I'm trying to create a runtime folder at
/run/gunicorn
for some Gunicorn socket / PID files, which are for a Django application. I can get everything working if I manually create directories. However, I'm trying to make this a robust setup, and eventually use Ansible to automate everything.I think I have 2 options, based on this question.
Option 1 - RuntimeDirectory
I think the first option is to use
RuntimeDirectory=
within my systemd service file, but I can't get it to create the folder. The service files contains:#/etc/systemd/system/gunicorn_django_test.service [Unit] Description=gunicorn_django daemon After=network.target [Service] User=gunicorn Group=www-data RuntimeDirectory=gunicorn #This line is supposed to create a directory RuntimeDirectoryMode=755 PIDFile=/run/gunicorn/django_test_pid WorkingDirectory=/vagrant/webapps/django_venv/django_test ExecStart=/vagrant/webapps/django_venv/bin/gunicorn --pid /run/gunicorn/django_test_pid --workers 3 --bind unix:/run/gunicorn/django_test_socket django_test.wsgi --error-logfile /var/log/gunicorn/django_test_error.log ExecReload=/bin/kill -s HUP $MAINPID ExecStop=/bin/kill -s TERM $MAINPID PrivateTmp=true [Install] WantedBy=multi-user.target
When I run
systemctl start gunicorn_django_test.service
, the service fails to start. When I snip out the exec line, and run it manually, I getError: /run/gunicorn doesn't exist. Can't create pidfile.
If I create the/run/gunicorn
folder manually, I can get things to work.Option 2 - tmpfiles.d
The second option is to use
tmpfiles.d
to have a folder created on boot, ready for the pid / socket files. I've tried this file:#/etc/tmpfiles.d/gunicorn.conf d /run/gunicorn 0755 gunicorn www-data -
This creates a directory, but it is quickly deleted somehow, and by the time I start the service, the folder isn't available.
I can manually add some PreExec
mkdir
commands into the service file, but I'd like to get to the bottom of why RuntimeDirectory / tmpfiles.d aren't working. Thanks.Versions / Info: Ubuntu 16.04 Server / systemd 229 / Gunicorn 19.7.1 / runtime dir = /run
-
geonaut about 7 yearsIt's something to do with group permissions in the /run/ folder. I can create a 0755 folder with the group as
www-data
, but I need the folder to be group writeable, so both the Nginx user and the Gunicorn user can access the socket file. In order to do that, I need sudo-level permissions. For some reason,sudo systemctl... etc
isn't passing the sudo permissions to the service. -
quixotic about 7 yearsi'll bet it's trying to create the directory with the uid from
User=
and failing. try addingPermissionsStartOnly=true
. see unix.stackexchange.com/a/207493/222377 -
quixotic about 7 yearshmm. actually i'll bet it's failing because the runtime directory is made but isn't
/run/gunicorn
. it's probably$XDG_RUNTIME_DIR/gunicorn
which might resolve to/run/user/$UID/gunicorn
for thegunicorn
user UID. (same question, next answer.) -
Mark Stosberg about 7 yearsAre you trying to use the same directory for multiple Gunicorn instances? You could be running into this related issue>
-
Alexis Wilke over 5 yearsYour Option 2 would have worked. However, the
tmpfiles.d
andRuntimeDirectory=...
definitions are not compatible. You should not have both turned on at the same time.
-