LoginSignup
4
8

More than 3 years have passed since last update.

DockerでPHP+Nginx+MySQLを構築〜使えるようになるまで

Last updated at Posted at 2019-12-31

タイトル通りです。只今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を立てます。

docker-compose.yml
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 じゃないと上手くいかないっぽい。修正して

docker-compose.yml
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は

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に以下を追加する

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にアクセスする。
テスト用に

test.php

<?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を少し編集します。

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 でビルドし、再起動させると
スクリーンショット 2019-12-25 21.00.31.png
バージョン情報が出ました!これで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番ポートを解放してください、僕はこれに気づかず二、三日頭を捻らせてました。

4
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
8