Web制作を行う全ての方へ

Laravel 開発環境を Docker で構築

ブログを書くのがかなり久しぶりになります。

最近 Laravel を触ってまして、Docker で環境構築して使うことが増えてきたので備忘録として書いておこうと思うので、これから触ってみたいという方の参考になれば嬉しいです

今回実行した環境は以下のとおりです

  • Mac Apple M1 MAX
  • Ventura 13.1

Docker の仕様について

下記環境を構築します

  • Webサーバー: NginX
  • PHP: php-fpm (php:8.0.5-fpm-alpine)
  • Database: MariaDB

まずは Docker が入ってない人は Docker をインストールしましょう

Docker

Docker はわかりやすく概要を説明すると、コンテナに必要なアプリケーションをイメージという単位で構築し、それぞれに上記で記載している Web サーバーや PHP, Database といったアプリケーションやミドルウェアなど自分に必要な構成で自分の端末に構築できる仕組みです。

自分の端末に直接 Web サーバーや Laravel をインストールして動かすこともできますが、案件によって Web サーバーを変更したり PHP のバージョンを変更するのは手間がかかります。

Docker なら必要なときに必要な構成を docker-compose.yml というファイルに定義しておくことでいつでも立ち上げたりシャットダウンしたり、削除することができるので、切り替えが容易に行えて楽です。

また設定ファイルを共有すれば、他の人にもすぐに同じ環境を用意してもらえるので、共同開発するのも便利。

かなり端的に概要を書いているので、もっと詳しく知りたい方はサーバー会社のさくらインターネットさんが公開している「さくらのナレッジ」の記事を読んでみましょう

Docker入門(第一回)~Dockerとは何か、何が良いのか~:さくらのナレッジ

docker-compose.yml

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

今回開発するフォルダを作成し、上記ファイルを保存しましょう。

作成するフォルダを sample とし、ユーザーディレクトリに作成した場合下記構成になります。

~/sample/docker-compose.yml

~/ はユーザーディレクトリを指します

このファイルを書く場合インデントに注意してください。インデントが崩れているとエラーになります。

Web サーバー NginX の設定

NginX の設定ファイルが必要なので、default.conf というファイルを用意します

default.conf

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$ {
    root /var/www/html/sample/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;
  }
}

root の位置は自分の作成したフォルダが sample なので、/var/www/html/sample/public になります。docker-compose.yml で名前を変更した場合は、このディレクトリ構造の sample を自分が docker-compose.yml で指定した値に合わせてください

同様に fastcgi_pass には docker-compose.yml に記載している php-fpm を指定し、ポートはデフォルトの9000番を割り当てています。

このファイルは下記のように配置します

~/sample/docker/web/
  │                             └──default.conf
  └──docker-compose.yml

ここで docker を起動しましょう

ターミナルなどで下記コマンドを実行します。場所は ~/sample に移動してから実行。(%は入力不要です)

% docker-compose up -d

データベース MariaDB

docker-compose.yml に MariaDB への接続情報を記載しています

上記記載の docker-compose.yml から抜粋

  db:
    image: mariadb:latest
    ports:
      - 33306:3306 //← 外部から接続する時のポート番号:内部接続時のポート番号
    environment:
      MYSQL_ROOT_PASSWORD: root //← Root のパスワード
      MYSQL_USER: root //← ユーザー名
      MYSQL_PASSWORD: root //← パスワード
      MYSQL_DATABASE: sampledb //← 作成するデータベース名
    volumes:
      - ./db-data:/var/lib/mysql

まずはデータベースが起動しているか確認してみましょう

下記コマンドをターミナルで入力してデータベースのコンテナに接続します

% docker-compose exec db sh

docker-compose exec ○○ sh で起動している○○( docker-compose.yml で定義している services: 内部に記載している web, php-fpm, db のどれか )に接続するという意味です。接続すればターミナルの操作が自分の端末ではなく、コンテナ上での操作に変わります。

# 

環境によって異なりますが、% から # のようにターミナルの開始記号が変わっていれば、コンテナに接続できています。

コンテナから抜けたい場合は exit コマンドで。

# exit
% 

このように切り替わったことを確認しながら今自分の端末を操作しているのか、コンテナを操作しているのか判断できるようになりましょう。

説明どおりに進めているとコンテナから抜けているので、改めてコンテナに接続します。

% docker-compose exec db sh

次にコンテナ内のデータベースに接続します

# mysql -u root -proot sampledb

mysql コマンドの -u はユーザーをしてするオプション、-p はそのまま続けてパスワードを入力するオプションで、最後に接続するデータベース名を記載します。

これらコマンドを使う時は下記に気をつけてください

  • 小文字大文字を間違えてないか
  • 半角スペースが全角スペースになっていないか

