Docker + Laravel + MariaDB + Redis での環境構築
Scalaの開発環境の次に、手堅くPHPの開発環境も作ることになりました。
その手順とハマったポイントなどを備忘録として書いていきたいと思います。
前提条件
・Macでの手順
・MacのVirtualBoxにUbuntuがインストール済み
・Dockerもインストール済み
・docker-composeもインストール済み
参考)VirtualBox、Ubuntuのインストールや、Dockerのインストール手順はこちらを参照
kabatin.hateblo.jp
参考)docker-composeのインストール手順はこちらを参照
kabatin.hateblo.jp
各ソフトウェアのバージョン情報など
・MacOSX 10.11.1
・VirtualBox 5.0.14
・Ubuntu 14.04 LTS
・Docker 1.10.2
・PHP 5.5.9
・Laravel 5.2
・MariaDB 10.1.12
・Redis 3.0.5
フォルダ構成
まず完成形のフォルダ構成はこちら
. ├── data │ └── php ├── docker-compose.yml ├── server │ └── docker │ ├── mariadb │ │ ├── Dockerfile │ │ └── docker-entrypoint-initdb.d │ │ └── configure.sh │ ├── nginx │ │ ├── Dockerfile │ │ └── conf │ │ └── default.conf │ ├── php │ │ └── Dockerfile │ └── redis │ └── redis.conf └── storage-compose.yml
MariaDB と Redis
まずは比較的簡単なデータベースとRedisの設定から行います。
設定するファイルはメインの docker-compose.yml とは分けて、storage-compose.yml とします。
中身はこんな感じになっています。
version: '2' services: db: build: server/docker/mariadb volumes: - ./data/mariadb:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: root MYSQL_PASSWORD: password MYSQL_USER: user1 MYSQL_DB: password entrypoint: /docker-entrypoint-initdb.d/configure.sh redis: image: redis:3.0.5 volumes: - "./server/docker/redis/redis.conf:/usr/local/etc/redis/redis.conf" entrypoint: - "redis-server" - "/usr/local/etc/redis/redis.conf"
MariaDB, Redis 共通
build
Dockerfile が置いてあるパスを指定します。
最初にお見せしたツリーを見ると MariaDB 用の Dockerfile の場所が指定されていることがわかります。
environment
コンテナ内の環境変数を設定しています。
entrypoint
コンテナ起動時に実行するコマンドを指定します。
今回は /docker-entrypoint-initdb.d/configure.sh を指定していますが、これは Dockerfile 内で、
事前に用意したファイルをコンテナ内部へコピーしたものを指定しています。
Redis
build
Dockerfile が置いてあるパスを指定します。
最初にお見せしたツリーを見ると Redis 用の Dockerfile の場所が指定されていることがわかります。
volumes
事前に設定してある redis.conf ファイルをコンテナ内の対象ファイルにマウントしています。
entrypoint
コンテナ起動時に実行するコマンドを指定します。
redis-server に対して、volumes でマウントしたコンフィグファイルを指定して実行しています。
MariaDB の Dockerfile
FROM mariadb:10.1.12 COPY ./docker-entrypoint-initdb.d/* /docker-entrypoint-initdb.d/ VOLUME /etc/localtime:/etc/localtime:ro RUN sed -i -e "s/\(\[mysqld\]\)/\1\ncharacter-set-server = utf8/g" /etc/mysql/my.cnf RUN sed -i -e "s/\(\[client\]\)/\1\ndefault-character-set = utf8/g" /etc/mysql/my.cnf RUN sed -i -e "s/\(\[mysqldump\]\)/\1\ndefault-character-set = utf8/g" /etc/mysql/my.cnf RUN sed -i -e "s/\(\[mysql\]\)/\1\ndefault-character-set = utf8/g" /etc/mysql/my.cnf RUN sed -i -e "s/^#bind-addresss*=s*0.0.0.0/bind-address=0.0.0.0/" /etc/mysql/my.cnf
FROM
mariadb イメージを利用しています。バージョン指定で 10.1.12 を利用。
COPY
事前に用意した configure.sh が入っているフォルダをコンテナ内へコピーしています。
VOLUME
時計をローカルに合わせています。
最後の「ro」は ReadOnly の略で読み取り専用にしてあります。
RUN
my.cnf に対して文字列痴漢を利用して設定変更を行っています。
上の4つは文字コードの設定、下は外部からの接続を許可するバインドアドレスの設定をしています。
Laravel と Nginx
次にLaravelとNginxの設定を行います。
設定するファイルはメインの docker-compose.yml です。
中身はこんな感じになっています。
version: '2' services: php: build: context: server/docker/php volumes: - "${PWD}/data/php/develop:/var/www/html" environment: DB_HOST: db DB_PORT: 5432 REDIS_HOST: redis REDIS_PORT: 6379 nginx: build: context: server/docker/nginx ports: - "8080:80" links: - php db: extends: file: storage-compose.yml service: db expose: - "3306" redis: extends: file: storage-compose.yml service: redis expose: - "6379"
※新しく出てきたものだけ説明します。
Nginx
ports
外部からコンテナへのポートフォワードを設定します。
8080:80 と記述すると、コンテナのIPの 8080 ポートに対してアクセスが来たら
80 ポートにポートフォワードされるようになります。
links
他のコンテナとリンクします。
docker run コマンドで -lilnk を指定するのと同じです。
DB, Redis
extends
別の yml ファイルに設定されている内容を継承します。
file に指定するのが yml フィアルの名称で、service に指定するのがコンテナ名(サービス名)です。
expose
コンテナの指定ポートを外部へ公開する設定です。
80 を指定すると、外部からコンテナの 80 ポートへアクセスが可能になります。
Laravel の Dockerfile
FROM php:fpm WORKDIR /var/www/html
WORKDIR
コンテナにログインした時に最初に表示されるフォルダを指定します。
Nginx の Dockerfile
FROM nginx:1.9.12 ADD conf/default.conf /etc/nginx/conf.d
FROM
nginx イメージの 1.9.12 バージョンを利用しています。
ADD
事前に用意した nginx のコンフィグファイルを対象フォルダへコピーしています。
Nginx のコンフィグファイル
NginxとPHPのコンテナが別々なので、NginxへのアクセスをPHPコンテナへ流す必要がある。
そのためのNginxのコンフィグファイルはこんな感じで設定するとうまくいった。
server { listen 80 default; server_name localhost; charset utf-8; root /var/www/html; #access_log /var/www/html/access.log; #error_log /var/www/html/error.log; access_log /dev/stdout; error_log /dev/stdout; #rewrite ^(.+)/$ $1; location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { root /var/www/html/public; fastcgi_pass php:9000; fastcgi_index index.php; #fastcgi_split_path_info ^(.+\.php)(.+)$; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }
フォルダ構成
もう一度フォルダ構成を載せておきます。
. ├── data │ └── php ├── docker-compose.yml ├── server │ └── docker │ ├── mariadb │ │ ├── Dockerfile │ │ └── docker-entrypoint-initdb.d │ │ └── configure.sh │ ├── nginx │ │ ├── Dockerfile │ │ └── conf │ │ └── default.conf │ ├── php │ │ └── Dockerfile │ └── redis │ └── redis.conf └── storage-compose.yml
この状態で、ルートフォルダにて下記コマンドを実行すると正常にサービスが起動するはずです。
$ docker-compose build $ docker-compose up -d $ docker ps -a ONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 01121a809ee9 laravel_db "/docker-entrypoint-i" 2 seconds ago Up 1 seconds 3306/tcp laravel_db_1 80802a0855e4 laravel_nginx "nginx -g 'daemon off" 2 seconds ago Up 2 seconds 443/tcp, 0.0.0.0:8080->80/tcp laravel_nginx_1 31004578e508 laravel_php "php-fpm" 2 seconds ago Up 2 seconds 9000/tcp laravel_php_1 5b4b17aa0840 redis:3.0.5 "redis-server /usr/lo" 3 seconds ago Up 2 seconds 6379/tcp laravel_redis_1
ハマった点
・NginxコンテナからPHPコンテナへルーティングするための、Nginxの設定が難しかった。
・Laravelのstorageフォルダ、bootstrapフォルダに対して、777権限を与えないと動かなかった。
(Laravelの公式ドキュメントに権限付与してくださいってちゃんと書いてあった・・・)
まとめ
・DockerComposeは一度設定すると次回から起動・停止が非常に楽にできて便利だが、
最初の構築するまでにひたすらつまずきポイントがあり、かなり時間を食ってしまう。
・DockerComposeで環境構築をするときは、まずひとつ1つのコンテナをしっかりと構築していくとうまくいきやすい。