docker-composeの起動
概要¶
このハンズオンではLaravelをECS上で動かします。
その前に今回立ち上げるLaravelをdocker-composeを使用してローカル環境を立ち上げてみましょう。
準備¶
先程作成したディレクトリへ入り、Laravelプロジェクトの初期化を行います。
$ cd ~/Desktop/laravel $ docker run -v `pwd`:/app -w /app composer create-project --prefer-dist laravel/laravel laravel $ ls laravel terraform
Dockerコンポーネントの準備¶
docker-composeを立ち上げるために、Laravelプロジェクトのdockerizeをします。
まずはlaravelディレクトリが存在するか確認しましょう
$ cd laravel $ ls app bootstrap composer.lock database phpunit.xml readme.md routes storage vendor artisan composer.json config package.json public resources server.php tests webpack.mix.js
Laravelを起動するために今回はnginxも使用します。
nginxとLaravelのDocker用ファイルを用意していきましょう
Laravel¶
まずはLaravelの設定から行いましょう。
$ vi Dockerfile
FROM php:7.2-fpm-alpine ARG UID=991 ARG UNAME=www ARG GID=991 ARG GNAME=www ENV WORKDIR=/var/www/html WORKDIR $WORKDIR COPY ./docker/php/php.ini /usr/local/etc/php COPY composer.json composer.lock ${WORKDIR}/ RUN set -x \ && apk add --no-cache git php7-zlib zlib-dev \ && docker-php-ext-install pdo_mysql zip \ && curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer \ && composer install --no-autoloader --no-progress --no-dev COPY . . RUN set -x \ && composer install --no-progress --no-dev \ && php artisan config:clear \ && addgroup ${GNAME} -g ${GID} \ && adduser -D -G ${GNAME} -u ${UID} ${UNAME} \ && chown -R ${UNAME}:${GNAME} ${WORKDIR} \ && mv /root/.composer /home/${UNAME}/ \ && chown -R ${UNAME}:${GNAME} /home/${UNAME} USER ${UNAME}
PHPを使用する場合はPHPの設定ファイル php.ini
が欲しいため、その作成を行います。
$ mkdir -p docker/php/php.ini $ vi docker/php/php.ini
[php] expose_php = Off default_charset = "UTF-8" max_execution_time = 30 memory_limit = 128M file_uploads = On upload_max_filesize = 5M post_max_size = 5M
laravel自体の設定ファイルを記載します。
ハンズオンの簡易化のためにdocker-composeで .env
ではなく .env.example
から環境変数の設定を読み込みます。プロダクションでは厳密に管理したほうが良いでしょう。
環境変数から不要な設定を外し、ローカルでLaravelからMySQLへの接続設定をします。
$ vi .env.example
APP_NAME=handson APP_ENV=local APP_KEY= APP_KEY=base64:p5Fu8gRUOuPUXzY3VcxpnYsUR9f2h8nTSm5JlYkzPTM= APP_DEBUG=true APP_URL=http://localhost LOG_CHANNEL=stderr DB_CONNECTION=mysql DB_HOST=mysql DB_DATABASE=app DB_USERNAME=root DB_PASSWORD=
ここまででLaravelの設定は終わりです。
nginx¶
従来のホスト上で環境構築をする場合nginxを立てるのは煩わしいだけでしたが、dockerのおかげで簡単に立ち上げることができるようになりました。
プロダクション環境との際を小さくするためにも、ローカルでもnginxを立ててしまいましょう。
nginxにきたトラフィックをphpへ渡す設定を書きます。
$ mkdir docker/nginx $ vi docker/nginx/default.conf.template
server { listen 80; add_header X-Frame-Options "SAMEORIGIN"; add_header X-XSS-Protection "1; mode=block"; add_header X-Content-Type-Options "nosniff"; root /var/www/html/public/; charset utf-8; location = /favicon.ico { access_log off; log_not_found off; } location = /robots.txt { access_log off; log_not_found off; } location / { try_files $uri /index.php?$query_string; } location ~ [^/]\.php(/|$) { fastcgi_pass ${PHP_HOST}:9000; fastcgi_split_path_info ^(.+?\.php)(/.*)$; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_param REQUEST_FILENAME $request_filename; include fastcgi_params; } }
nginx用Dockerfileの記載を行います。
FROM nginx:1.15-alpine COPY public /var/www/html/public COPY docker/nginx/default.conf.template /etc/nginx/conf.d/default.conf.template ENV PHP_HOST=127.0.0.1 EXPOSE 80 CMD /bin/sh -c 'sed "s/\${PHP_HOST}/${PHP_HOST}/" /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf && nginx -g "daemon off;"'
nginxは1点ポイントがあります。
ネットワークドライバによってDNS経由からローカルホスト経由か、ネットワークが異なるため、 default.conf.template
で ${PHP_HOST}
で一旦変数(?)にします。
fastcgi_pass ${PHP_HOST}:9000;
そしてDocker起動時に sed
で書き換えます。
デフォルトはDockerfile内の ENV PHP_HOST=127.0.0.1
にて 127.0.0.1
を指定してローカルホストにしています。
CMD /bin/sh -c 'sed "s/\${PHP_HOST}/${PHP_HOST}/" /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf && nginx -g "daemon off;"'
数が多い場合 envsubst
コマンドでも良いのですが、1箇所書き換えるだけならシンプルに sed
の方が分かりやすいでしょう。
ここまででdockerの設定は完了です。
docker-compose¶
先ほど作成したDockerfileと各種設定を読み込むdocker-composeの設定を記載します。
$ vi docker-compose.yaml
version: '3.7' services: nginx: build: context: . dockerfile: docker/nginx/Dockerfile volumes: - ./public:/var/www/html/public:ro ports: - 8001:80 environment: PHP_HOST: app app: build: . env_file: - .env.example volumes: - .:/var/www/html:cached mysql: image: mysql:5.7 volumes: - ./mysql:/var/lib/mysql:delegated command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci environment: MYSQL_ALLOW_EMPTY_PASSWORD: 'yes' MYSQL_DATABASE: 'app' ports: - 3306
記述しおわったら起動し、動作確認をします。
$ docker-compose up
Laravelのウェルカムページが表示されれば成功です!
MySQLを使用する¶
ここからはLaravelとMySQLを連携してみましょう。
migrateの実行¶
起動しているdocker-composeをそのままに、別のターミナルを開いて操作します。
まずはmigrateの実行を行います。
既に起動しているDockerコンテナの中で php
コマンドを打ってmigrateを行います。
$ cd /path/to/introduction-terraform-example/laravel $ docker-compose exec app php artisan migrate
APIの動作確認¶
まずは /api/books
のパスにアクセスして、何も帰ってこないことを確認します。
$ curl localhost:8001/api/books []
何回かPOSTリクエストを送って、データを増やしてみます。
$ curl -X POST localhost:8001/api/books { "title": "Ramiro Bernhard", "updated_at": "2019-03-20 04:59:05", "created_at": "2019-03-20 04:59:05", "id": 1 } $ curl -X POST localhost:8001/api/books { "title": "Ramiro Bernhard", "updated_at": "2019-03-20 04:59:05", "created_at": "2019-03-20 04:59:05", "id": 2 } :
最後に /api/books
へGETリクエストを送り、MySQLへデータが格納されていることを確認します。
$ curl localhost:8001/api/books [ { "id": 1, "title": "Ramiro Bernhard", "created_at": "2019-03-20 04:59:05", "updated_at": "2019-03-20 04:59:05" }, { "id": 2, "title": "Mr. Ford Nitzsche", "created_at": "2019-03-20 05:00:36", "updated_at": "2019-03-20 05:00:36" } ]
MySQLの中に入ってみる¶
Dockerコンテナ上で動かしているMySQLへログインしてみます。
$ docker-compose exec mysql mysql Your MySQL connection id is 8 Server version: 5.7.25 MySQL Community Server (GPL) Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql>
MySQLの公式Docker Image は環境変数で定義した app
というデータベースが作成されます。
MySQLコンテナの中に入り、 app
データベースのテーブルを一覧してみましょう。
mysql> use mysql Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> show tables; +-----------------+ | Tables_in_app | +-----------------+ | books | | migrations | | password_resets | | users | +-----------------+ 4 rows in set (0.00 sec)