ハイフンが付いているものはオプションです。-p については続けて入力するパスワードを省くと、コマンド実行後にパスワードを確認してきます。

mysql -u root -p sample
Enter pasword;

どちらの方法でも下記のようなメッセージが表示されれば接続できています

Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 28
Server version: 10.11.2-MariaDB-1:10.11.2+maria~ubu2204 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.

Laravel インストール

今回利用するバージョンは 9.52.7 になります

Laravel は PHP のフレームワークになるので、PHP の必要なパッケージやモジュールをインストールするために Docker ファイルを作成します

作成場所は先に記載している docker-compose.yml に記載している php-fpm の build 部分にしている場所になります

上記記載の docker-compose.yml から抜粋

php-fpm:
    build: ./docker/php

ファイル構成で示すと下記の構成になります

~/sample/docker/php/
  │                  │          └──Dockerfile
  │                  └─/web/
  │                             └──default.conf
  └──docker-compose.yml

Dokerfile

FROM php:8.0.5-fpm-alpine
RUN apk --update add \
     && apk add build-base curl git zip tar unzip vim oniguruma-dev
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-dev $PHPIZE_DEPS
RUN pecl install xdebug-3.1.5
RUN docker-php-ext-install pdo_mysql
RUN docker-php-ext-install mbstring
RUN docker-php-ext-install xml
RUN docker-php-ext-install curl
RUN docker-php-ext-install session
RUN docker-php-ext-install tokenizer
RUN docker-php-ext-enable pdo_mysql mbstring xml curl session tokenizer xdebug
WORKDIR /var/www/html

RUN docker-php-ext-install のように重複している箇所ははまとめて記述することもできます

RUN docker-php-ext-install pdo_mysql mbstring xml curl session tokenizer

ただこの場合どれかのパッケージインストール時にエラーが有る場合、原因が特定しづらいので分けておけばどのパッケージでエラーが出たかわかりやすくなります。

  • RUN 以降を Docker のコンテナ起動時に実行
  • apk add でパッケージのインストールを行います。
  • $PHPIZE_DEPS の指定は phpize に必要なパッケージのインストール。PHP拡張モジュールを動的にビルドするのに必要なもので、この指定がないと PHP 本体をビルドし直すことになります。
  • pecl install xdebug は PHP のデバッグツールですが僕が今回インストールした際にバージョン指定なしでインストールするとエラーが発生したので 3.1.5 を指定しています。
  • docker-php-ext-install PHP の拡張インストールで、docker-php-ext-enable を使って有効化しています。

コンテナ再構築

PHP の設定ファイルを追加したので docker-compose を再度実行し、コンテナを再構築します

% docker-compose up -d

構築が終わったら Laravel をインストールするため php-fmp のコンテナに接続し、インストールコマンドを実行します

% docker-compose exec php-fpm sh

接続するとターミナルの開始記号が下記のようになるはずなので

/var/www/html #

この状態でインストールコマンドを実行します。

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

最後の sample はアプリケーションの名前になり、作成したディレクトリにこの名前のフォルダが作成されます。

~/sample/db-data/
  │             /docker/php/
  │                  │          └──Dockerfile
  │                  └─/web/
  │                             └──default.conf
  │             /sample/
  └──docker-compose.yml

この sample フォルダの中身が Laravel プロジェクトになります

Laravel の welome ページをブラウザに表示

上記で作成している default.conf にドキュメントルートの指定が入っています

default.conf より抜粋

root /var/www/html/sample/public;

この中の index.php ファイルが Laravel プロジェクトをブラウザで表示する際のトップページになります。

そして、Laravel から データベースに接続する設定を .env というファイルに書き込まないとエラーになるので、.env を編集し MySQL の記述を下記に変更します。

Laravel プロジェクトフォルダ(今回だと sample )の直下に .env というファイルがありますが、見えない場合は不可視ファイルを表示するように設定が必要です

  • Mac の場合 cmmand + shift + .
  • Windows の場合 タスク バーから エクスプローラー を開く> [表示] > [表示] > [隠しファイル] を選択

.env の DB_ で始まる箇所を編集し、docker-compose.yml にある同一の項目と値を合わせます

DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=sampledb
DB_USERNAME=root
DB_PASSWORD=root
  • DB_CONNECTION の値は mysql になります。MariaDB ではないので注意しましょう
  • DB_HOST の値は docker-compose.yml で指定しているサービス名になるので今回は db
  • DB_PORT の値はコンテナ同士を内部通信で行うので docker-compose.yml で指定した ports の右側の値(33306:3306)
  • DB_DATABASE, DB_USERNAME, DB_PASSWORD の値は docker-compose.yml に指定した名前をそのまま利用します

