Raspberry pi の SDカードの寿命を伸ばすために /var/log を Ramdisk化したら、nginxとMySQLが起動しなくなったという話。原因はプロセス起動時に ディレクトリ /var/log/nginx や /var/log/mysql が存在しないからという単純なもの。
ラズパイ4で試す場合:[Raspberry pi] Ramdiskを設定したら nginx が起動しなくなったので、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.
試した環境
Raspberry Pi 3
Ubuntu 18.04.04 LTS 32bit
対策
ググってわかったことは、 /etc/nginx/nginx.conf の access_log と error_log の パスを変更しても、/var/log/nginx/ ディレクトリが無いと起動に失敗するということ。 ビルド時に埋め込まれているパスに対して必ず存在チェックをするバグ(というか仕様)らしい。
ということで、OS起動時に実行される /etc/rc.local でフォルダを作成する対処が回避策となる。/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
試した環境では、/etc/rc.local は有効になっていなかった(/etc/rc.local に書いた内容が実行されない)ので、追加で下記の設定を行った。
$ 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
/etc/systemd/system/rc-local.service に [Install] セクションが無いと、下記のようなエラーが出るので、/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.
参考: How to Enable /etc/rc.local with Systemd
/etc/nginx/nginx.conf でディレクトリを変更しても効き目がないのと、rc-local がすぐに動かなくて少し面倒だったなぁ。
コメント