簡単!DockerでPHP環境構築

先日美容院にいったら小学校以来の短さになったノリフミです。

Dockerについてシリーズ物で記事を書こうとおもっていたのですが、まずは元になる記事をかかねば…
ということで、今回は簡単にPHP環境を構築していきます。

目次

今回の妄想


ア○パ○マ○みたいになってしまいました、、、

今回の妄想は、サーバーやローカルなどでDockerを使い、各プロセスを独立して構築し稼働させることです。
これはDockerの思想?理念?である「1コンテナ1プロセス」に乗っ取った構築図になります。「1コンテナ1プロセス」については色々と論争が絶えないようですが、見なかったことにして進めます。

「簡単」が目標のため、Dockerfileを弄って云々はしません!
コマンドのみで公式debian imageを使って進めますので悪しからず。

Dockerでブリッジネットワークを構築

Dockerで独立して構築したコンテナを相互接続できるようにブリッジネットワークを構築していきます。

既にインストール時に、3種類のネットワークが構築されていますが、分かり易いように独自ネットワークを使いたいと思います。

# dockerブリッジネットワーク構築
docker network create -d bridge --subnet 192.168.99.0/16 --gateway 192.168.99.1 example_nw

「example_nw」は構築するブリッジネットワークの名前になります。
任意で設定してください。

作成が終われば、作成したネットワークを確認しておきます。

# ネットワーク詳細確認
docker network inspect example_nw
[
  {
    "Name": "example_nw",
    "Id": "hashhogehoge",
    "Created": "2017-11-06T00:15:36.163888222Z",
    "Scope": "local",
    "Driver": "bridge",
    "EnableIPv6": false,
    "IPAM": {
      "Driver": "default",
      "Options": {},
      "Config": [
        {
          "Subnet": "192.168.99.0/16",
          "Gateway": "192.168.99.1"
        }
      ]
    },
    "Internal": false,
    "Attachable": false,
    "Ingress": false,
    "ConfigFrom": {
      "Network": ""
    },
    "ConfigOnly": false,
    "Containers": {},
    "Options": {},
    "Labels": {}
  }
]

※ ブリッジネットワーク内のコンテナは設定しているコンテナ名やIPアドレスでアクセスすることが可能です。

Dockerでmysqlを動かす

コンテナを再構築時にもデータを保持できるように、mysqlデータ用のディレクトリをホストに作成しておきます。

mkdir ~/example/mysql

Docker imageはDocker Hubより適当に拝借します。

# docker mysql構築
docker run -d --name mysql \
-v ~/example/mysql:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=root_user_pass \
-e MYSQL_DATABASE=example_db \
-e MYSQL_USER=example_user \
-e MYSQL_PASSWORD=example_user_pass \
--net=example_nw \
--ip=192.168.99.100 \
mysql:latest
Unable to find image 'mysql:latest' locally
latest: Pulling from library/mysql
85b1f47fba49: Pull complete
5671503d4f93: Pull complete
3b43b3b913cb: Pull complete
4fbb803665d0: Pull complete
05808866e6f9: Pull complete
1d8c65d48cfa: Pull complete
e189e187b2b5: Pull complete
02d3e6011ee8: Pull complete
d43b32d5ce04: Pull complete
2a809168ab45: Pull complete
Digest: sha256:hashhogehoge
Status: Downloaded newer image for mysql:latest
hashhogehoge

※ 使用するimageがホストにない場合は初期構築に時間を要します。

mysqlデータ永続化確認

# mysql接続
docker exec -it mysql mysql -u example_user -p example_db
Enter password: 
# テーブル生成 
create table example_tb (id int); 
Query OK, 0 rows affected (0.04 sec) exit; 

# docker-mysql再構築 
docker stop mysql && docker rm mysql 
docker run -d --name mysql \ 
-v ~/example/mysql:/var/lib/mysql \ 
-e MYSQL_ROOT_PASSWORD=root_user_pass \ 
-e MYSQL_DATABASE=example_db \ 
-e MYSQL_USER=example_user \ 
-e MYSQL_PASSWORD=example_user_pass \ 
--net=example_nw \ 
--ip=192.168.99.100 \ 
mysql:latest

