6

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?

Valentin Bajrami
  • 9,244
  • 3
  • 25
  • 38
Octopus
  • 2,489
  • 6
  • 21
  • 25
  • 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. http://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 01:24
  • You could create a run-uwsgi.mount unit probably. rc.local is deprecated an old sysvinit scripts are a hack. – jsbillings May 22 '14 at 18:20

5 Answers5

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.

kevmitch
  • 250
  • 2
  • 5
  • 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 07 '16 at 00: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

slm
  • 363,520
  • 117
  • 767
  • 871
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
Octopus
  • 2,489
  • 6
  • 21
  • 25
  • 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". https://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
1

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'
  • 3
    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.

andrew
  • 151
  • 2