発生する状況
Vagrantで共有フォルダを設定している状態、例えばCentOS側の/var/www/htmlにホストOSのC:\src\htmlなどを設定していて、かつDocumentRootはその共有フォルダより下のフォルダ(C:\src\html\web1等)を指定しているような場合、vagrant upしてhttpdが起動するときにまだ共有フォルダのマウントが終わっていないため、httpdの起動がフォルダがないというエラーで起動しない。
Laravelで共有フォルダを[ルートフォルダ]としていて、DocumentRootで指定しているフォルダを[ルートフォルダ]/publicとするような場合に起こる。
環境
仮想化ソフト: VirtualBox 6.0.4
ホストOS: Windows7 64bit
ゲストOS: bento/centos-7.6
Webサーバ: Apache 2.4
対処方法
(1)systemdの起動順序を設定する。
こちらは以下の記事でまとめられていた。
Systemdでマウントするタイミングで開始するサービスを作る
(2)スクリプトを書く
今回はこちらでやってみる。
httpdが起動しているときは以下のような感じでプロセスが起動している
[root@localhost ~]# ps ax |grep httpd
6603 ? Ss 0:00 /usr/sbin/httpd -DFOREGROUND
6604 ? S 0:00 /usr/sbin/httpd -DFOREGROUND
6605 ? S 0:00 /usr/sbin/httpd -DFOREGROUND
6606 ? S 0:00 /usr/sbin/httpd -DFOREGROUND
6607 ? S 0:00 /usr/sbin/httpd -DFOREGROUND
6608 ? S 0:00 /usr/sbin/httpd -DFOREGROUND
6650 pts/0 R+ 0:00 grep --color=auto httpd
[root@localhost ~]#
なので、そのあたりを検索して上がっていなかったらsystemctl start httpdし、
起動してなかったらちょっと待ってまた起動コマンドを投げる、みたいなのを
書いてみる。
#!/bin/sh
retry=0
while [ $retry -ne 10 ]
do
ps ax | grep "\/usr\/sbin\/httpd -DFOREGROUND" >& /dev/null
if [ $? -eq 0 ];then
logger -i -t httpdcheck.sh "httpd started. checking is finished. exit."
exit 0
else
logger -i -t httpdcheck.sh "httpd doesn't start. try starting httpd and recheck process(${retry})."
systemctl start httpd
sleep 5
fi
retry=`expr $retry + 1`
done
logger -i -t httpdcheck.sh "httpdcheck is failed..."
exit 1
シェル芸人ではないので美しくない&&英語が無茶苦茶なのはご容赦を...orz
上のスクリプトの呼出しを/etc/rc.localに書くが、その前に /etc/rc.d/rc.local のパーミッションに実行属性を付けてあげる。
[root@localhost ~]# chmod u+x /etc/rc.d/rc.local
[root@localhost ~]#
これをしないとrc.localを起動時に実行してくれないのでちょっとだけハマった・・・。
以下の記事を参考。
その上で、/etc/rc.localに以下のように呼出しを追加。
#!/bin/bash
# THIS FILE IS ADDED FOR COMPATIBILITY PURPOSES
#
# It is highly advisable to create own systemd services or udev rules
# to run scripts during boot instead of using this file.
#
# In contrast to previous versions due to parallel execution during boot
# this script will NOT be run after all other services.
#
# Please note that you must run 'chmod +x /etc/rc.d/rc.local' to ensure
# that this script will be executed during boot.
touch /var/lock/subsys/local
# httpd start check. if httpd doesn't start, try starting httpd. ←コメントはご自由に
/bin/sh /root/httpdcheck.sh ←追加
今回は/root/httpdcheck.shに置いたので上のように書いているが、パスは各自適宜自分の環境で合わせて書き換える。
そして一度vagrant haltしてvagrant upしてみるとかすると、スクリプトが動いて5秒間隔でhttpdプロセスが起動していないとsystemctl start httpdを5秒間隔で実行してみたりするようになる。。。はず。
トライ結果は/var/log/messagesに出る。
Apr 15 10:35:56 localhost httpdcheck.sh[6140]: httpd doesn't start. try starting httpd and recheck process(1).
・・・ 中略 ・・・
Apr 15 10:35:56 localhost httpdcheck.sh[6140]: httpd doesn't start. try starting httpd and recheck process(2).
Apr 15 10:35:56 localhost systemd: Starting The Apache HTTP Server...
Apr 15 10:35:56 localhost httpd: AH00526: Syntax error on line 119 of /etc/httpd/conf/httpd.conf:
↓ まだマウントされてないのでエラーになってる
Apr 15 10:35:56 localhost httpd: DocumentRoot '/var/www/html/*****' is not a directory, or is not readable
Apr 15 10:35:56 localhost systemd: httpd.service: main process exited, code=exited, status=1/FAILURE
Apr 15 10:35:56 localhost kill: kill: cannot find process ""
Apr 15 10:35:56 localhost systemd: httpd.service: control process exited, code=exited status=1
Apr 15 10:35:56 localhost systemd: Failed to start The Apache HTTP Server.
Apr 15 10:35:56 localhost systemd: Unit httpd.service entered failed state.
Apr 15 10:35:56 localhost systemd: httpd.service failed.
Apr 15 10:35:56 localhost rc.local: Job for httpd.service failed because the control process exited with error code. See "systemctl
status httpd.service" and "journalctl -xe" for details.
Apr 15 10:36:01 localhost httpdcheck.sh[6601]: httpd doesn't start. try starting httpd and recheck process(3).
Apr 15 10:36:01 localhost systemd: Starting The Apache HTTP Server...
ost.localdomain. Set the 'ServerName' directive globally to suppress this message
Apr 15 10:36:01 localhost systemd: Started The Apache HTTP Server.
Apr 15 10:36:06 localhost httpdcheck.sh[6613]: httpd started. checking is finished. exit. ⇐ 起動したのでチェック終了
とまあこんな感じで、一応起動するようになったのでめでたしめでたし。