【学習メモ】 DockerのCentOS7にapache2.4をソースインストールしたけど時間がたつと終了している

#はじめに
DockerのCentOS7にapache2.4をソースから入れてみました。
Docker runで起動しても、5分もしないうちにwebにアクセスできなくなっていて、execで入ってみると起動していたはずのapacheが落ちている。
解決策を探した一連の流れです。

apacheをコンテナ起動時に立ち上げるために、/sbin/initを引数にしているので、systemctlを使ってどうにか起動できるようにしたかったのでした。

##結論：解決方法は2つ。
1.[systemctlに追跡させないType=simpleで起動すること](http://qiita.com/Hige-Moja/items/ddbc98693c1027f25a94#type%E3%82%92simple%E3%81%A7%E3%82%84%E3%81%A3%E3%81%A6%E3%81%BF%E3%82%8B)
2.[mod_systemd.soを入れること](http://qiita.com/Hige-Moja/items/ddbc98693c1027f25a94#mod_systemd%E3%82%92%E5%85%A5%E3%82%8C%E3%82%8B)




#やったこと
<details><summary>環境</summary>
[apache]
OS:Centos:7.3.1611
インストール先:/opt/apache2.4.27/
httpd.conf :/opt/apache2.4.27/conf/httpd.conf
httpd.service :/usr/lib/systemd/system/httpd.service
</details>
##apacheのログを確認
```diff:apacheのログレベルをwarnからdebugに変えてみる
### Dockerfile : イメージビルド時にログレベルを warn -> debug へ変更。
+ RUN sed -i -e 's/LogLevel\ warn/#LogLevel\ warn\nLogLevel\ debug/g' /opt/apache2.4.27/conf/httpd.conf

### httpd.conf
# LogLevel: Control the number of messages logged to the error_log.
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
#
- LogLevel warn
+ LogLevel debug
(後略)

```
結果、error_logに、apacheが終了したログは出なかった。

##rsyslog.confで確認
Dockerfileのイメージビルド時にrsyslogをインストールしてログレベルをinfo->debugへ変更する。

```diff:修正内容
### Dockerfile
+RUN yum install -y rsyslog
+RUN sed -i -e 's/\.info/\.debug/g' /etc/rsyslog.conf

### /etc/rsyslog.conf
(前略)
-*.info;mail.none;authpriv.none;cron.none   /var/log/messages
+*.debug;mail.none;authpriv.none;cron.none  /var/log/messages
(後略)
```

結果、それっぽいのが出た。

```:rsyslog抜き出し
(前略)
Aug 15 19:18:16 localhost systemd: Starting The Apache HTTP Server...
(中略)
Aug 15 19:19:46 localhost systemd: httpd.service start operation timed out. Terminating.
Aug 15 19:21:16 localhost systemd: httpd.service stop-final-sigterm timed out. Killing.
Aug 15 19:21:16 localhost systemd: httpd.service: main process exited, code=killed, status=9/KILL
Aug 15 19:21:16 localhost systemd: Failed to start The Apache HTTP Server.
Aug 15 19:21:16 localhost systemd: Unit httpd.service entered failed state.
Aug 15 19:21:16 localhost systemd: httpd.service failed.
(後略)
```
KILLされていた。
<details><summary>The Apache HTTP Serverの文字列はどこから？</summary>
起動用に作った /usr/lib/systemd/system/httpd.service の
[Unit]
Description=The Apache HTTP Server
に記載。</details>

##apacheが終了する原因を調べる
出てきた。
[Apache2.4 on CentOS7 でsystemctl start httpdで起動しない問題の対処法](http://qiita.com/DQNEO/items/7284687e22e3f9483984)

どうやら mod_system.so が足りないようだけど、
そんなmoduleは入っていないので、

```diff:httpd.confにmoduleを追加しても
+LoadModule systemd_module modules/mod_systemd.so
```

```bash:当然起動しない。
httpd: Syntax error on line X of ./httpd.conf:
Cannot load modules/mod_systemd.so into server:
./modules/mod_systemd.so: cannot open shared object file: No such file or directory
```

mod_systemd.soを入れるのは~~面倒そうなので~~後回し。
##systemdにpidを読ませる
systemdがTerminatingしてるのは間違いないのでsystemdの仕組みを調べる。
["fedora16でhttpd.serviceがsystemctl startで立ち上がらなかったマヌケな話"](http://www.himajin2001.com/blog/node/529)を読むと、どうやら/usr/lib/systemd/system/httpd.serviceに[PIDファイルの指定ができる](http://blog.putise.com/systemd%E3%81%AEservice%E3%81%A8pid%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E9%96%A2%E4%BF%82%E3%80%82systemctl-start%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF/)模様。
```/opt/apache2.4.27/bin/httpd -V```でオプションを見ながら

```bash:httpd-Vを実行してオプションを確認
Server version: Apache/2.4.27 (Unix)
(中略)
Server compiled with....
(中略)
 -D DEFAULT_PIDLOG="logs/httpd.pid"
(後略)
```
/usr/lib/systemd/system/httpd.serviceにpidを追記してみた。

```bash:/usr/lib/systemd/system/httpd.serviceの中身抜粋
[Unit]
Description=The Apache HTTP Server
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=notify
ExecStart=/opt/apache2.4.27/bin/httpd  -DFOREGROUND
ExecReload=/opt/apache2.4.27/bin/httpd  -k graceful
ExecStop=/bin/kill -WINCH
KillSignal=SIGCONT
PrivateTmp=true
PIDFile=/opt/apache2.4.27/logs/httpd.pid
```
早速Dockerで起動して、
Apacheが動いているうちにsystemctl status httpdで状態を確認。

```bash:まずは動いている模様
[root@localhost /]# systemctl status httpd
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
   Active: activating (start) since Wed 2017-08-16 09:34:04 UTC; 25s ago
 Main PID: 52 (httpd)
   CGroup: /docker/2646b0d50d674a4cdd1a56e48c5f5e351513f4d0c3e02a2a697ccf6ebb1cda51/system.slice/httpd.service
           ├─52 /opt/apache2.4.27/bin/httpd -DFOREGROUND
           ├─63 /opt/apache2.4.27/bin/httpd -DFOREGROUND
           ├─64 /opt/apache2.4.27/bin/httpd -DFOREGROUND
           └─65 /opt/apache2.4.27/bin/httpd -DFOREGROUND
           ‣ 52 /opt/apache2.4.27/bin/httpd -DFOREGROUND

Aug 16 09:34:04 localhost systemd[1]: Starting The Apache HTTP Server...
Aug 16 09:34:04 localhost httpd[52]: AH00558: httpd: Could not reliably determine the server's fully qualifi...ssage
Hint: Some lines were ellipsized, use -l to show in full.
```
しかし時間が経つと

```bash:終了。
[root@localhost /]# systemctl status httpd
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
   Active: failed (Result: signal) since Wed 2017-08-16 09:37:04 UTC; 3min 12s ago
  Process: 52 ExecStart=/opt/apache2.4.27/bin/httpd -DFOREGROUND (code=killed, signal=KILL)
 Main PID: 52 (code=killed, signal=KILL)
   CGroup: /docker/2646b0d50d674a4cdd1a56e48c5f5e351513f4d0c3e02a2a697ccf6ebb1cda51/system.slice/httpd.service

Aug 16 09:34:04 localhost systemd[1]: Starting The Apache HTTP Server...
Aug 16 09:34:04 localhost httpd[52]: AH00558: httpd: Could not reliably determine the server's fully qualifi...ssage
Aug 16 09:35:34 localhost systemd[1]: httpd.service start operation timed out. Terminating.
Aug 16 09:37:04 localhost systemd[1]: httpd.service stop-final-sigterm timed out. Killing.
Aug 16 09:37:04 localhost systemd[1]: httpd.service: main process exited, code=killed, status=9/KILL
Aug 16 09:37:04 localhost systemd[1]: Failed to start The Apache HTTP Server.
Aug 16 09:37:04 localhost systemd[1]: Unit httpd.service entered failed state.
Aug 16 09:37:04 localhost systemd[1]: httpd.service failed.
Hint: Some lines were ellipsized, use -l to show in full.
```
終了している模様。
##Type=forkingしてみる
[systemdの動きの流れ](http://yukiyan.hatenablog.jp/entry/2015/10/18/190639)をなんとなく理解して、["Systemd入門(4) - serviceタイプUnitの設定ファイル"](http://enakai00.hatenablog.com/entry/20130917/1379374797)を見ながらhttpd.serviceの設定ファイルを再確認する。
**PIDFileはfork型サービスのメインプロセスのPIDファイル**とあるけど、

```bash:httpd.service抜粋
[Service]
Type=notify
```
なんとnotify。PIDFileは効いてないのか。
httpd.serviceは["[CentOS7]初めてsystemdを使ってみたときのメモ"](http://qiita.com/toshihirock/items/ac2456c5ecedd46a2dca)を参考にしていた。[参考記事の参照元](https://www.freedesktop.org/software/systemd/man/systemd.service.html)を見ると、```Type=forking```でないとPIDを見に行かないらしい。
参考にした記事では、systemctl status httpdの結果がStart **ed** だから、問題なく起動している。同じCentOSでも何が違うのか…（→yum install httpdはmod_systemd.soが入る)

```bash:systemctlの結果の差
(成功)
localhost systemd[1]: Started The Apache HTTP Server...
(失敗)
localhost systemd[1]: Starting The Apache HTTP Server...
```
とりあえず、PIDFileは```Type=forking```でないと機能しない模様なので


```bash:notifyからforkingへ
[Service]
Type=forking
```
変更してやってみるけど、結局Apacheは時間とともに終了してしまう。
ログは一緒。pidが違うくらい。

さらに調べるとこんな記事が。
["Systemd メモ書き#tyepforking"](http://qiita.com/a_yasui/items/f2d8b57aa616e523ede4#typeforking)にsystemdのサービスでは```Type=notify```が推奨されるとあり、apacheでmod_systemdが利用できる~~（知ってた）~~。
現在はmod_systemdは使わない方向で解決策を探してるのだよ…

##ServerNameを指定する
ダメもとで。
ServerNameのエラーが出てるのでhttpd.confのSeverNameを設定。
Type=forikingのままやってみたけど、AH00558のエラーが消えただけで終了してしまう。（当然）

##Typeをsimpleでやってみる
いろいろ試すしかない。
httpd.serviceのTypeが問題そうなのは分かったので
まずは```Type=simple```に変えてみる。

```bash:Type=simple
[Service]
Type=simple
```
終了しないみたい。ログも変わった。

```bash:systemctl
[root@localhost /]# systemctl status httpd
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
   Active: active (running) since Wed 2017-08-16 10:45:32 UTC; 3min 46s ago
 Main PID: 53 (httpd)
   CGroup: /docker/5933466f5ea9ea58e4f51153eff4e2703741aa01177f75533c95796f11536363/system.slice/httpd.service
           ├─53 /opt/apache2.4.27/bin/httpd -DFOREGROUND
           ├─63 /opt/apache2.4.27/bin/httpd -DFOREGROUND
           ├─64 /opt/apache2.4.27/bin/httpd -DFOREGROUND
           └─66 /opt/apache2.4.27/bin/httpd -DFOREGROUND
           ‣ 53 /opt/apache2.4.27/bin/httpd -DFOREGROUND

Aug 16 10:45:32 localhost systemd[1]: Started The Apache HTTP Server.
Aug 16 10:45:32 localhost systemd[1]: Starting The Apache HTTP Server...
```
Startingのログが前後しているようだけど、
Startupが終了する前に、httpdに関するログは出ていない。


```bash:/var/log/messages
(前略)
Aug 16 10:45:32 localhost systemd: Started The Apache HTTP Server.
Aug 16 10:45:32 localhost systemd: Starting The Apache HTTP Server...
(中略)
Aug 16 10:45:32 localhost systemd: Started Cleanup of Temporary Directories.
Aug 16 10:45:32 localhost systemd: Startup finished in 17h 40.036s (kernel) + 458ms (userspace) = 17h 40.495s.
```
起動させるだけなら、Type=simpleで動作した。
落ちたときのために、[ServiceにRestartを設定すると良い模様](http://enakai00.hatenablog.com/entry/20130917/1379374797)。


##mod_systemdを入れる
Type=simpleで起動はできたので
面倒そうなmod_systemdを入れて対応することを考える。
mod_system.soを調べても、[apache2.5のリファレンス](https://httpd.apache.org/docs/trunk/mod/mod_systemd.html)しか出てこない。
まだ最新って2.4だと思ったんだけど…2.5ってどこからDLするの？
yum install httpdで動いているようなので、その中にmod_systemd.soがあるか確認する。

```bash:httpd-2.4*el7.centos*x86_64.rpm
yum install --downloadonly --downloaddir=/tmp httpd
```
- 投稿検証当時2017年08月16日は```httpd-2.4.6-45.el7.centos.4.x86_64.rpm```


rpmの中身を確認してみる。

```bash:検索してみる
rpm -pql /tmp/httpd-2.4*el7.centos*x86_64.rpm | grep mod_systemd.so
/usr/lib64/httpd/modules/mod_systemd.so
```
あったーーーーーーーー
[取り出す](http://linux.just4fun.biz/?%E9%80%86%E5%BC%95%E3%81%8DUNIX%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89/rpm%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%8B%E3%82%89%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E5%8F%96%E3%82%8A%E5%87%BA%E3%81%99)。

```bash:取り出す
cd /tmp
rpm2cpio /tmp/httpd-2.4*el7.centos*x86_64.rpm | cpio -id  ./usr/lib64/httpd/modules/mod_systemd.so
```
モジュールはコンパイル時に指定って聞いたような覚えがあるから、展開したソースファイルのmodulesフォルダに入れようとした。
modules以下にフォルダがありすぎて、どこに入れれば良いかわからない。
諦めてインストール後のmodulesフォルダに入れて、httpd.confでIncludeしてみる。

```bash:Dockerfile
RUN cp /tmp/usr/lib64/httpd/modules/mod_systemd.so /opt/apache2.4.27/modules
RUN sed -i -e 's/<IfModule\ unixd_module>/LoadModule\ systemd_module\ modules\/mod_systemd.so\n<IfModule\ unixd_module>/g' /opt/apache2.4.27/conf/httpd.conf
```
起動してみるとsystemctlを見ると…startedになっている！！

```bash:インストール後のmodulesフォルダに入れてIncludeしたとき
[root@localhost /]# systemctl status httpd 
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
   Active: active (running) since Wed 2017-08-16 17:55:17 UTC; 53s ago
 Main PID: 60 (httpd)
   Status: "Total requests: 2; Current requests/sec: 0; Current traffic:   0 B/sec"
   CGroup: /docker/dbdb7456c17c8f6972f66d619508f97673c4962c4a85186049189deb3b928c0c/system.slice/httpd.service
           ├─60 /opt/apache2.4.27/bin/httpd -DFOREGROUND
           ├─66 /opt/apache2.4.27/bin/httpd -DFOREGROUND
           ├─67 /opt/apache2.4.27/bin/httpd -DFOREGROUND
           └─68 /opt/apache2.4.27/bin/httpd -DFOREGROUND
           ‣ 60 /opt/apache2.4.27/bin/httpd -DFOREGROUND

Aug 16 17:55:17 localhost systemd[1]: Starting The Apache HTTP Server...
Aug 16 17:55:17 localhost systemd[1]: Started The Apache HTTP Server.
```
読み込まれているモジュールも確認。

```bash:httpd-Mで確認
/opt/apache2.4.27/bin/httpd -M | grep systemd
 systemd_module (shared)
```
コンパイルしなくても、フォルダに入れれば動いた。
(∩´∀｀)∩