🐳

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

2021/05/03に公開

はじめに

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

事前準備

Docker ネットワーク

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

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

リポジトリをクローン

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

ビルド

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

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

ビルドにおいて configs.tar.gz というファイルを展開しているが、このファイルは /etc と /root 配下の設定ファイルを纏めたファイル。

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

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

起動

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

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

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としておく。

nginx の環境設定

/etc/nginx/conf.d に配置したサーバ証明書関連のファイルは以下のように作成してある。

console
$ openssl genrsa 2048 >server.key
Generating RSA private key, 2048 bit long modulus (2 primes)
.......+++++
.....................................................................................................................+++++
e is 65537 (0x010001)
$ openssl req -new -key server.key >server.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:JP
State or Province Name (full name) [Some-State]:Tokyo
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Foo
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:localhost
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
$ openssl x509 -days 3650 -req -signkey server.key <server.csr >server.crt
Signature ok
subject=C = JP, ST = Tokyo, O = Foo, CN = localhost
Getting Private key

PHP の環境設定

以下の記事を参照。

https://zenn.dev/ksh2ksk4/articles/3cb75ed89ae662c1352d

PHP-FPM の環境設定

PHP-FPM の実効ユーザが apache になっていたため nginx に変更してある。

/etc/php-fpm.d/www.conf

MySQL の環境設定

おわりに

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

Discussion