【Webエンジニアがdocker入門】ec2+docker+PHP+MySQLで開発環境を構築してみた

2022-04-23

どうも!ヒグッティ(ヒグッティ@システムエンジニア)です!
今回は私がec2上でdockerを立ててPHPやWebサーバなどの開発環境を構築した時のことを書いていきます!!私が転職した直後に実務でやったことです。私が転職する前の話もあるのでよかったら見てください。

真面目で優しいシステムエンジニアは損をする23~代償~

やりたいこと

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

ちなみに下のは私の好きなマウスです。トラックボールなので癖ありますが、よかったら試してみてね!!

スポンサーリンク