5

I have set up a Django project to run with uwsgi and nginx and it's all running as expected, except that when I reboot uwsgi will not launch correctly until the /run/ folder is recreated on the fs. /run is mapped to 'tmpfs' so it needs to be recreated at each boot.

I have a systemd service file that I created for uwsgi:

[Unit]
Description=uWSGI Module
After=syslog.target

[Service]
ExecStart=/usr/bin/uwsgi --ini /etc/uwsgi.ini
Restart=always
KillSignal=SIGQUIT
Type=notify
StandardError=syslog
NotifyAccess=main

[Install]
WantedBy=multi-user.target

And the /etc/uwsgi.ini file looks like this:

[uwsgi]
uid = uwsgi
gid = uwsgi
pidfile = /run/uwsgi/uwsgi.pid
stats = /run/uwsgi/stats.sock
socket = /run/uwsgi/uwsgi.sock
master = true
processes = 1
chdir = /path/to/our/django/app
module = icscada
max-requests = 100
daemonize = /var/log/uwsgi.log

What is the recommended way for the /run/uwsgi folder to be recreated at each boot?

  • I am not aware of uwsgi but if the program runs fine as long as /run/uwsgi folder is present, you can add mkdir /run/uwsgi to your /etc/rc.local file and every time when the system reboots, the folder would be created. – Ramesh Apr 17 '14 at 20:39
  • @Ramesh, that happens too late. The folder is created by /etc/rc.local, but systemd has already tried to init the module and failed. – Octopus Apr 17 '14 at 21:06
  • You probably need to add the run control script to /etc/init.d. You can find more information regarding the same from here. docs.oracle.com/cd/E19683-01/806-4073/6jd67r96g/index.html – Ramesh Apr 17 '14 at 22:14
  • What is your distribution? /run should be created fairly early on by the boot scripts. Do you have an older distribution that doesn't create /run at all, or is your problem arranging to start uswgi late enough? – Gilles 'SO- stop being evil' Apr 17 '14 at 23:55
  • 1
    @Gilles, /run is created. i want to also create /run/uwsgi/ at roughly the same time. or at least before systemd loads modules. this is on fedora 16 and later (i'd prefer a solution that is generally os agnostic) – Octopus Apr 18 '14 at 1:24
15

From tmpfiles.d(5):

System daemons frequently require private runtime directories below /run to place communication sockets and similar in. For these, consider declaring them in their unit files using RuntimeDirectory= (see systemd.exec(5) for details), if this is feasible.

And from systemd.exec(5):

RuntimeDirectory=, RuntimeDirectoryMode=

Takes a list of directory names. If set, one or more directories by the specified names will be created below /run (for system services) or below $XDG_RUNTIME_DIR (for user services) when the unit is started, and removed when the unit is stopped. The directories will have the access mode specified in RuntimeDirectoryMode=, and will be owned by the user and group specified in User= and Group=. Use this to manage one or more runtime directories of the unit and bind their lifetime to the daemon runtime.

In other words, while using tmpfiles.d for this "works", the officially recommended way is to add

RuntimeDirectory=uwsgi

to the [Service] section of your unit file.

This has the advantage that it is briefer, guarantees that it's created with the correct user/group ownership, and cleans up the directory when the daemon is stopped.

  • Note that these options were added in a relatively recent version of systemd and may not be in the version on your server. Check your local man page for systemd.exec. if it's not there, you can't use it. – Eddie Jun 22 '15 at 22:58
  • This is the answer! – ATOzTOA Oct 7 '16 at 0:15
  • Yep. But watch it: those systemd parameters are f'king case-sensitive. And don't forget to do daemon-reload – Otheus Nov 10 '16 at 20:42
5

You need to create a configuration file under /etc/tmpfiles.d/ defining that this directory should be created by systemd during boot/startup.

Example

$ more /etc/tmpfiles.d/uwsgi.conf 
D /run/uwsgi 0770 uwsgi uwsgi -

Set it with whatever ownership/permissions you deem are appropriate for your situation.

NOTE: If you use the setup I provided above then you'll likely want to add the group uwsgi to Nginx's user nginx:

$ sudo usermod -a nginx -G uwsgi

References

2

The way I eventually solved this problem was to use the latest distributions. Fedora 20 and yum install uwsgi built an environment where all of these details were handled automatically for me, while I was previously trying to fudge this onto a Fedora17 system where it wasn't available in the yum repositories.

The way Fedora 20 solves this is by having this in its uwsgi service unit:

ExecStartPre=/bin/mkdir -p /run/uwsgi 
ExecStartPre=/bin/chown uwsgi:uwsgi /run/uwsgi
  • 1
    The way Fedora 20 solves this is by having this in its uwsgi service unit: ExecStartPre=/bin/mkdir -p /run/uwsgi ExecStartPre=/bin/chown uwsgi:uwsgi /run/uwsgi – jsbillings May 22 '14 at 19:28
  • 1
    Yes, definitely worth mentioning that in the answer, thanks. – Octopus May 22 '14 at 19:34
  • This won't work because the Pre's don't start in a defined order. You should use instead /bin/install -d -o uswsgi -g uwsgi -m 0770 /run/uwsgi – Otheus Nov 10 '16 at 20:31
  • @Otheus, I'm not sure about the accuracy of your statement. As jsbillings states, this is exactly what you end up with when you use the yum package manager on Fedora 20. – Octopus Nov 10 '16 at 21:24
  • I retract my previous comment. The systemd man page and evidence from 2011 show statements are executed "one after the other, serially". lists.fedoraproject.org/pipermail/devel/2011-July/153897.html Though I had evidence to the contrary, I'm not sure where that evidence is. – Otheus Nov 13 '16 at 13:03
0

Multiple ExecStartPre's command are not always executed in the same order as they are listed in the .service file.

What works is to combine all commands into a single sh invocation, like this:

ExecStartPre=/bin/sh -c 'mkdir -p /run/uwsgi ; chown uwsgi:uwsgi /run/uwsgi'
  • 2
    Why do people not know about install?? /bin/install -d -o uswsgi -g uwsgi -m 0770 /run/uwsgi – Otheus Nov 10 '16 at 20:34
0

The uwsgi package I was installing—the default one on CentOS 7—already included the correct /usr/lib/tmpfiles.d/uwsgi.conf file. But the directory was still not there. A reboot probably would have caused it to be created when systemd-tmpfiles started up fresh, but in my case—

I needed to run

systemd-tmpfiles --create

after installing the package in order to create the directory right away.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.