これで php-fpm のコンテナに接続し、データベースのコンテナへ接続できるので、php-fpm に接続した状態でデータベースのテーブル定義を Laravel のコマンドを利用して設定します。

コンテナに接続していない場合はまずは接続

% docker-compose exec php-fpm sh

接続したらドキュメントルートから始まるので、Laravel プロジェクトに移動

/var/www/html cd sample

/var/www/html は表示されているはずなので、コピーする際にコピーしないように気をつけてください

cd というコマンドがディレクトリを移動するコマンドを意味し、今いる階層に存在する sample ディレクトリに移動するという意味になります。

移動したら Laravel の migrate コマンドを実行

/var/www/html/sample  php artisan migrate

こんな感じで表示されれば成功。

これは Laravel プロジェクトに artisan ファイルが存在するからこのコマンドが利用できるので、エラーが出た場合は正しいディレクトリ位置にいるか確認してください。また今いる sample ディレクトリの中身を確認して artisan ファイルが存在するかも確認してみましょう。

ディレクトリ内のファイルを確認するには下記コマンドを実行

/var/www/html/sample ls -la

下記のように存在するファイル一覧を表示できます

また、自分の端末のユーザーディレクトリに sample ディレクトリを作成して開発しているので、ユーザーディレクトリの中身を Finder や エクスプローラで確認すれば同様に内部のファイル一覧が確認できます。

コンテナに接続して確認するのも、端末側から確認するのも同じファイルが確認できます。これは同じファイルを扱っている事になりますが下記の違いがあります

  • コンテナに接続してアクセスする場合はルートディレクトリが Laravel ディレクトリになり、ドキュメントルートは default.conf に記述した設定になる(今回は /var/www/html/photom/public
  • 端末から見る場合はルートは端末のルートディレクトリ

Docker の Web サーバーコンテナを利用しているので、これは仮想的なサーバーを端末の中に用意して利用している。こんなイメージを想像してもらえればわかりやすいと思います。

自分の端末内部イメージ
Docker, Container, image

ここまでで準備は整いました。実際にブラウザに表示してみましょう。

/var/www/html/sample php artisan serve

php artisan serve このコマンドで Web サーバーが起動します。

Web サーバーが起動すると ip アドレスが表示されるので、この ip アドレスをコピーしてブラウザに貼り付けてみます。

様子がおかしいですね。

コンテナ内部から起動するとこのように表示できないエラーが返ってきます。

これはコンテナ内部からの通信設定で起動しているからで、ブラウザを経由するような外部通信だと設定を変えないといけないんですよね。(これに気づくのに時間がかかりました)

ですので、まずは一度起動を停めます

Press Ctrl+C to stop the server

と記載があるので、キーボードを Ctrl + C 入力して停めます。そしてコンテナの接続から抜けて自分の端末接続に切り替えます

/var/www/html/sample exit

次に .env のファイルを書き換えます

.env

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=33306
DB_DATABASE=photom
DB_USERNAME=root
DB_PASSWORD=root

変わるのは DB_HOST と DB_PORT ですね。内部通信・外部通信というのがいまいち理解しづらいですが、ターミナルでコンテナに接続してそこから別のコンテナに接続通信を行う場合は内部通信。ブラウザなどを使って外側から通信する場合が外部通信といった感じです。

内部通信の場合は DB_HOST の名前を docker-compose.yml で指定しているサービス名を指定していましたが、外部通信に変更する場合は

  • DB_HOST を 先程表示された ip アドレスに( 127.0.0.1 )
  • DB_PORT を docker-compise.yml ファイルの内部と外部で設定した左側の内容に( 33306:3306 )

Laravel を触っていてブラウザに表示した際に接続エラーが出た場合は、この設定値に誤りがあるケースが多いので確認してみましょう。

ちなみになぜわざわざ外部と内部のポートを変えているかというと、自分の環境にほかの開発用アプリケーションがインストールしてあって、それらが既存の 80番や3306番を利用しているかで、ここがバッティングするとエラーになって使えないからです。

コンテナー同士の内部通信であればそれらの影響を受けないのでデフォルトの値で利用できますが、開発端末の方はそういうわけに行かないので、外部通信のポートをあえて変更して設定しています。

では改めて端末側からサーバーを起動してみましょう。必ず Laravel プロジェクトにいることを確認してください

% php artisan serve

先ほどと同じ用に ip アドレスが表示されるのでブラウザの画面を更新します

この画面が表示されれば成功です。

参考資料

今回記事執筆に参考させていただきました

お役に立てたらお願いします🙇

Kyashで送金する

Ad



Share