再度mysqlに接続し、テーブル確認。

docker exec -it mysql mysql -u example_user -p example_db
Enter password: 
show tables; 
+----------------------+
| Tables_in_example_db |
+----------------------+
| example_tb           |
+----------------------+
1 row in set (0.00 sec)  exit;

Dockerでphp-fpmを動かす

nginxもありますが、先にfpmを構築していきます。

プロジェクト用のディレクトリと簡単なindexファイルを作成しておきます。

mkdir ~/example/src
vi ~/example/src/index.php
<?php
// pdoインスタンス生成
$pdo = new PDO('mysql:host=mysql;dbname=example_db;charset=utf8', 'example_user', 'example_user_pass');
// テーブルリスト取得
$result = $pdo->query('SHOW TABLES')->fetch(PDO::FETCH_ASSOC);
// テーブルリスト表示
echo "example_db table list<br>";
foreach ($result as $row) { echo "{$row}<br>"; }

Docker imageはDocker Hubより適当に拝借します。

# docker php-fpm構築
docker run -d --name php-fpm \
-v ~/example/src:/var/www/html \
--net=example_nw \
--ip=192.168.99.111 \
php:fpm
Unable to find image 'php:fpm' locally
fpm: Pulling from library/php
85b1f47fba49: Already exists
d8204bc92725: Pull complete
92fc16bb18e4: Pull complete
9859644f2c58: Pull complete
eed3518188ca: Pull complete
33c8f7623948: Pull complete
3211acc287de: Pull complete
83bc6e66e57e: Pull complete
c15398ec94ed: Pull complete
Digest: sha256:hashhogehoge
Status: Downloaded newer image for php:fpm
hashhogehoge

※ 使用するimageがホストにない場合は初期構築に時間を要します。

公式imageにデフォルトでmysqlと連携可能なimageが見つからなかったため、手動でインストールしておきます。

# pdo pdo_mysqlインストール、再起動
docker exec php-fpm docker-php-ext-install pdo pdo_mysql
docker restart php-fpm

Dockerでnginxを動かす

nginxの設定ファイルを作成しておきます。

# 設定ファイル用ディレクトリ生成
mkdir ~/example/conf
# nginx設定ファイルを生成
# ドメインは適宜設定しなおしてください
vi ~/example/conf/nginx.conf
server {
 listen 80;
 root /var/www/html;
 server_name example.com;
 index index.php;
 location / {
  try_files $uri $uri/ /index.php?$query_string;
 }
 location ~ \.php$ {
  fastcgi_pass php-fpm:9000;
  fastcgi_index index.php;
  fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
  fastcgi_read_timeout 300;
  include fastcgi_params;
 }
 sendfile off;
}

今回はホストの80ポートをポートフォワードさせて、ホストに飛んできたアクセスをdocker nginxに向くように構築します。

# docker nginx構築コマンド
docker run -d --name nginx \
-p 80:80 \
-v ~/example/src:/var/www/html \
-v ~/example/conf/nginx.conf:/etc/nginx/conf.d/example.conf \
--net=example_nw \
--ip=192.168.99.110 \
nginx:stable
Unable to find image 'nginx:stable' locally
stable: Pulling from library/nginx
bc95e04b23c0: Pull complete
f473e7d72364: Pull complete
82cca2490d0d: Pull complete
Digest: hashhogehoge
Status: Downloaded newer image for nginx:stable
hashhogehoge

接続確認

設定したドメインにアクセス可能か、mysql接続が問題ないかを確認します。


成功!

まとめ

1コンテナ1プロセス…
ローカルmysqlをrdsに変更する場合など、参照先を変更して対象コンテナを削除するだけで、なかったことになるので便利は便利です。

ただ、公開サービスで「リソース監視したい!」と思うだけで
→ munin導入する…?
 → 1コンテナ複数プロセスになる…
  → 実行管理がデフォルトで出来ない…?
   → …etcetc
壁がすごい…

マイクロサービスの運用などには非常に有用ですが、適切に管理するためにはそれなりに知識が必要です。
また機会があればdockerfileやcompose、複数プロセス対応など記事にしたいと思います。

それでは。