カテゴリー: BackEnd

Laravelの開発環境をdocker-composeで一から構築してみる

はじめに

こんにちは。以前、LaradockでLaravelの開発環境を作っていました。ひとまずLaravelを触ってみたい時はそれで十分ですが、ほとんどチュートリアルのコピペで環境構築が終わってしまうので、dockerやdocker-composeが何をしているのかよく分からないままでした。

Laravel以外の環境構築もDockerで行えるようになっておきたいですし、今回は自力でdocker-composeを書いてローカル環境を構築してみます。

環境はmacOS High Sierra 10.13.6、Docker Desktop 2.0.0.2がインストール済みであることを前提とします。

nginxでwebサーバを立てる

適当なディレクトリを決めて、その中で作業します。どこでも構いませんが、今回は~/testとして、必要なコンテナを構築する情報をdocker-compose.ymlに記述していきます。

$ mkdir ~/test && cd $_1
$ mkdir -p ./docker/web
$ vi ./docker-compose.yml
version: "3"
services:
  web:
    image: nginx:latest
    ports:
      - 80:80
    volumes:
      - ./docker/web/default.conf:/etc/nginx/conf.d/default.conf
      - .:/var/www/html
  • image: nginx:latestで、DockerHub上にあるnginxの最新版のDockerイメージを指定できます。ローカルにイメージがあればそれを使い、無ければダウンロードされます。
  • portsはそのままポート番号です。左側がホスト側、右側がコンテナ側です。上記の場合はいずれもhttp通信のデフォルトである80番を指定しています。
    例えば8000:80と記述した場合、ブラウザからアクセスする際はhttp://ホスト名:8000となります。
  • volumesでコンテナと共有したいパスを指定します。ホスト側で作成したdefault.confを、コンテナ側の同ファイルと置き換えます。
    ポートと同じくホスト側パス:コンテナ側パスの順で記述します。

default.conf作成

nginxの設定ファイルです。ひとまず最低限の設定のみ記述し、PHP関連の設定は後で追記します。

server {
    listen 80;

    root  /var/www/html;
    index index.html;

    access_log /var/log/nginx/access.log;
    error_log  /var/log/nginx/error.log;
}

index.html作成

nginxの動作を確認できればよいので、htmlの中身は1行で構いません。

$ touch ./index.html && echo "

Hello nginx.

" > ./index.html

nginxコンテナ起動

$ docker-compose up -d
Creating network "test_default" with the default driver
Creating test_web_1 ... done

ブラウザでhttp://localhostにアクセスしてHello nginx.の文字が出てくればOKです。

nginxでPHP-FPMを動作させる

docker-compose.yml編集

静的コンテンツが見れるようになりましたので、次はPHP-FPMです。docker-compose.ymlにPHP-FPMコンテナの情報を記述していきます。
また、nginxにもPHP-FPMとの関連性を追記します。

version: "3"
services:
  web:
    image: nginx:latest
    ports:
      - 80:80
    volumes:
      - ./docker/web/default.conf:/etc/nginx/conf.d/default.conf
      - .:/var/www/html
    depends_on:
      - php-fpm
  php-fpm:
    image: php:7.3-fpm-alpine
    volumes:
      - .:/var/www/html
  • image: php:7.3-fpm-alpineで、nginxと同様にdockerhub上のイメージを指定します。PHP-FPMのイメージはたくさんあるのですが、ここでは軽量なalpine Linuxのイメージを使っています。
  • depends_on:はコンテナの依存関係を示します。上記のように記述することで「php-fpmコンテナが起動したらwebコンテナを起動する」という意味になり、起動の順番を制御できます。

default.conf編集

nginxの設定ファイルdefault.confにもPHP-FPMの設定を追記します。
fastcgi_passの項にPHP-FPMへの接続情報を記述します。docker-compose.ymlでPHP-FPMの名前として指定しているphp-fpmを記述し、PHP-FPMのデフォルトポートである9000番を指定します。

server {
    listen 80;

    root  /var/www/html;
    index index.php index.html index.htm;

    access_log /var/log/nginx/access.log;
    error_log  /var/log/nginx/error.log;

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass   php-fpm:9000;
        fastcgi_index  index.php;

        include        fastcgi_params;
        fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param  PATH_INFO $fastcgi_path_info;
    }
}

