Help us understand the problem. What is going on with this article?

dockerでPHP7.3+Laravel環境を15分で作る~2019年版

昨年の最後にLaravelのプロジェクトの雛形を作る必要があったので、メモとして書きました。
この記事では、dockerコマンドだけで、以下のことができるようになります。

  1. Laravelプロジェクト雛形の作成
  2. PHP v7.3 コンテナの作成 - xdebug, opcacheも含む
  3. nginx v1.15 コンテナの作成
  4. ローカルマシンで動かす

プロジェクトは、githubに公開しています。
https://github.com/tomoyamachi/docker-laravel-fpm-7.3

なお、この記事は、以下の記事の知識をベースに進んでいきます。
本番運用に備えたPHP7.3.0のコンテナを作る

プロジェクト作成

composerコンテナ経由でカレントディレクトリにLaravelのプロジェクトを作成します。

$ docker run --rm --interactive --tty -v $(pwd):/app \
  composer bash -c \
  "composer create-project --prefer-dist laravel/laravel ."

カレントでカレントディレクトリを確認

$ docker-laravel-php-fpm-7.3.0# ls
app            composer.json  database       public         routes         tests
artisan        composer.lock  package.json   readme.md      server.php     vendor
bootstrap      config         phpunit.xml    resources      storage        webpack.mix.js

OK.

PHP-FPMコンテナを作成

PHP-FPMコンテナのDockerfile/.dockerignoreファイルを作成します。

PHPのDockerfileの作成については、長くなるので別の記事にまとめました。
こちらをご参照ください。

2019/01/26 追記
@hokutoasari さんの記事を参考に echo 'opcache.optimization_level=0x7FFFBBFF' を追加しました。

# Dockerfile
FROM php:7.3.0-fpm-alpine3.8

RUN apk upgrade --update && apk --no-cache add \
    # iconv, intl
    icu-dev \
    # xdebug
    autoconf make g++ gcc

RUN docker-php-ext-install  -j$(nproc) iconv intl mbstring pdo_mysql opcache && \
  pecl install xdebug-2.7.0beta1 && \
  docker-php-ext-enable xdebug

RUN { \
  echo 'upload_max_filesize = 100M'; \
  echo 'post_max_size = 108M'; \
  echo 'short_open_tag = On'; \
  echo 'fastcgi.logging = 1'; \
  echo 'opcache.enable=1'; \
  echo 'opcache.optimization_level=0x7FFFBBFF'; \
  echo 'opcache.revalidate_freq=0'; \
  echo 'opcache.validate_timestamps=1'; \
  echo 'opcache.memory_consumption=128'; \
  echo 'opcache.interned_strings_buffer=8'; \
  echo 'opcache.max_accelerated_files=4000'; \
  echo 'opcache.revalidate_freq=60'; \
  echo 'opcache.fast_shutdown=1'; \
  echo 'xdebug.remote_enable=1'; \
} > /usr/local/etc/php/conf.d/overrides.ini

COPY . /var/www/html
RUN chown -R www-data:www-data /var/www

そして docker build 。とりあえずlaravelという名前で起動できるようにしてコンテナ起動。

$ docker build -t laravel . 
$ docker run laravel

[30-Dec-2018 17:24:55] NOTICE: fpm is running, pid 1
[30-Dec-2018 17:24:55] NOTICE: ready to handle connections

動いてそうというところまで来ました。

NGINXコンテナを作成

ちゃんと動いていることを確認しましょう。
nginxのコンテナを作成します。

FROM nginx:1.15.6-alpine

RUN { \
echo 'server {';\
    echo 'listen 80;';\
    echo 'root /var/www/html/public;'; \
    echo 'index index.php index.html;'; \
    echo 'error_log  /var/log/nginx/error.log;'; \
    echo 'access_log /var/log/nginx/access.log;';\
    echo 'location ~ \.php$ {';\
        echo 'try_files $uri =404;';\
        echo 'fastcgi_split_path_info ^(.+\.php)(/.+)$;';\
        echo 'fastcgi_pass laravel:9000;';\
        echo 'fastcgi_index index.php;';\
        echo 'include fastcgi_params;';\
        echo 'fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;';\
        echo 'fastcgi_param PATH_INFO $fastcgi_path_info;';\
    echo '}';\
    echo 'location / {';\
        echo 'try_files $uri $uri/ /index.php?$query_string;';\
        echo 'gzip_static on;';\
    echo '}';\
echo '}';\
} > /etc/nginx/conf.d/default.conf

COPY public /var/www/html/public

上記のDockerfileをビルドしていきます。
Dockerfile.nginx などと名付けて、 docker build -f Dockerfile.prod -t laravel-nginx . でビルドしましょう。

やっていることは、phpへのアクセスが来たら laravel:9000 にプロキシするよ、という感じになってます。
次は、laravelという名前でphp-fpmコンテナにつなげるようにしましょう。

nginx経由でphp-fpmに接続

nginxからphp-fpmコンテナに接続したいので、以下の条件を満たしていきます。

  1. 同じネットワーク上にコンテナを配置する
  2. nginxからphp-fpmコンテナに laravel というhost名でアクセスできるようにする

では、やっていきます。

1. 同じネットワーク上にコンテナを配置する

dockerは通常のプロセスと切り離されて存在し、各自にhosts情報を持ちます。
コンテナ同士で通信するためには、同じネットワーク上にコンテナを作成する必要があります。

この際、他のコンテナに影響を与えないように、新たなネットワークを作成します。
名前は docker network ls をしてかぶってないものを選びましょう。
今回は laravel-test として作成します。

$ docker network create laravel-test

2. nginxからphp-fpmコンテナに laravel というhost名でアクセスできるようにする

docker runするときにnameを指定します。
さきほど作成したlaravelというコンテナを、先程つくったlaravel-testというネットワーク上に、 laravelという名前で配置します。

$ docker run --network laravel-test --name laravel laravel

そして、別のターミナルで、同じネットワーク上に先程つくったnginxコンテナを設置します。その際、コンテナの80ポートをマシンの80ポートにexposeします。

docker run --network laravel-test -p 80:80 laravel-nginx

ブラウザでチェック

laravel.png

見えました!!

なお、上記のコマンドだと、ターミナルにログが表示されているはずです。

PHP-FPM側

172.25.0.3 -  30/Dec/2018:17:51:57 +0000 "GET /index.php" 200
172.25.0.3 -  30/Dec/2018:17:51:59 +0000 "GET /index.php" 200

nginx側

172.25.0.1 - - [30/Dec/2018:17:51:57 +0000] "GET / HTTP/1.1" 200 2333 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36"
172.25.0.1 - - [30/Dec/2018:17:51:59 +0000] "GET / HTTP/1.1" 200 2333 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36"

これは、docker run時に -d オプションを渡すと、バックグラウンドで動いてくれます。
あるいは一旦プロセスを停止させて、 docker container start 経由でコンテナを再始動させてもバックグラウンドで動きます。

$ docker container ls -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS                NAMES
39a0c410b1cc        laravel-nginx       "nginx -g 'daemon of…"   10 minutes ago      Exited (0) 6 seconds ago                        boring_rosalind
2b46c41b09db        laravel             "docker-php-entrypoi…"   22 minutes ago      Exited (0) 4 minutes ago                         laravel

$ docker container start 2b46c41b09db
2b46c41b09db

$ docker container start 39a0c410b1cc
39a0c410b1cc

まとめ

ちゃんと手順をまとめたりすると結構時間がかかりましたが、コンテナだけでプロジェクトを作成するだけなら15分くらいでできます。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away