DockerでMacに超絶シンプルなPHP&Apache環境を整える


はじめに

PHP案件を頂いたため、MAMPでやるかぁーと思ったのですが、ふと、「MAMPの必要あるか…?」となりました。

というのも、今回はDB使わないし、MacにはPHPもApacheも入ってるよなと思ったのです。

Terminal
$ php -v
PHP 7.3.11 (cli) (built: Jun  5 2020 23:50:40) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.11, Copyright (c) 1998-2018 Zend Technologies

$ httpd -v
Server version: Apache/2.4.41 (Unix)
Server built:   Jun  5 2020 23:42:06

うんうん入ってる。

ただし、ソースが動く本番環境のPHPバージョンは5系だったので、PHPのバージョンを切り替える必要がありました。

開発環境を整える方法として思いついたのは3つ。

  1. HomebrewでPHPバージョンを切り替えて開発する
  2. MAMPをちょっといじってPHPバージョンを切り替えて開発する
  3. Dockerを建てちゃう

そんなにPHP案件が多いわけではないですが、ローカル環境をガチャガチャするのが嫌だし、LinuxライクにコマンドポチポチーでApache起動できる方が慣れているので、今回は3つめのDockerを採用することにしました。

前提

環境 バージョン等
MacBook Pro 2019年モデル
OS macOS Catalina
Docker Engine v19.03.13
PHP 5.4

1. Docker Desktopをインストールする

公式サイトDownload for Macを選択し、Docker Desktopをダウンロードします。

Docker.dmgを実行し、インストールします。

インストール完了したら実行します。
実行後、パスワードを求められることがありますが、適宜入力してください。

実行すると上のメニューバーの右側にクジラさんが現れます。(ちっちゃくてすみません)↓

試しにターミナルでコマンドを打ってみて確認します。

$ docker version
Client: Docker Engine - Community
 Cloud integration: 1.0.2
 Version:           19.03.13
 API version:       1.40
 Go version:        go1.13.15
 Git commit:        4484c46d9d
 Built:             Wed Sep 16 16:58:31 2020
 OS/Arch:           darwin/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          19.03.13
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.13.15
  Git commit:       4484c46d9d
  Built:            Wed Sep 16 17:07:04 2020
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          v1.3.7
  GitCommit:        8fba4e9a7d01810a393d5d25a3621dc101981175
 runc:
  Version:          1.0.0-rc10
  GitCommit:        dc9208a3303feef5b3839f4323d9beb36df0a9dd
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683

2. Dockerfileを作成してビルドする

2.1. Dockerfileの作成

Dockerfileを書いてイメージを作成します。

適当なディレクトリを作成し、Dockerfileを作成します。

$ mkdir php5_apache

$ cd php5_apache

$ vim Dockerfile

公式のDockerイメージを拝借しちゃいましょう。
php:<version>-apacheと記述することで、Apacheも含んだコンテナを建てられます。
今回使用するバージョンは5.4ですのでその通り記述します。

Dockerfile
FROM php:5.4-apache

2.2. ビルド

docker build <Dockerfileのパス> -t <イメージ名>:<タグ名>
でビルドをかけます。

ここでは、イメージ名はphp5_apache、タグはバージョンとして1.0と指定しておきます。

-t: 名前とタグを指定するオプション

$ docker build ./ -t php5_apache:1.0

ビルドできたか確認しましょう。

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
php5_apache         1.0                 7246b9f23253        5 years ago         470MB

ちなみに、Docker Desktopのダッシュボードからも確認することができます。

3. コンテナを作成し、起動する

早速起動させていきましょう。

動かしたいソースは既に手元にあるので、マウントしちゃいます。

コマンドは以下の通り。
docker run -d -p <ホスト側ポート>:<コンテナ側ポート> -v <ホスト側パス>:<コンテナ側パス> php5_apache:1.0

今回使用したオプションの説明は以下。

  • -d: デタッチドモードで起動する(バックグラウンド実行)
  • -p: コンテナのポートをホスト側に公開する
  • -v: ホスト側のディレクトリをコンテナにマウントする
$ docker run -d -p 80:80 -v <作業ディレクトリ>:/var/www/html php5_apache:1.0

無事に起動できたか確認しましょう。

$ docker ps
CONTAINER ID        IMAGE               COMMAND                CREATED              STATUS              PORTS                NAMES
469f65bd6a4f        php5_apache:1.0     "apache2-foreground"   About a minute ago   Up About a minute   0.0.0.0:80->80/tcp   recursing_hodgkin

4. ブラウザで確認

80番ポートで開いたのでポート指定なしでlocalhostをブラウザのアドレスバーに入力し開きます。
無事にPHP等が出力されていればOKです。

5. コンテナの開始と停止

コンテナを一度作成してしまえば、docker start <コンテナIDまたはコンテナ名>で起動、docker stop <コンテナIDまたはコンテナ名>で停止できます。

今回はコンテナ名でやってみます。
recursing_hodgkinと名付けられていましたので、それで停止、開始してみます。

$ docker stop recursing_hodgkin
$ docker start recursing_hodgkin

6. コンテナにログインする

以下でrootでログインできます。
ちなみにOSはDebianです。

$ docker exec -it recursing_hodgkin /bin/bash

出るときはおなじみのexit

# exit

7. おまけ

7.1. Apacheのエラー

ふとログを見てみるとなんかエラーっぽいログが吐かれていました。

$ docker logs recursing_hodgkin
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
[Thu Dec 10 09:58:54.402679 2020] [mpm_prefork:notice] [pid 1] AH00163: Apache/2.4.10 (Debian) PHP/5.4.45 configured -- resuming normal operations
[Thu Dec 10 09:58:54.402792 2020] [core:notice] [pid 1] AH00094: Command line: 'apache2 -D FOREGROUND'

「ドメイン名設定されてないよぉー困るよぉー」という内容です。
ご親切に「ServerNameディレクティブを設定しろ」と解決策まで書いてくれていますね。

多分設定しなくても問題ないんですが、エラーが残っているのが気持ち悪いので設定してあげます。

(私はCentOSばっかりいじってたので、DebianのApacheの設定ファイルとかどこ〜〜〜〜ってなりました。)

まずは、dockerにログイン。

$ docker exec -it recursing_hodgkin /bin/bash

vimが慣れているので一応インストール。
apt updateしないとvimがインストールできなかったのでやむなくしてます。
Dockerfileに最初から書いとけばよかったと思いつつ……

コンテナ内
# apt update
# apt -y upgrade
# apt install -y vim
# vim /etc/apache2/conf-enabled/httpd.conf

/etc/apache2/conf-enabled/*.confをconfigファイルとして読み込んでいるようなので、この中に記述していきます。

httpd.conf
ServerName localhost:80

Apacheサービス再起動。

# /etc/init.d/apache2 reload
[ ok ] Reloading web server: apache2.

CentOSいじってるとsystemctl restart httpdで再起動なので、service apache2 restartで再起動したくなるんですが、これを実行したらコンテナも一緒にお亡くなりになられたので、上記コマンドを叩きます。

7.2. マルチバイト文字使えないんだが

モジュール入れてないやろ。

どこからかそんな声が聞こえてきました。

モジュールを入れて、

# docker-php-ext-install mbstring

iniに追記し有効化します。

php.ini
extension=mbstring.so

恒例のapache再起。

# /etc/init.d/apache2 reload

終わりに

私もDockerに明るいわけではないので、備忘録的に残しました。

phpのエラーログとか出すようにしたり、おまけに書いた部分をDockerfileに記述したり等、実際に開発始める上で躓いたところがあったので、そこらへんもあとで記事にしておきたいと思います。