⛴️

Laravelの開発環境をdocker-composeで自作してみる

2022/09/01に公開

目次

  1. 背景
  2. プロジェクトの作成
  3. Nginxコンテナの作成
  4. PHPコンテナの作成
  5. Laravelプロジェクトの作成
  6. MySQLコンテナの作成
  7. まとめ

背景

私は普段業務でLaravelを使用することが多く、ローカルの開発環境にはDockerを使用することがほとんどです。

ただ、その開発環境は既に社内で知見のある方が作ったテンプレートをmaek upコマンドで立ち上げるだけで、実際にどうやって環境が出来ているかを詳しく知らずに使っていました。

そこでインフラやコンテナの知見を深めるために、Laravelの開発環境をdocker-composeを使用して自作してみたいと思います。

環境の構成はWebサーバー、PHPサーバー、DBサーバーで、
ミドルウェアは私が良く使っているNginx、MySQLを使用します。

プロジェクトの作成

1. ディレクトリ構成

それではプロジェクトを作成していきます。

Dockerやdocker-composeの概要については割愛します。

日本語のドキュメントはこちらです。

まずはディレクトリを作成します。

$ mkdir sample
$ cd sample

2. docker-composeファイルの作成

各コンテナを起動する大元となるdocker-compose.ymlファイルをプロジェクト配下に作成します。
このファイル内で各コンテナを定義していき、1つの環境を作っていきます。

$ touch docker-compose.yml

今回、docker-composeのバージョンは3.xとします。

~/docker-compose.yml
# docker-composeのバージョン
version: "3" 

まずは簡単にNginxコンテナを作成したいと思います。

~/docker-compose.yml
# docker-composeのバージョン
version: "3" 

services:
  # コンテナの作成
  web:
    # このコンテナで使用するDockerイメージの指定
    image: "nginx:latest"
    # ホスト側のポート:コンテナ側のポートを指定
    ports:
      - "8080:80"

それではコンテナを起動します。

$ docker compose up -d --build

コンテナが正常に起動したら、http://localhost:8080を開いてみます。

[+] Running 1/1
 ⠿ Container sample-web-1  Started

Nginxの初期画面が開きました。

これから作成するコンテナの設定ファイルを配置するためのディレクトリを作成します。

$ mkdir container

Nginxコンテナの作成

これから本格的に開発環境を作っていきます。

containerディレクトリ配下にNginxコンテナで使用するファイルを格納するためのディレクトリを作成します。

$ cd container
$ mkdir web

1. 設定ファイルの作成

Nginxの設定ファイルを作成します。

$ cd web
$ touch default.conf

設定ファイルはこちらを参考にしました。