index.php作成

index.htmlと同様に、起動を確認できれば充分です。

$ touch ./index.php && echo "" > ./index.php

コンテナ起動

初回起動ではイメージのダウンロードが実行されます。最後2行のdoneが表示されたら起動OKです。再度http://loalhostにアクセスしてみましょう。

$ docker-compose up -d
...
中略
...
Creating test_php-fpm_1 ... done
Recreating test_web_1   ... done

MariaDBを立ち上げる

データベースはMariaDBを使用します。MySQLでも問題ありませんが、設定や接続方法はほとんど一緒(らしい)なので、試しに使ってみようという程度のチョイスです。

docker-compose.yml編集

db:以下がMariaDBに関する記述です。また、php-fpmにも上述のdepends_onを追記しています。

version: "3"
services:
  web:
    image: nginx:latest
    ports:
      - 80:80
    volumes:
      - ./docker/web/default.conf:/etc/nginx/conf.d/default.conf
      - .:/var/www/html
    depends_on:
      - php-fpm
  php-fpm:
    image: php:7.3-fpm-alpine
    volumes:
      - .:/var/www/html
    depends_on:
      - db
  db:
    image: mariadb:latest
    ports:
      - 3306:3306
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_USER: test
      MYSQL_PASSWORD: test
      MYSQL_DATABASE: testdb
    volumes:
      - ./db-data:/var/lib/mysql

environment以下にMariaDBの情報を設定しています。MariaDB最新の10系はMySQL5.7がベースとなっており、MySQL用の設定がそのまま使えるようです。

  • MYSQL_ROOT_PASSWORD:rootユーザーの初期パスワードです。
  • MYSQL_USERroot以外の初期ユーザーを設定できます。
  • MYSQL_PASSWORD↑で設定した初期ユーザーのパスワードです。
  • MYSQL_DATABASEを指定することで、MariaDBコンテナに接続する際のデータベース名を定義できます。データベースが無い場合は作成されます。

コンテナ起動

docker-compose up -dでMariaDBコンテナも起動するようになります。

Creating test_db_1 ... done
Recreating test_php-fpm_1 ... done
Recreating test_web_1     ... done

接続確認

PHPからMariaDBへの接続はLaravelインストール後に設定しますので、まずはMariaDBが立ち上がっていることの確認のみです。

#MariaDBコンテナに接続する 
$ docker-compose exec db sh

# testdbに接続する
$ mysql -u test -p testdb

# MYSQL_PASSWORDの値を入力する
Enter password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 9
Server version: 10.3.13-MariaDB-1:10.3.13+maria~bionic mariadb.org binary distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [testdb]>

Laravelインストール

ようやくLaravelです。ComposerやPHP拡張など、Laravelのインストールと動作に必要なパッケージを用意します。php-fpmコンテナの中でコマンドを実行してもよいのですが、docker-composeコマンド実行時に自動でよしなにやってくれるように、docker-compose.ymlを編集します。

php:7.3-fpm-alpineイメージには上述のパッケージが含まれていませんので、別途Dockerfileを作成し、そこにインストールコマンドを記述します。

  php-fpm:
    build: ./docker/php
    volumes:
      - .:/var/www/html
    depends_on:
      - db

build:に記述したパスにDockerfileを作成します。
$ mkdir ./docker/php && vi ./docker/php/Dockerfile

FROM php:7.3-fpm-alpine
RUN apk --update add \
    && apk add build-base curl git zip unzip vim
