【WSL2】DockerでLaravel開発環境を構築する -Part2-

【WSL2】DockerでLaravel開発環境を構築する -Part2-

はじめに

前回では、各種コンテナの導入・設定を行っていきました。今回は機能を追加して最終的な開発環境を完成させます。

今回は、太字の部分を実装していきます。

  • Lravel の開発環境
  • X-Debug の導入
  • npm を導入して JavaScript FW の開発にも対応する
  • リバースプロキシを導入して test.example.comのようなポート番号無しのドメインでアクセスできるようにする
  • mailhog を導入してメール送信のテストを行えるようにする

前回の記事はこちらです。

開発環境

  • OS: Windows11(21H2)
  • WSL: Ubuntu-20.04 Version 2
  • Docker: Version 20.10.9
  • Docker Compose: Version 1.29.2

リバースプロキシの導入

リバースプロキシとは、ざっくりいうと外部からの通信をリバースプロキシ配下にある Web サーバに振り分ける機能を持ったサーバになります。

リバースプロキシの設定

今回、リバースプロキシにはjwilder/nginx-proxyを使用します。この Docker イメージ を使うことで、簡単にリバースプロキシ環境が構築できます。

WSL2 上で起動した Docker ではhttp://localhost:8080のようにポート番号もつけてアクセスする必要がありますが、jwilder/nginx-proxyを使うことで、test.example.comのようにポート番号を付けずにアクセスすることができます。

services:
  # サービス名を指定
  nginx-proxy:
    container_name: nginx-proxy-container
    # 使用する Docker Image を指定
    build: ./docker/nginx-proxy
    ports:
      # 80番ポートへのアクセスを、Docker上で動いているサーバの80番ポートに対応させる
      - 80:80
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro

設定は至ってシンプルです。

volumes:
  - /var/run/docker.sock:/tmp/docker.sock:ro

ここではホスト側の Docker ソケットをコンテナ側へマウントしています。コンテナ側で:roとすることで読み取り専用としてマウントさせます。デフォルトでは書き込みも可能なアクセス権となります。

Dockerfile の設定

ここでは使用するイメージを指定しているだけですが、他のコンテナ同様に Dockerfile に切り分けました。

"docker/nginx-proxy/Dockerfile
FROM jwilder/nginx-proxy

Docker ソケットとは?

Docker ソケットとはざっくりいうと、Docker デーモンと通信するための橋渡しすをるための仕組みになります。Linux に詳しい方ならシェルにのようなものと言ったほうが伝わりやすいでしょうか。

このホスト側の Docker ソケットをコンテナ側へマウントすることによってコンテナ側から Docker ソケット経由して通信することが出来ます。

ローカル環境で任意のドメインを使ってアクセスするための設定

Web サーバ側で、ローカル環境で任意のドメインを使ってアクセスするための設定を行います。

Web の Dockerfile に、以下の記述を追加します。

"docker/web/Dockerfile
# 指定したドメインでコンテナにルーティングされるように設定
# nginx-proxyに関連した設定
ENV VIRTUAL_HOST=test.example.com

次に、Windows 内のhostsファイルにこのドメインを追加します。

Windows で hosts ファイルはC:\Windows\System32\drivers\etcに配置されています。

hostsファイルを visual studio code など適当なエディタで開きます。開いたファイルにループパックアドレスとドメインを記述します。

hostsファイル

保存する際に管理者権限を許可して保存します。

hostsファイル保存

mailhog の設定

最後に mailhog の記述を確認します。

services:
  # 中略

  # mailhogのコンテナ
  mailhog:
    # コンテナ名を指定
    container_name: mailhog-container
    build: ./docker/mailhog
    ports:
      # 管理画面に接続するポート(違うポート番号にすると管理画面に接続できない)
      - 8025:8025

このイメージファイルのDcokerHubを確認すると、メール送信のための SMTP ポートは1025、管理画面用の HTTP 通信用のポートは8025だということが分かります。

メール送信のための設定は GitHub に記載さています。

Dockerfile の設定

ここでも使用するイメージを指定しているだけです。

"docker/mailhog/Dockerfile
FROM mailhog/mailhog

コンテナを起動する準備

コンテナをビルドする

一通り設定が終わりましたので、一度コンテナを起動します。

# イメージからコンテンを構築
$ docker-compose build
# 正常にビルドが完了したことを確認

# コンテナを起動
$ docker-compose up -d

Laravel をインストールする

各種コンテナ起動後、Web サーバのコンテナに入り Laravel をインストールします。

# Webサーバのコンテナ内にログイン
$ docker-compose exec web bash

# 現時点での最新版がインストールされます
$ laravel new sample_laravel

# プロジェクトディレクトリへ移動
$ cd sample_laravel

# Webサーバの書き込み権限を与える
$ chmod -R 777 storage
$ chmod -R 777 bootstrap/cache

ブラウザのアドレスバーにtest.example.comと入力して Laravel のトップページが表示されるはずです。

Laravelトップ画面

Remote Development を導入する

