【Webエンジニアがdocker入門】ec2+docker+PHP+MySQLで開発環境を構築してみた
どうも!ヒグッティ(ヒグッティ@システムエンジニア)です!
今回は私がec2上でdockerを立ててPHPやWebサーバなどの開発環境を構築した時のことを書いていきます!!私が転職した直後に実務でやったことです。私が転職する前の話もあるのでよかったら見てください。
目次
やりたいこと
5~6人で共同開発できる環境を構築したい。LAMP環境での開発がしたい。できるだけランニングコストは抑えたい。何となくdocker使ってみようかな!!今回はdocker上にWebサーバを構築することがメインの記事です。vagrantやcloud9も考えましたが、ec2上にdockerを立てることにしました。
最初に
今回のゴールとしては以下のような環境を構築しました。私はAWSにLinux環境を構築したことはありましたが、dockerは使ったことがありませんでした。自分の経験にもなると思いdockerに挑戦しようと思いました。
- ec2のホストOS上:MySQL、phpMyAdmin、docker
- docker:Apache、PHP
またこの環境を利用するのは5~6人を想定しています。構成としてはこんな感じです。

経緯
私は中堅Sierから小さいWeb制作会社に転職した直後でした。その時、Web制作会社の開発環境で様々な問題を抱えていたので、開発環境を構築し直すことにしました。Web制作では主にLAMPを使ってお客さんにWebサイトを開発、保守していました。
抱えている問題とその解決
既存の開発環境の問題が以下になります。
- 1つのサーバに様々なサイト環境が構築されている。 → dockerを導入しコンテナで管理
- ソース管理の仕組みがない(SVNやgitを使っていない)。どのソースが最新かわからない(本番ソースが正) → AWS CodeCommitを導入
- 1つの案件に対して複数人で開発ができない(サーバが1つしかないため) → dockerを導入しコンテナで管理
- 開発したソースコードがLinux上でしか動かない(環境依存な書き方になっている) → これは諦めた!無理!www
- どのソースを変更したかは、自分でメモし管理しなければならない → git、AWS CodeCommitを導入
- ソースのバックアップなどは全て自分で取得し管理しなければならない → git、AWS CodeCommitを導入
最初、上記の環境を目の当たりにしたときは何十年前の開発してるんだと過去にタイムスリップした気分でした。
開発環境の作成
会社の中でインフラについて知識があるのは私だけでした。なので社長は私に好きにやってくれ!任せた!という感じでした。やったこととしてはこんな感じです。
- CodeCommitにソースを移す
- ec2でAmazon Linux2のサーバを用意
- ec2のサーバにdockerのインストール
- ec2のサーバにMySQLのインストール
- ec2のサーバにphpMyAdminのインストール
- dockerイメージの作成、起動(今回の記事では、この構築について書きます)
dockerのイメージ作成~起動~確認
dockerの全体的な流れはこんな感じです。

