むにえる牧場

毎日むにえるをつくっています

DockerでLaravelの開発環境を1から作ってみる

はじめに

Dockerなんもわからんになっていたので勉強を兼ねて、Laravelの開発環境を1からDockerでつくってみました。
最終的にこんなディレクトリ構成になります。

$ tree -L 3
.
├── LICENSE
├── README.md
├── docker
│   ├── mysql
│   │   └── Dockerfile
│   ├── nginx
│   │   └── default.conf
│   └── php
│       └── Dockerfile
├── docker-compose.yml
└── src
    ├── index.html
    ├── info.php
    └── sample
        ├─...

環境変数 .env

Dockerfileを記述する上で環境変数を多用するため、 .envファイルを準備します。
必要に応じて環境変数は変更しますが、とりあえず今回の記事の中では以下の .envファイルを準備しておけばok ルートディレクトリとなる箇所に配置してください。

./.env

NGINX_PORT=8080
PROJECT_PATH=./src
LARAVEL_SERVER_PORT=3501
MYSQL_PORT=3502
MYSQL_DATABASE=homestead
MYSQL_PASSWORD=secret
MYSQL_ROOT_PASSWORD=secret

Nginx

まずはNginxのコンテナを準備します。 ベースとなるイメージにはNginxの公式イメージを利用。

./docker-compose.yml

version: '3'
   services:
     web:
       image: nginx
       container_name: 'nginx'
       ports:
         - ${NGINX_PORT}:80
  • docker-compose build してビルド
  • docker-compose up -dしてNginxコンテナを立ち上げ

  • docker-compose psをすることでコンテナが立ち上がっていることが確認できる

$ docker-compose ps
   Name          Command          State          Ports
   -----------------------------------------------------------
   nginx   nginx -g daemon off;   Up      0.0.0.0:8080->80/tcp
  • localhost:8080 にアクセスしたらNginxの初期設定画面が見られる
    f:id:jalemy:20190721201807p:plain
    Nginx 初期画面

PHP

続いてPHPのコンテナを準備します。
ベースには公式イメージのversion 7.3.7を利用しました。

まずは、PHP用のDockerfileを作ります。

./docker/php/Dockerfile

FROM php:7.3.7-fpm
  • docker-compose.ymlphpコンテナの内容を追記します

docker-compose.yml

 ...
    app:
       build: ./docker/php
       container_name: 'laravel-php'
       ports:
         - ${LARAVEL_SERVER_PORT}:8000
  • docker-compose build docker-compose up -dとして、PHPを立ち上げます
$ docker-compose exec app php -v
PHP 7.3.7 (cli) (built: Jul 12 2019 02:57:19) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.7, Copyright (c) 1998-2018 Zend Technologies
  • PHPが動作していることを確認できました

Nginxのコンテナにファイル共有

./src/ ディレクトリにindex.htmlを配置して、Nginxにアクセスすることでindex.htmlを表示できるようにします。

./src/index.html

<p>hogehoge<p>
<p>nginx<p>
  • docker-compose.ymlNginx部分を書き換えます

docker-compose.yml

   nginx:
       image: nginx
       container_name: "laravel-nginx"
       ports:
         - "8080:80"
       volumes:
         - ./src:/src
         - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
  • Nginxの設定ファイルを準備します

./docker/nginx/default.conf

server {
       index index.php index.html;
       root /src;
}
  • docker-compose down docker-compose up -dとして再起動
  • localhost:8080にアクセスして、index.htmlが表示されます

PHPのコンテナにファイル共有

同じくPHPのコンテナでも設定を行います。

./src/info.php

<?php
    phpinfo();
  • docker-compose.ymlに追記します

docker-compose.yml

app:
       build: ./docker/php
       container_name: 'laravel-php'
       ports:
         - ${LARAVEL_SERVER_PORT}:8000
       volumes:
         - ${PROJECT_PATH}:/src
  • Nginxの設定にphp-fpmの設定を追加します

./docker/nginx/default.conf

  server {
       index index.php index.html;
       root /src;
   
       location \ {
           try_files $uri $uri/ /index.php?$query_string;
       }
   
       location ~ \.php$ {
           fastcgi_split_path_info ^(.+\.php)(/.+)$;
           fastcgi_pass app:9000;
           fastcgi_index index.php;
           include fastcgi_params;
           fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
           fastcgi_param PATH_INFO $fastcgi_path_info;
       }
   }
  • docker-compose down docker-compose up -d
  • http://localhost:8080/info.phpにアクセスすると、phpinfoの内容が出力されます

f:id:jalemy:20190721203601p:plain
phpinfo出力

mysql

