Laravel開発環境をDockerで作成 「基本構成」

今回の環境について

今回の記事ではLaravelの開発環境をDockerで作成していきます。
マシンはWindowsを使用していますが、wsl上での構築となるため、Macでも同様に使用可能だと思います。

むしろ、Windowsマシンを使用している場合については、色々と都合の悪い挙動があり苦労しました。
Windowsマシンの場合については、ファイルを含めwsl上に配置してしまう方が良いという結論になりましたが、それにしても、、、な部分もあります。
とりあえず、細かい部分には目を瞑ってまずはLaravelの開発を行うためのDockerを作成していきます。

ディレクトリ構成

  • docker-sample
    • docker
      • laravel-bash
        • dev-serve.sh
        • first.sh
        • restart.sh
      • mysql
        • Dockerfile
        • init.sql
        • db_data
      • nginx
        • default.conf
        • Dockerfile
      • php
        • Dockerfile
        • php.ini
      • volumes
      • .env
      • docker-compose.yml
      • docker-compose.yml.template
    • src

青く色を付けているものがファイルになっています。

dockerディレクトリにはDocker全体の設定ファイルと、各コンテナのフォルダを配置しています。
各コンテナのフォルダにはコンテナの構成ファイルや設定ファイルを格納しています。
今回作成しているものは汎用的なものとして作成したいので、案件ごとに設定を組み替えることを想定して作成しました。

「docker-compose.yml.template」については不要です。
今回はgitで管理することを想定しています。そのため、Docker環境を構築する端末によって多少設定が変わることを考慮して、gitで管理するための設定ファイルとして「docker-compose.yml.template」を作成しました。
「docker-compose.yml」が本体ファイルとなるため、こちらで十分ということであれば「docker-compose.yml.template」は不要です。

.env

Dockerの環境変数の定義ファイルになります。今回はプロジェクト名を定義しているだけになります。
あまり見かけないファイルですが、便利そうなので使ってみました。
場合によっては、このファイルも「.env」「.env.template」といった感じでgit管理用に作成することが求められるかもしれませんね。

COMPOSE_PROJECT_NAME=laravel_docker_sample

docker-compose.yml

各コンテナの定義を行うファイルになります。
Docker環境を作成する上で一番のコアになるファイルですね。

version: '3'
services:
  laravel_docker_sample-nginx:
    build: 
      context: ./nginx
    restart: no
    ports:
      - "80:80"
    volumes:
      - laravel_docker_sample-src:/var/www/html
    depends_on:
      - laravel_docker_sample-php
      - laravel_docker_sample-mysql
  laravel_docker_sample-php:
    build:
      context: ./php
    ports:
      - "8000:8000"
      - "5173:5173"
    volumes:
      - laravel_docker_sample-src:/var/www/html
      - ./laravel-bash:/var/www/html/laravel-bash
    restart: no
  laravel_docker_sample-mysql:
    build:
      context: ./mysql
    volumes:
      - laravel_docker_sample-db_data:/var/lib/mysql
    restart: no
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: test
      MYSQL_USER: test
      MYSQL_PASSWORD: test
volumes:
  laravel_docker_sample-src:
    driver: local
    driver_opts:
      o: bind
      device: ../src
      type: none
  laravel_docker_sample-db_data:
    driver: local
    driver_opts:
      o: bind
      device: ./mysql/db_data
      type: none

version

Docker Compose のバージョンを指定します。

services

各コンテナの定義を行います。
以下、今回の各コンテナの定義についての解説もどきになります。

もちろん名前は適当なものに変えてください。

laravel_docker_sample-nginx(Nginxコンテナ)

「build」セクションの「context」にて「./nginx」を指定しています。
そのため、同じdockerディレクトリに存在する「nginx」ディレクトリの「Dockerfile」を元にコンテナのビルドが行われます。

「restart: no」とすることで、コンテナ終了時に再起動しないようにしています。
コマンドによる再起動などは通常通り行えます。なんらかの理由で予期せぬ停止をした場合の挙動を指定できます。

「ports」でホストのポートとコンテナのポートをマッピングします。「ホストのポート: コンテナのポート」で指定します。
Webサーバ機能を使用するためにコンテナの80ポートにマッピングしています。80以外の場合はコンテナの設定を変えた上で、個々の記述も変更しましょう。ホスト側は空いているポートであればOKです。そのため、ホストのポートが他のソフトウェアによって使用されている場合は「8080:80」などとして、ホスト側のポートをずらしましょう。

「volumes」はボリュームを使用して、ホストとコンテナ間でデータを共有するために設定します。
今回は「laravel_docker_sample-src:/var/www/html」とすることで、serviceと同列で定義しているvolumesの「laravel_docker_sample-src」をコンテナの「/var/www/html」にマウントします。
volumesという同じ名前で、ホストとコンテナ間の設定と、ボリューム自体の定義をしているので注意してください。

最後に「depends_on」です。これを定義することで、指定したコンテナの起動後にコンテナが起動します。
今回の定義により、「laravel_docker_sample-nginx」は「laravel_docker_sample-php」と「laravel_docker_sample-mysql」のコンテナが起動した後に起動します。

laravel_docker_sample-php(phpコンテナ)

このコンテナでLaravelの開発を進めていくことになります。
基本的な記述はNginxコンテナと同じなので詳しい説明は省きます。

portsにて「8000」「5173」を指定していますが、これはLaravelのビルトインサーバとviteが使用するポートを指定しています。
開発の際にこれらを使用する場合にひつようになるため、念のため指定をしています。
特に8000ポートについてはNginx経由でアプリケーションにアクセスしていると使用しない可能性がありますね。

続いてvolumesの「./laravel-bash:/var/www/html/laravel-bash」です。
先ほどは定義したボリュームを使用しましたが、これはディレクトリを直接マウントしています。
この、「laravel-bash」は私が横着するために作成したshファイルが入っているので、雑にマウントしました。なくても大丈夫なものです。
過去に一部環境で、volumesとして定義したものをマウントしないと正常に動作しないパターンがありました。
なので、ボリュームマウントを実施する際には定義したものをマウントすることをおススメします。

laravel_docker_sample-mysql(MySQLコンテナ)

続いてMySQLコンテナになります。DBコンテナはボリュームマウントを行わないと「うっかりデータが飛ぶ」可能性があるので、マウント必須だと思っています。

ここでの新しい記述としては「environment」になります。今回設定しているのは

  • MYSQL_ROOT_PASSWORD:rootユーザーのパスワード
  • MYSQL_DATABASE:作成するデータベースの名前
  • MYSQL_USER:作成するユーザーの名前
  • MYSQL_PASSWORD:作成したユーザーのパスワード

この設定により初期設定が行われ、指定したデータベース、ユーザーが作成されます。

volumes

Dockerコンテナにマウントしているボリュームの定義を行っています。
パスを直接記述してマウントする方法もありますが、このように定義してからマウントしないと動作しない場合もあるようです。
※昔のバージョンの話なので、現在は分かりません