LAMP環境にDocker環境を
追加してみた
八田 寛
株式会社トライスクエア
2017.05.31
0.Dockerの必要性
新しいプロジェクトなので、どうせなら最新の Laravel5.4
を採用したい!
と、思ったものの、PHP >= 5.6.4 の文字が。
すでに 5.3系、5.5系、各バージョンのVPSがいくつもあるの
で、またテスト環境用のVPS増やすのもちょっと…
Vagrantを使う手もあるが、VMよりもDockerの方が軽い
というウワサ?
すでにLAMP環境構築されているサーバーに追加して、DB
の共有もできそう。
といった経緯から、LAMP環境がすでに構築されているテス
ト用VPSに、Docker環境の追加を試みることにした。
インストールはyumで簡単にできる
# yum –y install docker
# docker –version
Docker version 1.12.6, build 3a094bd/1.12.6
Dockerのバージョン確認
Docker自動起動設定(CentOS 7系)
# systemctl enable docker
# systemctl is-enabled docker
enabled
Docker手動起動
# systemctl start docker
1.インストールと起動
イメージファイルの確認
# docker images
※インストールしたばかりは空なので何も表示されないはず。
素のCentOS環境から構築したいのでイメージをpull
# docker pull centos
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/centos latest a8493f5f50ff 7 weeks ago 192.5 MB
再度メージファイルの確認
Dockerイメージ起動
# docker run -it centos
2.Dockerイメージ起動
リポジトリの追加
# yum install epel-release
# yum install http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
素のCentOS環境で何も入ってないのでツールを入れてみる
# yum -y install cronie-noanacron net-tools iproute bind-utils
Apacheインストール
# yum -y install httpd
php5.6のインストール
# yum --enablerepo=remi-php56 install php php-mbstring php-mcrypt php-pdo php-
gd php-mysql php-opcache php-xml
3.Dockerイメージ内の環境構築
ここまで順調。なので次に、この環境のイメージファイルを
保存し、デーモン化しようとした。
# systemctl enable httpd
# systemctl is-enabled httpd
enabled
Apacheの自動起動設定
よし、コンテナ内の自動起動設定OK…なはず。
この状態でイメージファイル保存
# exit
# docker commit -a "H.Hatta" -m "Apache+PHP“ xxxxxxxxx apache24php56
※ xxxxxxxxx は、IMAGE ID
4.環境構築したDockerイメージを保存
保存したイメージをデーモン化して実行
# docker run -d -p 8888:80 --hostname demohost --name demo apache24php56
ところが…
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
あれ?コンテナ起動してない
# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
xxxxxxxxxxx apache24php56 "/bin/bash“ 4 seconds ago Exited (0) demo
コンテナ終了してる…
5-1.環境構築したDockerイメージを起動…できない?
よくよく調べてみると…
「Dockerの思想としては、1コンテナ
1プロセスで実行し、コンテナ間の連携
にはlinkを使うことを推奨している。」
ということらしい。
この言葉でハッ!と気付いた。
自分が大きな勘違いしていたことを…
5-2.環境構築したDockerイメージを起動…できない?
コンテナは、仮想マシンとの比較として、こんな感じの図を
見かけるはず。
ホストOS
コンテナ コンテナ
プロセス プロセス
コンテナ
プロセス プロセス
ホストOS
仮想マシン 仮想マシン
プロセス プロセス
仮想マシン
プロセス プロセス
ゲストOS ゲストOS
なので、てっきり1つのコンテナの中でいろんなプロセスを
動かすものだと思ってた。
5-3.環境構築したDockerイメージを起動…できない?
でもDockerで構築すると実際はこんな感じ。
ホストOS
プロセス
(Apache)
プロセス
(cron)
コンテナ コンテナ
プロセス
(MySQL)
コンテナ
Docker
link link
1プロセス1コンテナで、プロセス間の連携はLinkという
機能でコンテナ間連携をするのです。
5-4.環境構築したDockerイメージを起動…できない?
ということは、これでいけるか?
# docker run -d -p 8888:80 --hostname demohost --name demo apache24php56
/usr/sbin/httpd
上記のように、Docker内で動かすプロセス名を指定してみ
たがこれもダメ。すぐにコンテナ終了してしまう。
だが、そりゃそうだ。/usr/sbin/httpdはバックグラウンド
プロセスを起動させるためのスクリプトなので、スクリプト
自体はすぐ終了してしまう。
5-5.環境構築したDockerイメージを起動…できない?
※/usr/sbin/httpd を明示的に指定してみた
# docker run -d -p 8888:80 –hostname demohost –name demo apache24php56
/usr/sbin/httpd -DFOREGROUND
となると、
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS
PORTS NAMES
xxxxxxxx apache24php56 "/usr/sbin/httpd -DFO" 2 seconds ago Up 2 seconds
0.0.0.0:8888->80/tcp demo
※フォアグラウンドで実行するオプション
やっとDockerでhttpdが起動した!
さっそくブラウザでhttpアクセス
http://demohost:8888/
見れた!
6.改めて、環境構築したDockerイメージを起動
7.ホストOSの80番ポートへの割り当て
demohost:8888 とか、URLにいちいちポート番号を書く
のはなんかメンドいので、ホストOSの80番ポートで
Docker内のApacheに接続できるようにしてみたい。
# vi /etc/httpd/conf.d/docker.conf
というわけで、ホストOS側のApache設定ファイルに、
docker環境にProxyするバーチャルホストを追加。
<VirtualHost *:80>
ServerName demohost.hogehoge.hoge
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:8888/
ProxyPassReverse / http://127:0.0.0:8888/
</VirtualHost>
# systemctl restart httpd
これで、
※ApacheでProxyする設定
http://demohost.hogehoge.hoge/
でコンテナにアクセスできるようになる。
なんとかApache+PHPがDocker環境で動かせた。
まずはDocker環境でホスト側のIPアドレスを確認する
8-1.ホストOSのMySQLと接続してみよう
でも、もともとLAMP環境のあるサーバーにDocker環境を
追加したので、ホストOSで動いている既存のMySQLに接
続することで、DBサーバーは1つだけにしたい。
# ip route
default via 172.17.0.1 dev eth0
172.17.0.0/16 dev eth0 proto kernel scope link src 172.17.0.2
⇒ 172.17.0.1 らしい
# route
Destination Gateway Genmask Flags Metric Ref Use Iface
default gateway 0.0.0.0 UG 0 0 0 eth0
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
⇒ gateway というホスト名でもOKらしい
【ip】
コマンド
の場合
【route】
コマンド
の場合
ホストOSのIPアドレスがわかったので、MySQLクライアン
トをインストールして接続を試みる。
# mysql -h gateway -u username –p
Enter password:
ERROR 2003 (HY000): Can't connect to MySQL server on 'gateway' (113)
接続できない…
あれこれ悩みながら調べた結果、原因はホストOS側の
iptablesであることが判明。
8-2.ホストOSのMySQLと接続してみよう
ホストOS側の iptables で 3306ポートはlocalhost以外か
らの接続が許可されていないだけなので、iptables にルー
ルを追加しよう。
8-3.ホストOSのMySQLと接続してみよう
# iptables -L --line-numbers
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
2 ACCEPT all -- anywhere anywhere
3 INPUT_direct all -- anywhere anywhere
4 INPUT_ZONES_SOURCE all -- anywhere anywhere
5 INPUT_ZONES all -- anywhere anywhere
6 DROP all -- anywhere anywhere ctstate INVALID
7 REJECT all -- anywhere anywhere reject-with icmp-host-prohibited
Chain INPUTの3番目に追加する。
# iptables -I INPUT 3 -m state --state NEW -p tcp -s 172.17.0.0/16 --dport 3306 -j ACCEPT
そして、再度コンテナ側から接続確認
# mysql -h gateway -u username –p
Enter password:
mysql>
接続OK!
8-4.ホストOSのMySQLと接続してみよう
ご静聴ありがとうございました
https://www.try-square.co.jp/
株式会社トライスクエア
Webアプリケーション受託開発、Webサーバー構築、承ります。

LAMP環境にDocker環境を追加してみた