~/container/web/default.conf
server {
    listen 80;
    listen [::]:80;
    # ルートディレクトリを指定
    root /var/www/html/public;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-Content-Type-Options "nosniff";

    index index.php;

    charset utf-8;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    error_page 404 /index.php;

    location ~ \.php$ {
        # PHP-FPMはデフォルトで9000番のポートを使用するため、PHPコンテナの9000番へルーティング
        fastcgi_pass php:9000; 
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}

2. Dockerfileの作成

Nginxコンテナを起動するためのDockerfileを作成します。

$ touch Dockerfile

作成したDockerfileを編集していきます。

~/container/web/Dockerfile
# ベースイメージの指定
FROM nginx:stable-alpine

# 作成した設定ファイルをコンテナ内にコピー
COPY ./container/web/default.conf /etc/nginx/conf.d/default.conf

3. docker-composeファイルの書き換え

作成した設定ファイルをdocker-composeファイルに反映させたいと思います。

~/docker-compose.yml
# docker-composeのバージョン
version: "3" 

# コンテナ定義
services:
  # webサーバー
  web:
    # コンテナ名
    container_name: "web"
    # コンテナの作成に使用するDockerfileのパス
    build:
      dockerfile: "./container/web/Dockerfile"
    # ホスト側のポート:コンテナ側のポートを指定
    ports:
      - "8080:80"
    # src配下のファイルをコンテナ内の~/va/www/html配下に配置
    volumes:
      - "./src:/var/www/html"

書き換えたら、再度コンテナを立ち上げます。

$ docker compose up -d --build

コンテナが正常に起動したら、http://localhost:8080を開いてみます。

[+] Running 2/2
 ⠿ Network sample_default  Created
 ⠿ Container web           Started

指定したrootにファイルがないため、File not Found.となりましたが、このまま進めたいと思います。

PHPコンテナの作成

続いて、アプリケーションサーバーとなるPHPのコンテナを立ち上げたいと思います。

1. 設定ファイルの作成

containerディレクトリ配下にphpディレクトリを作成します。

$ cd container
$ mkdir php

PHPの設定ファイルを作成します。

$ touch php.ini
~/container/php/php.ini
[Date]
date.timezone = "Asia/Tokyo"
[mbstring]
mbstring.internal_encoding = "UTF-8"
mbstring.language = "Japanese"

2. Dockerfileの作成

PHPコンテナ用のDockerfileを作成します。

$ touch Dockerfile
~/container/php/Dockerfile
# ベースイメージの指定
FROM php:fpm-buster

# 作成した設定ファイルをコンテナ内にコピー
COPY ./container/php/php.ini /usr/local/etc/php/php.ini

# コンテナ内で作業する際のカレンとディレクトリの指定
WORKDIR /var/www/html

3. docker-composeファイルの書き換え

~/docker-compose.yml
# docker-composeのバージョン
version: "3" 

# コンテナ定義
services:
  # webサーバー
  web:
    # コンテナ名
    container_name: "web"
    # コンテナの作成に使用するDockerfileのパス
    build:
      dockerfile: "./container/web/Dockerfile"
    # ホスト側のポート:コンテナ側のポートを指定
    ports:
      - "8080:80"
    # src配下のファイルをコンテナ内の~/va/www/html配下に配置
    volumes:
      - "./src:/var/www/html"

  # PHPサーバー
  php:
    # コンテナ名
    container_name: "php"
    # コンテナの作成に使用するDockerfileのパス
    build:
      dockerfile: "./container/php/Dockerfile"
    # srcディレクトリ内のファイルをコンテナ内の~/var/www/html配下にマウント
    volumes:
      - "./src:/var/www/html"

書き換えたら、再度コンテナを立ち上げます。

$ docker compose up -d --build

PHPコンテナが正常に起動しました。

[+] Running 3/3
 ⠿ Network sample_default  Created
 ⠿ Container web           Started
 ⠿ Container php           Started

Laravelプロジェクトの作成

1. Dockerfileの書き換え

Laravelのプロジェクトを作成出来るように各種パッケージとcomposerをPHPコンテナ内でインストールします。

~/container/php/Dockerfile
# ベースイメージの指定
FROM php:fpm-buster

# 作成した設定ファイルをコンテナ内にコピー
COPY ./container/php/php.ini /usr/local/etc/php/php.ini

# パッケージのインストール
RUN apt-get update \
    && apt-get -y install git zip unzip vim

RUN docker-php-ext-install pdo_mysql

# composerのインストール
RUN cd /usr/bin && curl -s http://getcomposer.org/installer | php && ln -s /usr/bin/composer.phar /usr/bin/composer

# コンテナ内で作業する際のカレンとディレクトリの指定
WORKDIR /var/www/html

2. Laravelプロジェクトの作成

PHPコンテナ内でLaravelのプロジェクトを作成します。

$ docker compose exec php bash
// カレントディレクトリはDockerfileで指定した/var/www/html
$ composer create-project --prefer-dist "laravel/laravel=" .

これで実際のプロジェクトのsrcディレクトリ内にLaravelのソースコードが作成されましたので、http://localhost:8080を開いてみます。

Laravelの初期画面が開きました。
これでPHPサーバーのコンテナが立ち上がり、Laravelのプロジェクトが作成出来ました。

MySQLコンテナの作成

それでは、DBサーバー用のコンテナを立ち上げたいと思います。
各種ファイルを格納するディレクトリを作成します。

$ mkdir db

1. 設定ファイルの作成

MySQLの設定ファイルを作成します。

$ cd db
$ touch my.conf

設定内容は最小限です。

~/container/db/my.conf
[mysqld]
character-set-server=utf8mb4
[client]
default-character-set=utf8mb4

2. Dockerfileの作成

DBコンテナ用のDockerfileを作成します。

$ touch Dockerfile
~/container/db/Dockerfile
# ベースイメージの指定
FROM mysql:8.0

# 作成した設定ファイルをコンテナ内にコピー
COPY ./container/db/my.conf /etc/my.conf

3. docker-composeファイルの書き換え

~/docker-compose.yml
# docker-composeのバージョン
version: "3" 

# コンテナ定義
services:
  # webサーバー
  web:
    # コンテナ名
    container_name: "web"
    # コンテナの作成に使用するDockerfileのパス
    build:
      dockerfile: "./container/web/Dockerfile"
    # ホスト側のポート:コンテナ側のポートを指定
    ports:
      - "8080:80"
    # src配下のファイルをコンテナ内の~/va/www/html配下に配置
    volumes:
      - "./src:/var/www/html"

  # PHPサーバー
  php:
    # コンテナ名
    container_name: "php"
    # コンテナの作成に使用するDockerfileのパス
    build:
      dockerfile: "./container/php/Dockerfile"
    # srcディレクトリ内のファイルをコンテナ内の~/var/www/html配下にマウント
    volumes:
      - "./src:/var/www/html"

  # DBサーバー
  db:
    # コンテナ名
    container_name: "db"
    # コンテナの作成に使用するDockerfileのパス
    build:
      dockerfile: "./container/db/Dockerfile"
    # ホスト側のポート:コンテナ側のポートを指定
    ports:
      - "3306:3306"
    # 環境変数の指定
    environment:
      - "MYSQL_ROOT_PASSWORD=password"
      - "MYSQL_DATABASE=database"
      - "MYSQL_USER=laravel"
      - "MYSQL_PASSWORD=password"
    # srcディレクトリ内のファイルをコンテナ内の~/var/www/html配下にマウント
    volumes:
      - "./container/db/data:/var/lib/mysql"

書き換えたら、再度コンテナを立ち上げます。

$ docker compose up -d --build
[+] Running 4/4
 ⠿ Network sample_default  Created
 ⠿ Container php           Started
 ⠿ Container db            Started
 ⠿ Container web           Started

WebサーバーからDBへの疎通を確認したいと思います。

docker-compose.ymlで指定したMySQLの環境変数をLaravelプロジェクト内の.envファイルに反映させます。

~/src/.env
~ 省略 ~
DB_CONNECTION=mysql
# DBコンテナ名を指定
DB_HOST=db
DB_PORT=3306
DB_DATABASE=database
DB_USERNAME=laravel
DB_PASSWORD=password
~ 省略 ~

書き換えたら、再度コンテナを立ち上げます。

$ docker compose up -d --build

PHPコンテナ内でDBのマイグレーションを行ってみます。

$ docker compose exec php bash
$ php artisan migrate
 INFO  Preparing database.  

  Creating migration table ........................................ 25ms DONE

   INFO  Running migrations.  

  2014_10_12_000000_create_users_table ............................ 34ms DONE
  2014_10_12_100000_create_password_resets_table .................. 24ms DONE
  2019_08_19_000000_create_failed_jobs_table ...................... 27ms DONE
  2019_12_14_000001_create_personal_access_tokens_table ........... 36ms DONE

マイグレーションが成功しました。
正常にDBへの疎通が出来たみたいです。

まとめ

以上でLaravelの環境構築は完了です。

実際に環境を作成することでよりDockerやサーバーなどのインフラ、ミドルウェアについての理解が深まったと思います。

皆さんも環境を自作してみてマイテンプレートを作成してみてはいかがでしょうか?

今回作成したソースコードのリポジトリはこちらです。

Discussion