PHP 開発環境を Docker コンテナで構築する
はじめに
Chromebook で Docker を利用できるようにしたので、 PHP 開発環境の Docker コンテナを構築します。
OS は Amazon Linux 2 を利用します。
事前準備
Docker ネットワーク
コンテナを配置するネットワークについては以下の記事を参照。
リポジトリをクローン
$ git clone https://github.com/ksh2ksk4/Docker.git
ビルド
以下のコマンドでビルドを実行。
$ sudo docker build -t php ./Docker/php
ビルドにおいて configs.tar.gz
というファイルを展開しているが、このファイルは /etc と /root 配下の設定ファイルを纏めたファイル。
個々のファイルを COPY
するのは億劫だったのでこうしている。
起動
$ 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 になっていることを確認。
確認
$ sudo docker exec -it php fish
起動したコンテナのプロセス実行状態を確認。
# 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 が起動していない。
# 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)
になっている。
どうやら起動に失敗している模様。
# 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.
やはり起動しない。
# 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 ファイルが存在しない」というエラーが発生している。
nginx: [emerg] open() "/usr/share/nginx/run/nginx.pid" failed (2: No such file or directory)
/usr/share/nginx/run
は /run/nginx
ディレクトリへのシンボリックリンク。
Docker イメージをビルドする際に以下を実行しているため、存在しないはずはないのだが・・・。
ls
コマンドで確認してみたところ、確かに /run/nginx
ディレクトリは存在しない。
原因は不明だが、コンテナ起動時に /run
配下が一旦クリアされているような気がする。
仕方ないのでディレクトリを再作成。
# mkdir /run/nginx
# chown nginx:nginx /run/nginx
再度 nginx を起動してみる。
# systemctl start nginx
Job for nginx.service failed because a timeout was exceeded. See "systemctl status nginx.service" and "journalctl -xe" for details.
しばらくするとエラーメッセージが表示される。
何かでタイムアウトしているらしい。
# 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 の設定を見てみる。
# 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 の設定のパスを変更して再起動してみたが、状況は変わらず。
で、ググったところ以下を発見。
systemd の設定の Type
を forking
から simple
に変更して再起動。
# systemctl daemon-reload
# systemctl start nginx
今度はエラーが発生せず、直ぐに実行が完了。
# 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
に配置したサーバ証明書関連のファイルは以下のように作成してある。
$ 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 の環境設定
以下の記事を参照。
PHP-FPM の環境設定
PHP-FPM の実効ユーザが apache
になっていたため nginx
に変更してある。
/etc/php-fpm.d/www.conf
MySQL の環境設定
おわりに
幾つか上手くないところはありますが、ひとまず Chromebook に PHP の開発環境を構築することができました。
Discussion