PHP 開発環境を Docker コンテナで構築する

10 min read読了の目安(約9100字

はじめに

Chromebook で Docker を利用できるようにしたので、 PHP 開発環境の Docker コンテナを構築します。
OS は Amazon Linux 2 を利用します。

事前準備

Docker ネットワーク

作成するコンテナを配置するネットワークについては、以下の記事を参照してください。

https://zenn.dev/ksh2ksk4/articles/95fb4a71b51b8d9c9f54

リポジトリをクローン

console
$ git clone https://github.com/ksh2ksk4/Docker.git

ビルド

Dockerfile

https://github.com/ksh2ksk4/Docker/blob/f7c62c22fda6c1766e51169579aad44d4270f315/php/Dockerfile

Dockerfile の中で configs.tar.gz というファイルを展開していますが、このファイルは /etc と /root 配下の設定ファイルを纏めたファイルです。
(いまのところ /root 配下のファイルのみです)

https://github.com/ksh2ksk4/Docker/blob/f7c62c22fda6c1766e51169579aad44d4270f315/php/configs.tar.gz

個々のファイルを COPY するのは億劫だったのでこうしています。

以下のコマンドでビルドを実行します。

console
$ sudo docker build -t php ./Docker/php

起動

console
$ sudo docker run -d --privileged --name php --network apps_segment -p 8080:80 -p 8443:443 -p 3306:3306 php

コンテナで systemctl を利用するため、 --privileged オプションを付与しています。

コンテナ起動後は sudo docker ps -a を実行してコンテナのステータスが Up になっていることを確認します。

確認

console
$ sudo docker exec -it php fish

fish を実行すると以下のエラーが発生します。

console
Failed to execute process '/usr/share/fish/tools/create_manpage_completions.py'. Reason:
The file '/usr/share/fish/tools/create_manpage_completions.py' does not exist or could not be executed.

操作は可能なんですが、コマンド補完が効かないので bash の方が良いかもしれません。

起動したコンテナのプロセス実行状態を確認します。

console
# ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.6  0.1  43120  5112 ?        Ss   22:50   0:00 /sbin/init
root        21  0.1  0.1  41052  3168 ?        Ss   22:50   0:00 /usr/lib/systemd/systemd-journald
root        26  0.0  0.1  43028  3336 ?        Ss   22:50   0:00 /usr/lib/systemd/systemd-udevd
dbus        38  0.0  0.1  58248  4104 ?        Ss   22:50   0:00 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
root        41  0.0  0.0  24116  1352 ?        Ss   22:50   0:00 /usr/lib/systemd/systemd-logind
mysql       63  1.5  6.1 1314540 176908 ?      Sl   22:50   0:00 /usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid
root       164  0.0  0.1  88596  5044 ?        Ss   22:50   0:00 /usr/libexec/postfix/master -w
postfix    165  0.0  0.2  88684  6956 ?        S    22:50   0:00 pickup -l -t unix -u
postfix    166  0.0  0.2  88760  7036 ?        S    22:50   0:00 qmgr -l -t unix -u
root       167  0.9  0.1 175464  5508 pts/0    Ss   22:50   0:00 fish
root       201  0.0  0.1  51848  3468 pts/0    R+   22:51   0:00 ps aux

なぜか nginx が起動していません。

console
# systemctl status nginx
● nginx.service - The nginx HTTP and reverse proxy server
   Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled)
  Drop-In: /usr/lib/systemd/system/nginx.service.d
           └─php-fpm.conf
   Active: inactive (dead)

状態が inactive (dead) になっています。
どうやら起動に失敗している模様。

console
# systemctl start nginx
Job for nginx.service failed because the control process exited with error code. See "systemctl status nginx.service" and "journalctl -xe" for details.

やはり起動しません。

console
# systemctl status nginx
● nginx.service - The nginx HTTP and reverse proxy server
   Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled)
  Drop-In: /usr/lib/systemd/system/nginx.service.d
           └─php-fpm.conf
   Active: failed (Result: exit-code) since Sun 2021-05-02 22:57:32 JST; 51s ago
  Process: 326 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=1/FAILURE)
  Process: 325 ExecStartPre=/usr/bin/rm -f /run/nginx.pid (code=exited, status=0/SUCCESS)

May 02 22:57:31 366ff5005534 systemd[1]: Starting The nginx HTTP and reverse proxy server...
May 02 22:57:32 366ff5005534 nginx[326]: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
May 02 22:57:32 366ff5005534 nginx[326]: nginx: [emerg] open() "/usr/share/nginx/run/nginx.pid" failed (2: No such file or directory)
May 02 22:57:32 366ff5005534 nginx[326]: nginx: configuration file /etc/nginx/nginx.conf test failed
May 02 22:57:32 366ff5005534 systemd[1]: nginx.service: control process exited, code=exited status=1
May 02 22:57:32 366ff5005534 systemd[1]: Failed to start The nginx HTTP and reverse proxy server.
May 02 22:57:32 366ff5005534 systemd[1]: Unit nginx.service entered failed state.
May 02 22:57:32 366ff5005534 systemd[1]: nginx.service failed.

「 nginx.pid ファイルが存在しない」というエラーが発生しています。