DBということでとりあえずmysqlコンテナを作成します。

  • mysqlDockerfileを作成

./docker/mysql/Dockerfile

FROM mysql:8.0.16
  • docker-compose.ymlに追記します

docker-compose.yml

  db:
       build: ./docker/mysql
       container_name: 'db-mysql'
       ports:
         - ${MYSQL_PORT}:3306
       environment:
         - MYSQL_DATABASE=${MYSQL_DATABASE}
         - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
         - TZ=Asia/Tokyo
  • docker-compose build docker-compose up -dをして、コンテナを立ち上げ
  • mysql -h 0.0.0.0 --port {port番号} -u root -pとコマンドを入力して、mysqlの存在を確認できます
$ mysql -h 0.0.0.0 --port 3502 -u root -p
   Enter password:
   Welcome to the MySQL monitor.  Commands end with ; or \g.
   Your MySQL connection id is 9
   Server version: 8.0.16 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>

composer

続いてcomposerのインストールをします。

  • PHPDockerfilecomposerについての記述を追記します。

./docker/php/Dockerfile

FROM php:7.3.7-fpm

# zip extension
RUN apt-get update \
    && apt-get install -y libzip-dev zlib1g-dev \
    && docker-php-ext-install zip

# install composer
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \
    && php -r "if (hash_file('sha384', 'composer-setup.php') === '48e3236262b34d30969dca3c37281b3b4bbe3221bda826ac6a9a62d6444cdb0dcd0615698a5cbe587c3f0fe57a54d8f5') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" \
    && php composer-setup.php \
    && php -r "unlink('composer-setup.php');" \
    && mv composer.phar /usr/local/bin/composer

ENV COMPOSER_ALLOW_SUPERUSER 1
ENV COMPOSER_HOME /composer
ENV PATH $PATH:/composer/vendor/bin
  • zip extensionとなるlibzip-dev zlib1g-devを入れていないとエラーで怒られるので注意です

Laravel

ようやくLaravelのインストール……

  • ./docker/php/DockerfileにLaravelについての記述を追記します。

./docker/php/Dockerfile

   FROM php:7.3.7-fpm
   
   # zip extension
   RUN apt-get update \
       && apt-get install -y libzip-dev zlib1g-dev \
       && docker-php-ext-install zip
   
   # install composer
   RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \
       && php -r "if (hash_file('sha384', 'composer-setup.php') === '48e3236262b34d30969dca3c37281b3b4bbe3221bda826ac6a9a62d6444cdb0dcd0615698a5cbe587c3f0fe57a54d8f5') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" \
       && php composer-setup.php \
       && php -r "unlink('composer-setup.php');" \
       && mv composer.phar /usr/local/bin/composer
   
   ENV COMPOSER_ALLOW_SUPERUSER 1
   ENV COMPOSER_HOME /composer
   ENV PATH $PATH:/composer/vendor/bin
   
   RUN composer global require "laravel/installer"
   
   WORKDIR /src
  • docker-compose buildでビルドし直し
  • docker-compose up -dで立ち上げ
  • docker-compose exec app laravel new sampleで新しくLaravelのプロジェクトをつくります
  • ./src/sample/ディレクトリにLaravelのプロジェクトが作られていることが確認できます。

  • Nginxのルートを変更して、Laravelのページが表示されるように設定します。

./docker/nginx/default.conf/

server {
    index index.php index.html;
    root /src/sample/public;
...
  • docker-compose exec web restartNginxを再起動
  • localhost:8080にアクセスすると……

f:id:jalemy:20190721204912p:plain
Laravel立ち上がってる図

(余分なもの写ってますが気にしないでください。)
これでDockerを利用してLaravelを動作させることができました🙌
本当はこの後にDBの設定したり、PHPの拡張したり、Node.js入れたりしないといけないのですが、力尽きたのでここまで……

おわりに

1から写経しながら環境構築するのめちゃくちゃ勉強になりました……
しかし環境構築周りは詰まることが多くてとても疲労困憊になります。(本来は詰まったことを記事にするべき……?)

追記

docker-compose exec app bashbashが立ち上がらなくてなんでだろう?となっていたところ、該当サービスのDockerfileを見てみたら、
FROM php:7.3.7-fpm-alpine

alpineと接尾につくイメージは、イメージ容量を小さくするために最低限のものしか入っていないようです。
その影響でbashすら起動できないということでした。
今回は別に容量気にしてなかったので、 FROM php:7.3.7-fpm とすることで解決。

参考

Laravelの開発環境をDockerを使って構築する - Qiita

Alpine Linux で Docker イメージを劇的に小さくする - Qiita