まずはDockerfileを作成しました。ファイル全体はこんな感じ。DockerfileとはDockerイメージを作成するファイルのことです。
FROM php:7.4.15-apache
RUN apt-get update && docker-php-ext-install pdo_mysql
&& pecl install xdebug && docker-php-ext-enable xdebug
&& apt-get install -y libfreetype6-dev libjpeg62-turbo-dev libpng-dev libmcrypt-dev
&& mv /etc/apache2/mods-available/rewrite.load /etc/apache2/mods-enabled/rewrite.load
&& mv /etc/apache2/mods-available/authz_groupfile.load /etc/apache2/mods-enabled/authz_groupfile.load
一行ずつ見ていきます。
FROM php:7.4.15-apache
「FROM」はベースとなるイメージを決めるコマンドです。今回はphpとapacheが必要なのでこのイメージをがぴったりでした。イメージはdocker hubにありますのでよかったら見てください。
docker hub次はRUNコマンドの中身です。
RUN apt-get update && docker-php-ext-install pdo_mysql
「RUN」はイメージをビルド(イメージを作成する)するコマンドです。これからイメージを作りますって宣言ですね。
「apt-get update」はパッケージ管理ソフトの更新です。これからdockerに作ったコンテナに色々なソフトをいれるため、パッケージ管理ソフトを最新バージョンに更新します。
「&& docker-php-ext-install pdo_mysql」はmysqlを扱うためのライブラリをインストールします。ちなみに「&&」はコマンドとコマンドをつなぐ文字です。「apt-get update」の実行後、「docker-php-ext-install pdo_mysql」のコマンドを実行します。
&& pecl install xdebug && docker-php-ext-enable xdebug
「pecl」はPHPの拡張モジュールをインストールするコマンドです。「docker-php-ext-enable」はdocker上でpeclでインストールしたモジュールを有効にするコマンドです。「xdebug」はPHPをデバッグするためのモジュールです。今回は使いませんが、今後のためにインストールしました。
&& apt-get install -y libfreetype6-dev libjpeg62-turbo-dev libpng-dev libmcrypt-dev
上記のコマンドは.htaccessを利用できるようにするためのライブラリをインストールしています。.htaccessとはWebサーバにアクセスがあったときのルールを記載するファイルだと思ってください。
&& mv /etc/apache2/mods-available/rewrite.load /etc/apache2/mods-enabled/rewrite.load
上記のコマンドは「rewrite_module」を有効にするためのコマンドです。「.htaccess」の中でrewrite_moduleを利用します。例えば、httpでリクエストが来たらhttpsにリダイレクトさせる時などに利用します。
&& mv /etc/apache2/mods-available/authz_groupfile.load /etc/apache2/mods-enabled/authz_groupfile.load
上記のコマンドは、「.htaccess」の中でBasic認証を設定できるようにするためのコマンドです。Webにアクセスする時、ユーザとパスワードを求められます。
余談ですが、ubuntuのapacheって「/etc/apache2」に色々作成されるんですね、、いつもCentOSとかRedHatなのでてっきり「/etc/httpd」にあると思ってました。これに気づかず「apacheないなぁ」とはまっていました、、、
これでイメージ作成の準備は完了!!
dockerイメージのビルド
先ほど作成したDockerfileと同じディレクトリで以下のコマンドを実行してください。
sudo docker build ./ -t 【イメージ名】
今回はec2上のec2-userで実行しているので「sudo」をつけて実行しています。以下、実行した時のターミナルに出力されたログです。
[ec2-user@testphp higu]$ sudo docker build ./ -t phptest
Sending build context to Docker daemon 294.4MB
Step 1/2 : FROM php:7.4.15-apache
---> 83db90327db8
Step 2/2 : RUN apt-get update && docker-php-ext-install pdo_mysql && pecl install xdebug && docker-php-ext-enable xdebug && apt-get install -y libfreetype6-dev libjpeg62-turbo-dev libpng-dev libmcrypt-dev && mv /etc/apache2/mods-available/rewrite.load /etc/apache2/mods-enabled/rewrite.load && mv /etc/apache2/mods-available/authz_groupfile.load /etc/apache2/mods-enabled/authz_groupfile.load
---> Running in 693caefac5de
Get:1 http://security.debian.org/debian-security buster/updates InRelease [65.4 kB]
Get:2 http://deb.debian.org/debian buster InRelease [122 kB]
Get:3 http://deb.debian.org/debian buster-updates InRelease [51.9 kB]
Get:4 http://security.debian.org/debian-security buster/updates/main amd64 Packages [317 kB]
Get:5 http://deb.debian.org/debian buster/main amd64 Packages [7911 kB]
Get:6 http://deb.debian.org/debian buster-updates/main amd64 Packages [8796 B]
長いので途中は省略、、最後に「Successfully」と出力されれば完成です。
Setting up libmcrypt-dev (2.5.8-3.4) ...
Setting up libfreetype6:amd64 (2.9.1-3+deb10u2) ...
Setting up libfreetype6-dev:amd64 (2.9.1-3+deb10u2) ...
Processing triggers for libc-bin (2.28-10) ...
Removing intermediate container 693caefac5de
---> 618a71d45f78
Successfully built 618a71d45f78
Successfully tagged phptest:latest
イメージのビルドができたら、イメージを確認してみましょう。「docker images」で確認します。
sudo docker images
実際に確認した結果は以下になります。
[ec2-user@phptest higu5]$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
phptest latest 618a71d45f78 7 minutes ago 442MB
php-apache latest 63a397f20afb 4 weeks ago 432MB
php 7.4.15-apache 83db90327db8 14 months ago 414MB
[ec2-user@phptest higu5]$
「phptest」というイメージができていました!これでイメージのビルドまで完成です。
dockerコンテナの起動
作成したイメージをコンテナ上で起動します。起動するときのコマンドは以下です。
sudo docker run -d --name 【コンテナ名】
--add-host=local_devhost:【ホストのIP※AWSではprivate ipを記載】
-v /home/ec2-user/higu5/src/www/test.site:/var/www/html
-v /home/ec2-user/higu5/src/phpmodule:/var/phpmodule
-p 81:80 【作成したイメージ名※ここではphptest】
上記のコマンドを1行ずつ説明します。
sudo docker run -d --name 【コンテナ名】
「docker run -d」でコンテナをバッググラウンドで実行します。コマンドを実行した後、ターミナルのコントロールがすぐに戻ってきます。run -dは実行時の必須オプションと思ってください。
「–name」は起動するコンテナ名です。任意のコンテナ名を指定してください。
--add-host=local_devhost:【ホストのIP※AWSではprivate ipを記載】
「add-host」はコンテナからホストにアクセスするときに利用します。今回はコンテナからホスト上のMySQLに接続するときに利用します。上記いうと、MySQLのIPまたはホスト名を指定する時「local_devhost」と記載すればコンテナからホスト上のMySQLに接続できます。
-v /home/ec2-user/higu5/src/www/test.site:/var/www/html
-v /home/ec2-user/higu5/src/phpmodule:/var/phpmodule
「-v ホスト上のディレクトリ:コンテナ上のディレクトリ」はホストとコンテナ上でディレクトリを共有します。今回は共有したディレクトリにphpのソースを格納しています。コンテナを停止しても変更したソースが元に戻らないように、ホスト上のディレクトリに実際のソースを格納しておくでソースを永続化しています。
その他の使い方としてはDBのデータファイルなどをホスト側と共有し永続化するためにも使われるそうです。
「/home/ec2-user/higu5/src/www/test.site」にあるソースをコンテナ側の公開ディレクトリ「/var/www/html」に共有し、ブラウザから見れるようにしています。
-p 81:80 【作成したイメージ名※ここではphptest】
「-p ホスト上のポート:コンテナ上のポート」はホストのポートをコンテナのポートに転送する設定です。今回はホストの81ポートをコンテナの80ポート(HTTP)に転送しています。
なので「http://ホストのIPまたはホスト:81」でコンテナのWebサーバにアクセスできます。
dockerコンテナの起動確認
以下のコマンドで起動状態を確認できます。
sudo docker ps -a
実際の実行結果は以下となります。今回、コンテナ名は「phpcontener」で起動しています。
[ec2-user@testphp]$ sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e886b0beb154 phptest "docker-php-entrypoi…" 11 seconds ago Up 10 seconds 0.0.0.0:81->80/tcp, :::81->80/tcp phpcontener
これでコンテナ起動の確認ができました。
あとはec2のサーバにVSCODEのremote developから接続すれば開発環境の完成です。この他にもホスト側のMySQL、phpMyAdminのインストールやcodecommitとの連携などは必要ですが、、それはまたいつかの機会に、、詳しく知りたい人はtwitterでDMください!!
最後に
今回は開発環境の作成をやりました。docker初心者でしたが、意外とわかりやすかったです。時間はかかりましたが、、この環境を作成するまでに2週間くらいかかりました。1日3時間×10日なので30時間くらいですね。もっと効率の良い方法があるような気はしますが、、今後も改良していきます!!よい方法があったら皆さん是非教えてください!!
よく使うdockerコマンドのまとめ
今回、私がdockerを触ってよく使ったコマンドを備忘録変わりにまとめます。
イメージのビルド
docker build 【Dockerfileのあるディレクトリ】 -t 【作成するイメージ名】
#例
docker build ./ -t phptest
Dockerfileを変更したら必ずこのコマンドを実行し、イメージを再作成してください!!
イメージの確認
docker images
#出力結果
REPOSITORY TAG IMAGE ID CREATED SIZE
phptest latest 618a71d45f78 2 hours ago 442MB
イメージをコンテナとして起動
docker run -d --name 【コンテナ名】 -v 【ホストのディレクトリ】:【コンテナのディレクトリ】 -p 81:80 【イメージ名】
#例
docker run -d --name phpcontena -v /home/ec2-user/higu5/src/www/test.site:/var/www/html -p 81:80 phptest
コンテナの起動
docker start "CONTAINER ID"
#例
docker start phpcontena
コンテナの停止
docker stop "CONTAINER ID"
#例
docker stop phpcontena
コンテナの削除
docker rm "CONTAINER ID"
#例
docker rm phpcontena
コンテナにログイン
docker exec -it [コンテナ名] /bin/bash
#例
docker exec -it phpcontena /bin/bash
イメージの削除
docker rmi イメージ名
#例
docker rmi phptest
ちなみに下のは私の好きなマウスです。トラックボールなので癖ありますが、よかったら試してみてね!!