To extend the life of the Raspberry Pi SD card, I made /var/log a Ramdisk, and then nginx and MySQL stopped starting. The cause was simple: directories such as /var/log/nginx and /var/log/mysql did not exist when the processes started.
When trying this on a Raspberry Pi 4: [Raspberry Pi] After Setting Up a Ramdisk, nginx Stopped Starting, So I Handled It with rc-local
washi@rpi3:~$ /etc/init.d/nginx status ● nginx.service - A high performance web server and a reverse proxy server Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: en abled) Active: failed (Result: exit-code) since Tue 2020-04-07 08:58:30 JST; 1h 8min ago Docs: man:nginx(8) Process: 1492 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=1/FAILURE) Apr 07 08:58:30 rpi3.nosubject.io systemd[1]: Starting A high performance we…… Apr 07 08:58:30 rpi3.nosubject.io nginx[1492]: nginx: [alert] could not open…ry) Apr 07 08:58:30 rpi3.nosubject.io nginx[1492]: 2020/04/07 08:58:30 [emerg] 1…ry) Apr 07 08:58:30 rpi3.nosubject.io nginx[1492]: nginx: configuration file /et…led Apr 07 08:58:30 rpi3.nosubject.io systemd[1]: nginx.service: Control process…s=1 Apr 07 08:58:30 rpi3.nosubject.io systemd[1]: nginx.service: Failed with res…e'. Apr 07 08:58:30 rpi3.nosubject.io systemd[1]: Failed to start A high perform…er. Hint: Some lines were ellipsized, use -l to show in full.
Test Environment
Raspberry Pi 3
Ubuntu 18.04.04 LTS 32-bit
Workaround
What I found from searching is that even if you change the access_log and error_log paths in /etc/nginx/nginx.conf, startup still fails if the /var/log/nginx/ directory does not exist. It seems to be a bug, or maybe a specification, where nginx always checks a path embedded at build time.
So the workaround is to create the folders from /etc/rc.local, which runs when the OS starts. Write something like the following in /etc/rc.local.
washi@rpi3:~$ cat /etc/rc.local #!/bin/bash mkdir -p /var/log/nginx mkdir -p /var/log/mysql chown root.www-data /var/log/nginx chown mysql.mysql /var/log/mysql exit 0
In the environment I tested, /etc/rc.local was not enabled, meaning the contents written there did not run, so I additionally configured the following.
$ sudo cp /lib/systemd/system/rc-local.service /etc/systemd/system
washi@rpi3:~$ cat /etc/systemd/system/rc-local.service #SPDX-License-Identifier: LGPL-2.1+ # #This file is part of systemd. # #systemd is free software; you can redistribute it and/or modify it #under the terms of the GNU Lesser General Public License as published by #the Free Software Foundation; either version 2.1 of the License, or #(at your option) any later version.#This unit gets pulled automatically into multi-user.target by #systemd-rc-local-generator if /etc/rc.local is executable. [Unit] Description=/etc/rc.local Compatibility Documentation=man:systemd-rc-local-generator(8) ConditionFileIsExecutable=/etc/rc.local After=network.target
[Service] Type=forking ExecStart=/etc/rc.local start TimeoutSec=0 RemainAfterExit=yes GuessMainPID=no
[Install] WantedBy=multi-user.target
$ sudo systemctl enable rc-local
If /etc/systemd/system/rc-local.service does not have an [Install] section, the following error appears, so you need to add it to /etc/systemd/system/rc-local.service.
$ sudo systemctl enable rc-local The unit files have no installation config (WantedBy, RequiredBy, Also, Alias settings in the [Install] section, and DefaultInstance for template units). This means they are not meant to be enabled using systemctl. Possible reasons for having this kind of units are: 1) A unit may be statically enabled by being symlinked from another unit's .wants/ or .requires/ directory. 2) A unit's purpose may be to act as a helper for some other unit which has a requirement dependency on it. 3) A unit may be started when needed via activation (socket, path, timer, D-Bus, udev, scripted systemctl call, …). 4) In case of template units, the unit is meant to be enabled with some instance name specified.
Reference: How to Enable /etc/rc.local with Systemd

Changing the directory in /etc/nginx/nginx.conf had no effect, and rc-local did not work right away, so it was a bit troublesome.