console
nginx: [emerg] open() "/usr/share/nginx/run/nginx.pid" failed (2: No such file or directory)

/usr/share/nginx/run/run/nginx ディレクトリへのシンボリックリンクです。
Docker イメージをビルドする際に以下を実行しているため、存在しないはずはないのですが・・・。

https://github.com/ksh2ksk4/Docker/blob/f7c62c22fda6c1766e51169579aad44d4270f315/php/Dockerfile#L48

しかし、 ls コマンドで確認してみたところ、確かに /run/nginx ディレクトリは無くなっています。
原因は不明ですが、コンテナ起動時に /run 配下が一旦クリアされているような気がします。

仕方ないのでディレクトリを再作成します。

console
# mkdir /run/nginx
# chown nginx:nginx /run/nginx

再度、 nginx を起動してみます。

console
# systemctl start nginx
Job for nginx.service failed because a timeout was exceeded. See "systemctl status nginx.service" and "journalctl -xe" for details.

しばらくするとエラーメッセージが表示されます。
何かでタイムアウトしているらしい。

console
# systemctl status nginx
● nginx.service - The nginx HTTP and reverse proxy server
   Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled)
  Drop-In: /usr/lib/systemd/system/nginx.service.d
           └─php-fpm.conf
   Active: failed (Result: timeout) since Mon 2021-05-03 01:58:13 JST; 1min 26s ago
  Process: 580 ExecStart=/usr/sbin/nginx (code=exited, status=0/SUCCESS)
  Process: 579 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=0/SUCCESS)
  Process: 578 ExecStartPre=/usr/bin/rm -f /run/nginx.pid (code=exited, status=0/SUCCESS)

May 03 01:56:43 366ff5005534 systemd[1]: Starting The nginx HTTP and reverse proxy server...
May 03 01:56:43 366ff5005534 nginx[579]: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
May 03 01:56:43 366ff5005534 nginx[579]: nginx: configuration file /etc/nginx/nginx.conf test is successful
May 03 01:58:13 366ff5005534 systemd[1]: nginx.service start operation timed out. Terminating.
May 03 01:58:13 366ff5005534 systemd[1]: Failed to start The nginx HTTP and reverse proxy server.
May 03 01:58:13 366ff5005534 systemd[1]: Unit nginx.service entered failed state.
May 03 01:58:13 366ff5005534 systemd[1]: nginx.service failed.

起動時にタイムアウトしている、ということしか分からない・・・。

これまた仕方ないので systemd の設定を見てみます。

console
# cat /usr/lib/systemd/system/nginx.service
[Unit]
Description=The nginx HTTP and reverse proxy server
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=/run/nginx.pid
# Nginx will fail to start if /run/nginx.pid already exists but has the wrong
# SELinux context. This might happen when running `nginx -t` from the cmdline.
# https://bugzilla.redhat.com/show_bug.cgi?id=1268621
ExecStartPre=/usr/bin/rm -f /run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
KillSignal=SIGQUIT
TimeoutStopSec=5
KillMode=mixed
PrivateTmp=true

[Install]
WantedBy=multi-user.target

nginx.pid のパスが一致していません。

  • systemd の設定
    • /run/nginx.pid
  • Dockerfile の設定
    • /run/nginx/nginx.pid

systemd の設定のパスを変更して再起動してみましたが、状況は変わらず。

で、ググったところ以下を発見。

https://stackoverflow.com/questions/45012415/systemd-start-operation-timed-out-terminating

systemd の設定の Typeforking から simple に変更して再起動してみました。

console
# systemctl daemon-reload
# systemctl start nginx

今度はエラーが発生せず、直ぐに実行が完了しました。

console
# systemctl status nginx
● nginx.service - The nginx HTTP and reverse proxy server
   Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled)
  Drop-In: /usr/lib/systemd/system/nginx.service.d
           └─php-fpm.conf
   Active: active (running) since Mon 2021-05-03 02:18:04 JST; 4s ago
  Process: 811 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=0/SUCCESS)
  Process: 810 ExecStartPre=/usr/bin/rm -f /run/nginx/nginx.pid (code=exited, status=0/SUCCESS)
 Main PID: 812 (nginx)
   CGroup: /docker/366ff5005534d41b9e2e78236ac1b95ec99e9144a0e21f9ad1abb106ca64a459/system.slice/nginx.service
           ├─812 nginx: master process /usr/sbin/nginx
           ├─814 nginx: worker process
           └─815 nginx: worker process
           ‣ 812 nginx: master process /usr/sbin/nginx

May 03 02:18:04 366ff5005534 systemd[1]: Starting The nginx HTTP and reverse proxy server...
May 03 02:18:05 366ff5005534 nginx[811]: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
May 03 02:18:04 366ff5005534 systemd[1]: Started The nginx HTTP and reverse proxy server.
May 03 02:18:05 366ff5005534 nginx[811]: nginx: configuration file /etc/nginx/nginx.conf test is successful

nginx が起動しています。

この変更内容が適切かどうかよく分からないですが、ひとまずOKとしておきます。

おわりに

幾つか上手くないところはありますが、ひとまず Chromebook に PHP の開発環境を構築することができました。