タイトル通りです。只今webサイトの構築をしていてどうせならDockerを使って動かそうと思い、Dockerの勉強をしている最中です。qiitaを見れば既に構築済みのスクリプトがたくさんあるのですがそれを使っては勉強にならないし、そこに至った過程などがわからないため、半分以上自分の為に&今後参考にできるようにそこに至った過程を記しながら書き貯めたいと思います。
なお、今回はdocker-compose.ymlを使って書いていきます。
最終的なディレクトリツリーは
.
├── Dockerfile
├── docker-compose.yml
├── data
│ └── database
├── web
│ └── test.php
├── nginx
│ └── nginx.conf
├── php
│ ├── Dockerfile
│ └── php-fpm.conf
└── phpmyadmin
└── config.inc.php
構築
nginxを作る
webサーバー無くてはサイトは出来ません。まず最初にnginxを立てます。
nginx:
image: nginx:latest
ports:
- 8080:80
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./web:/var/www/html
nginxのimageをDocker-hubから取ってきて、portが8080から80にフォワード、自分で書いたnginx.conf、web(ディレクトリ、この中に.html .phpが入ってる)をボリュームする。
これでnginx自体は終わり
nginxとphpをつなげる
nginxはapacheと違ってphpの使用がめんどくさいです。
初め、安直にlinks: -phpで繋げようとしたら ERROR: for nginx Cannot start service nginx: b'Cannot link to a non running container: と怒られた。
エラーを見ると動いてないコンテナには繋げられないそうなのでlinksの代わりにdepends_onを使います。
depends_on
Express dependency between services, Service dependencies cause the following behaviors:
docker-compose up starts : services in dependency order. In the following example, db and redis are started before web.docker-compose up SERVICE : automatically includes SERVICE’s dependencies. In the following example, docker-compose up web also creates and starts db and redis.
docker-compose stop : stops services in dependency order. In the following example, web is stopped before db and redis.
公式ドキュメントより
nginxはphpに依存するのでphpが起動してから起動するようにします
そして起動しようとしたらまたエラー、色々調べたらversionを3にしたり、上記のnginx.confのボリューム先は/etc/nginx/conf.d/default.conf じゃないと上手くいかないっぽい。修正して
version: '3'
services:
nginx:
image: nginx:latest
ports:
- 8080:80
volumes:
- ./web:/var/www/html
- ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf
depends_on:
- php
php:
image: php:7-fpm
volumes:
- ./web:/var/www/html
これで一先ずphpは使えるようになった。
PHPをMySQLにつなげる
nginxをphpに繋げた時と同じようにphpをmysqlに繋げる。今度はphpがmysqlに依存しているのでdocker-compose.ymlは
version: '3'
services:
nginx:
image: nginx:latest
ports:
- 8080:80
volumes:
- ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf
depends_on:
- php
php:
image: php:7-fpm
volumes:
- ./web:/var/www/html
depends_on:
- sql
sql:
image: mysql:5.7
ports:
- 13306:3306
volumes:
- ./data/database:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=password
こんな感じになった、MYSQL_ROOT_PASSWORDもここで記述する必要がある。
使えるようになるまで
MySQLデータの操作
MySQLのデータベースにテーブルを作成したりする為にコンテナにアクセスする必要がある。
まず docker ps でmysqlのコンテナIDを調べる。その後
$ docker exec -it [mysqlのコンテナID(先頭3文字でも大丈夫)] /bin/bash
でコンテナ内のbashが起動する。
あとは通常のmysqlの操作と同じ、
# mysql -u root -p
でさっき指定したmysqlのパスワードを打ち込めばログインできる、これでテーブルなどを操作できる。
又、今回phpmyadminを使用してデータの操作をすることにした。
上記のdocker-compose.ymlに以下を追加する
phpmyadmin:
image: phpmyadmin/phpmyadmin
ports:
- 8888:80
environment:
- PMA_ARBITRARY=1
- PMA_HOST=sql
- PMA_USER=root
- PMA_PASSWORD=password
depends_on:
- sql
volumes:
- /sessions
- ./phpmyadmin/config.inc.php:/var/www/html/config.inc.php
これで8888ポートにアクセスするだけでデータの操作ができるようになる。
PHPからMySQLへのアクセス
ここから実際にphpを使ってmysqlにアクセスする。
テスト用に
<?php
try {
$dsn = 'mysql:host=sql;dbname=[database];';
$db = new PDO($dsn, 'root', 'password');
$sql = 'SELECT version();';
$stmt = $db->prepare($sql);
$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
var_dump($result);
} catch (PDOException $e) {
echo $e->getMessage();
exit;
}
?>
上記のphpファイルを作ってブラウザ上で開き、しっかりバージョン情報が得られるか実験する。この時host名はlocalhostではなくsqlになる事に注意
そして実際に開いてみると「could not find driver」と出ます。mysqlと接続するにはphp側にpdo_mysqlというものを入れる必要があるらしいのでdocker-compose.ymlを少し編集します。
php:
image: php:7-fpm
build: ./php/ //追加
volumes:
- ./web:/var/www/html
depends_on:
- sql
そしてphpフォルダ内に以下のDockerfileを作成します
FROM php:7-fpm
RUN apt-get update && docker-php-ext-install pdo_mysql
docker-composeではRUNに相当するものがないのでDockerfileを使ってコンテナ作成時にpdo_mysqlをインストールするよう記述します
その後 docker-compose build でビルドし、再起動させると
バージョン情報が出ました!これでphpとmysql間が使えるようになりました!
nginxの設定
実際に使っているとcssファイルやイメージを読み込まなくなったので調べてみるとnginxの設定で解決できたので記載しておきます。nginx.confのserverディレクティブに以下を追加します。
location ~\.(css|js|png|html) {
root /var/www//html;
access_log off;
expires max;
try_files $uri $uri/ =404;
}
以上で一通り使えるようになったはずです。
サーバーで実際に動かすときはOS側で8080番ポートを解放してください、僕はこれに気づかず二、三日頭を捻らせてました。