この後.envファイルに接続するデータベースの情報を記述していくのですが、コンテナ内のファイルを wsl にマウントさせているファイルに対して、エディタで直接編集しようとすると権限が無いと言われるので、Remote Developmentでコンテナにリモート接続して開発を行います。

Remote Development

Remote Developmentの導入の仕方は以下の記事を参考にしました。

作成されたdevcontainer.jsonの内容です。remoteUserだけvscodeからrootに変更しています。

".devcontainer/devcontainer.json"
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
// https://github.com/microsoft/vscode-dev-containers/tree/v0.238.0/containers/debian
{
  "name": "Debian",
  "build": {
    "dockerfile": "Dockerfile",
    // Update 'VARIANT' to pick an Debian version: bullseye, buster
    // Use bullseye on local arm64/Apple Silicon.
    "args": { "VARIANT": "bullseye" }
  },

  // Use 'forwardPorts' to make a list of ports inside the container available locally.
  // "forwardPorts": [],

  // Uncomment to use the Docker CLI from inside the container. See https://aka.ms/vscode-remote/samples/docker-from-docker.
  // "mounts": [ "source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind" ],

  // Uncomment when using a ptrace-based debugger like C++, Go, and Rust
  // "runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined" ],

  // Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
  "remoteUser": "root"
}

これで vscode で編集できるようになりました。

.env を編集

データベース接続に関する設定

.env内のデータベース接続に関する部分を以下のように記述します。

ホスト名が127.0.0.1では無いことに注意してください。

DB_CONNECTION=mysql
# container_name: db-container を指定
DB_HOST=db-container
DB_PORT=3306
DB_DATABASE=sample_laravel
DB_USERNAME=root
DB_PASSWORD=rootpass

マイグレーションを実行する

コンテナへ接続し migrate コマンドを実行します。

# Webサーバのコンテナ内にログイン
$ docker-compose exec web bash

$ cd sample_laravel

$ php artisan migrate
# 正常に実行が完了したことを確認する

phpMyAdmin への接続テストも兼ねて、テーブルが作成されているか確認します。

http://test.example.com:8082へ接続するの phpMyAdmin へ接続できると思います。

phpMyAdmin

mailhog に関する設定

Laravel9 を新規でインストールした場合、デフォルトの.envファイルで mailhog に関する設定は以下のようになっています。テストメールを送信するだけなら設定の変更は必要ありません。

MAIL_MAILER=smtp
MAIL_HOST=mailhog
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS="hello@example.com"
MAIL_FROM_NAME="${APP_NAME}"

mailhog をテストする

mailhog の動作確認を行っていきます。http://test.example.com:8025へアクセスすると以下のような管理画面が開きます。

mailhog管理画面

次に、Laravel のtinkerを使ってメールを送信するプログラムを実行します。

$ php artisan tinker
Psy Shell v0.11.5 (PHP 8.1.9 — cli) by Justin Hileman
>>> Mail::raw('test email body', function ($email) { $email->to('info@hn-pgtech.com')->subject('test email subject'); });
=> Illuminate\Mail\SentMessage {#3562}

管理画面でメールが届いているか確認します。

mailhog管理画面メール1

mailhog管理画面メール2

正常に届いていることが確認できました。

XDebug をテストする

最後に、XDebug が実行できる環境を作成します。

まずは VS code の拡張機能でPHP Debugをインストールします。

PHP Debug

次に.vscodeディレクトリを作成し、その配下にlaunch.jsonを作成します。

".vscode/launch.json"
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "PHP XDebug", // デバック構成として表示する名前
      "type": "php", // 使用するデバッガー

      // launch: デバッグ時にプログラムを起動する
      // attach: 既に起動しているプログラムにデバッガーをアタッチする
      "request": "launch", // デバッグ実行のモード
      "port": 9013, // php.iniのxdebugの設定と合わせる
      "pathMappings": {
        // docker上のdocument root: ローカルのdocument root
        "/var/www/html": "${workspaceRoot}/htdocs" // ${workspaceRoot}: VSCodeで開いたフォルダのパス
      },
      "ignore": ["**/vendor/**/*.php"], // デバッグを除外するファイルやディレクトリを指定
      "xdebugSettings": {
        "max_children": 128,
        "max_data": 1024,
        "max_depth": 10
      }
    }
  ]
}

php.iniの設定は前回の記事で紹介しているのでそちらを参照してください。

ここまで設定できたら、デバッグできるか確認します。今回は適当にルーティングのファイルにブレークポイントを設置して XDbug を起動します。

XDebug_1

トップページにアクセスし直すとブレークポイントで実行が止まっているのが分かります。

XDebug_2

以上で一通り環境構築が終わりました。

最後に

Laravel ではLaravel Sailなどがありますが、今回自分で一から開発環境を構築して色々調査していく中で理解が深まった部分があり大変勉強になりました。

Docker の開発環境は GitHub に色々な方が公開しているので、参考にして違うミドルウェア導入したり挑戦してみたいと思います。