RUN cd /usr/bin && curl -sS https://getcomposer.org/installer | php && ln -s /usr/bin/composer.phar /usr/bin/composer
RUN apk add libxml2-dev curl-devel $PHPIZE_DEPS
RUN pecl install xdebug
RUN docker-php-ext-install pdo_mysql mbstring xml curl session tokenizer json
RUN docker-php-ext-enable pdo_mysql mbstring xml curl session tokenizer json xdebug
WORKDIR /var/www/html
  • RUN以降をシェルコマンドとして、コンテナ起動時に実行します。
  • apk addでパッケージインストールを行います。alpine以外のイメージだと大抵はapt-getで、CentOSなどのRedHat系で言うyumですね。
  • $PHPIZE_DEPSを指定することで、phpizeに必要なパッケージが自動でインストールされます。phpizeはPHP拡張モジュールを動的にビルドするのに必要で、これがないとPHP拡張を導入する際、いちいちPHP本体をビルドし直すことになってしまいます。
  • pecl install xdebugはdockerとは関係なく、peclライブラリを入れる時のコマンドそのままですね。必要に応じてimagickやredisなどお好きなものを。
  • docker-php-ext-installでPHP拡張をインストールし、docker-php-ext-enableで有効化します。意味こそコマンド名そのままですが、dockerコンテナ上ではこういう書き方になるんですね。
    MariaDBはMySQL用のライブラリで接続可能ですのでpdo_mysqlを入れます。その他mbstringなど最低限必要そうなものを入れていますが、ここもお好みで。
  • RUN composerの行はLaravelのインストールを実行するコマンドです。testappはプロジェクト名ですので、ここは自由にどうぞ。

コンテナ再構築

docker-compose up -dを実行しましょう。パッケージのダウンロード/インストール/ビルドが一斉に走りますので、結構かかります。
上述のDockerfileの最後にLaravelインストールのコマンドを記述すればコンテナ構築と同時にインストールも実行されますが、Dockerfileに書くとコンテナ起動時に毎回Laravelのインストールが走ってしまうので、あとでコンテナに入って実行します。

Laravelインストール

$ docker-compose exec php-fpm sh

/var/www/html # composer create-project --prefer-dist laravel/laravel testapp

ここでもLaravelが依存するComposerのパッケージ群がモリモリ入りますので、数分お待ち下さい。

Laravelのwelcomeページを表示する

Laravelの公開ディレクトリをドキュメントルートにするため、default.confを編集します。locationの中に下記の1行を追記し、docker-compose restartで変更を反映してください。

    location ~ \.php$ {
        root /var/www/html/testapp/public; ←追記
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass   php-fpm:9000;
        fastcgi_index  index.php;

        include        fastcgi_params;
        fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param  PATH_INFO $fastcgi_path_info;
    }

LaravelからMariaDBに接続する

Laravelプロジェクト内の.envファイルに、docker-compose.ymlで設定した接続情報を記述します。DB_HOSTにはMariaDBのコンテナ名が入ります。この場合はdbですね。

$ vi testapp/.env

DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=testdb
DB_USERNAME=test
DB_PASSWORD=test

マイグレーション実行

php-fpmコンテナ内で実行します。DB接続に成功すれば、最初から入っているマイグレーションファイルが実行されます。

$ docker-compose exec php-fpm sh

/var/www/html # cd testapp/
/var/www/html/testapp # php artisan migrate
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table

上記のようなメッセージが表示されればOKです。お疲れ様でした。

さいごに

Laradockはチュートリアルが充実していたおかげで、docker-composeについてはほぼ知識ゼロでも構築ができてしまっていました。今回docker-compose.ymlを調べながら一項目ずつ書くことで、それぞれがどのような意味で何が実行されているのか、多少は把握することができるようになりました。

おすすめ書籍

nomura

コメントを見る

  • Laravelインストールの項目で用意する ./docker/php/Dockerfile の5行目にある
    curl-devel
    でエラーが出て、これは正しくは
    curl-dev
    でしょうか?

    調べると teratail の記述のアンサーで解決できたのでお知らせさせていただきました。
    https://teratail.com/questions/310977

シェア
執筆者:
nomura
タグ: Dockerlaravel

最近の投稿

フロントエンドで動画デコレーション&レンダリング

はじめに 今回は、以下のように…

2週間 前

Goのクエリビルダー goqu を使ってみる

はじめに 最近携わっているとあ…

4週間 前

【Xcode15】プライバシーマニフェスト対応に備えて

はじめに こんにちは、suzu…

2か月 前

FSMを使った状態管理をGoで実装する

はじめに 一般的なアプリケーシ…

3か月 前