🐘

[conoha VPSにDocker + Laravel構築①] ベースのcompose.yamlを作成する

に公開

はじめに

Laravelで個人開発中の備忘録です。

conoha VPSにDocker + Laravel構成のローカル開発環境とVPSのdev環境とそのデプロイ機構までを作成していきますので是非ご参考ください🙌

  1. [conoha VPSにDocker + Laravel構築①] ベースのcompose.yamlを作成する (←今ここ)
  2. [conoha VPSにDocker + Laravel構築②] VPSへSSH接続する
  3. [conoha VPSにDocker + Laravel構築③] VPSでコンテナを起動する
  4. [conoha VPSにDocker + Laravel構築④] GitHubActionsでデプロイする
  5. [conoha VPSにDocker + Laravel構築⑤] SSL対応 ※後日予定

今回はベースのcompose.yamlを作成する内容のため、構成図的には以下の①を範囲になります。
(構成図の画像は拡大してご確認いただけます)

環境

実行環境

🐳 コンテナ

  • php 8.2
  • laravel 12

💻 ローカル

  • MacOS 15.4
  • Docker version 24.0.2
  • Docker Compose version v2.19.1

コンテナ構成

今回は以下の構成で進めます。

コンテナ イメージ 用途
db FROM mysql:8 MySQL
phpmyadmin FROM phpmyadmin/phpmyadmin:5 DBクライアント
app FROM php:8.2-apache Laravelの実行環境

appコンテナの補足

シンプルな構成にしておきたいので今回はwebとappは分けず、ホストからの通信をwebコンテナを介さずにappコンテナで受けます。

また、③記事で対応しますが、最終的にはVPSにApacheをインストールしてコンテナへマッピングするため、受けたリクエストをチェックするなどリバースプロキシとしての役割はVPSにApacheをインストールして対応する予定のため、コンテナ側はappのみの構成にしています。

ディレクトリ構成

先にディレクトリ構成を紹介します。

コンテナごとにディレクトリを切ってDockerfileを入れてます。こうしておくとDockerfileに書くことが少ない場合でもcompose.yamlbuildキーの値の書き方が統一できて個人的には見やすいかなと思います。

.
├── compose.yaml
├── docker
│   ├── app
│   │   ├── 000-default.conf
│   │   ├── Dockerfile
│   │   └── php.ini
│   ├── db
│   │   ├── Dockerfile
│   │   └── my.cnf
│   └── phpmyadmin
│       └── Dockerfile
├── README.md
└── src
    └── index.php # Laravelのコードを入れる予定

src/index.phpは動作検証用なので後で消しますが、一旦phpinfoページを返す記述をしておきます。

index.php
<?php
phpinfo();

appコンテナの設定

compose.yaml

compose.yamlは徐々に追加してきますがappコンテナに必要な記述は以下でOKです。

compose.yaml
services:

# ----------------------------------
# Apache + PHP
# ----------------------------------
  app:
    container_name: local_app
    build: ./docker/app
    volumes:
      - ./src:/var/www/html
    ports:
      - 8000:80

docker/app/Dockerfile

主に以下をしてます。

  • Laravelに必要なパッケージ(OSやPHPの拡張モジュール)のインストール
  • composerのインストール
  • ユーザー作成とwww-dataグループへの追加
FROM php:8.2-apache
    #######################
    # Apacheのリダイレクト設定
    #######################
RUN a2enmod rewrite

    #######################
    # Ubuntuのパッケージ
    # -- libxml2-dev : XML処理ライブラリ
    # -- lib*-dev : 画像処理ライブラリ (gd拡張の依存)
    # -- libzip-dev : ZIP圧縮ライブラリ (zip拡張の依存)
    #######################
RUN apt-get update \
    && apt-get install -y \
        git \
        curl \
        vim \
        zip unzip \
        libxml2-dev \ 
        libjpeg-dev libpng-dev libfreetype6-dev \
        libzip-dev \
    ###############################
    # PHP拡張モジュールビルド前の設定
    # -- gd --with-jpeg : JPEG画像処理ライブラリを明示的に有効化しておく必要がある
    ###############################
    && docker-php-ext-configure \
        gd --with-jpeg --with-freetype \
    ###############################
    # 追加するPHP拡張モジュール
    # -- pdo_mysql : MySQLにPDOを使って接続
    # -- mysqli : MySQLi拡張
    # -- zip : ZIPファイルの操作
    # -- intl : 国際化サポート
    # -- bcmath : 任意精度数学演算
    # -- gd : 画像処理
    ###############################
    && docker-php-ext-install \
        pdo_mysql mysqli \
        zip \
        intl \
        bcmath \
        gd

# Composerのインストール
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

# ユーザー作成
ARG UID=1000
ARG USER=dev-user

RUN useradd -G www-data -u ${UID} -d /home/${USER} ${USER}
RUN mkdir -p /home/${USER}/.composer
RUN chown -R ${USER}:${USER} /home/${USER}

USER ${UID}

# php.iniをコンテナへ設置
ADD php.ini /usr/local/etc/php/

Laravel12に必要なPHPの拡張モジュールは、Laravelドキュメントのサーバ要件に記載がありますが、php:8.2インストール時点ですでに含まれている拡張モジュールもあるので差分だけインストールしています。

https://readouble.com/laravel/12.x/ja/deployment.html

php8.2に含まれる拡張モジュールの確認方法
  1. FROM php:8.2-apacheだけ記述してコンテナを実行
  2. docker compose exec app bashでコンテナ内に入りphp -m
結果
[PHP Modules]
Core
ctype
curl
date
dom
fileinfo
filter
hash
iconv
json
libxml
mbstring
mysqlnd
openssl
pcre
PDO
pdo_sqlite
Phar
posix
random
readline
Reflection
session
SimpleXML
sodium
SPL
sqlite3
standard
tokenizer
xml
xmlreader
xmlwriter
zlib

[Zend Modules]

php.ini

[Date]
date.timezone = "Asia/Tokyo"
[mbstring]
mbstring.internal_encoding = "UTF-8"
mbstring.language = "Japanese"

動作確認

コンテナを起動します。

docker compose up --build

http://localhost:8000/にアクセスしてphpinfoページが表示されればOKです。

dbコンテナの設定

compose.yaml

dbコンテナへはphpMyAdmin経由でアクセスするため、ポートマッピングはせず外部から直接のアクセスはできないようにしておきます。

environmentについての補足は以下です。

Head 必須/任意 Head
MYSQL_ROOT_PASSWORD 必須 rootユーザのPW
MYSQL_DATABASE 任意 指定するとDBを自動で作成する
MYSQL_USER 任意 MYSQL_DATABASEで作成したDBへのフル権限ユーザーを作成
MYSQL_PASSWORD 任意 MYSQL_USERのPW

「phpMyAdmin → DB」や「Laravel → DB」へのアクセスユーザーとしてroot以外のadmin(名前は任意)ユーザーを作成しています。

yaml
services:

+ # ----------------------------------
+ # MySQL
+ # ----------------------------------
+   db:
+     container_name: local_db
+     build: ./docker/db
+     restart: always
+     environment:
+       - MYSQL_ROOT_PASSWORD=password
+       - MYSQL_DATABASE=local_db
+       - MYSQL_USER=admin
+       - MYSQL_PASSWORD=password123
+       - TZ=Asia/Tokyo
+     volumes:
+       - local_data:/var/lib/mysql

# ----------------------------------
# Apache + PHP
# ----------------------------------
  app:
    container_name: local_app
    build: ./docker/app
    volumes:
      - ./src:/var/www/html
    ports:
      - 8000:80
+     depends_on:
+       - db


+ # ボリュームの定義
+ volumes:
+   local_data:

https://hub.docker.com/_/mysql

docker/db/Dockerfile

FROM mysql:8

# MySQLの設定
ADD my.cnf /etc/mysql/conf.d/my.cnf

docker/db/my.cnf

[mysqld]
character-set-server=utf8

動作確認

とりあえずコンテナ起動するプロセスでエラーが出てないかだけ確認します。
外からアクセスできないので、DBができているかなどの確認は次のphpMyAdminセクションでします。

docker compose up --build

phpmyadminコンテナの設定

compose.yaml

environmentPMA_HOSTSは前のセクションで作成したMySQLのサービス名(db)を指定します。

yaml
services:

# ----------------------------------
# MySQL
# ----------------------------------
  db:
    container_name: local_db
    build: ./docker/db
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=password
      - MYSQL_DATABASE=local_db
      - MYSQL_USER=admin
      - MYSQL_PASSWORD=password123
      - TZ=Asia/Tokyo
    volumes:
      - local_data:/var/lib/mysql

+ # ----------------------------------
+ # phpMyAdmin
+ # ----------------------------------
+   phpmyadmin:
+     container_name: local_phpmyadmin
+     build: ./docker/phpmyadmin
+     restart: always
+     environment:
+       - PMA_ARBITRARY=1
+       - PMA_HOSTS=db
+     ports:
+       - 8080:80
+     depends_on:
+       - db

# ----------------------------------
# Apache + PHP
# ----------------------------------
  app:
    container_name: local_app
    build: ./docker/app
    volumes:
      - ./src:/var/www/html
    ports:
      - 8000:80
    depends_on:
      - db


# ボリュームの定義
volumes:
  local_data:

docker/phpmyadmin/Dockerfile

FROM phpmyadmin/phpmyadmin:5

動作確認

docker compose up --build

http://localhost:8080/にアクセスしてログインページが表示されます。
「local_db」「admin」「password123」でログインできればOKです。

[Laravel] インストール

ここまででコンテナ環境の構築はできました。
続いてappコンテナに入りLaravelをインストールしていきます。

準備

コンテナ内でLaravelのセットアップをするために以下準備をします。

まずは不要な./src/index.phpを削除しておきます。

(起動してなかったら)コンテナを起動し、appコンテナに入ります。

docker compose up
docker compose exec app bash

ターミナルが以下のように切り替わり/var/www/htmlにいることを確認します。

🤖

dev-user@430156f32511:/var/www/html$

インストール

/var/www/htmlにLaravelをインストールします。

🤖

composer create-project laravel/laravel .

compose.yamlの設定でappコンテナの/var/www/htmlとホスト(ローカルPC)の./srcはバインドマウントしているため、インストールと同時に手元のエディタの./srcの中身にもLaravelのコードが入ってきたと思います。

Apacheのデフォルトルートをpublicに変更

docker/app/000-default.confを以下の内容で作成します。

<VirtualHost *:80>
    DocumentRoot /var/www/html/public
</VirtualHost>

docker/app/Dockerfileに以下を追記し、appコンテナ起動時にのApache設定ファイルを差し替えます。

docker/app/Dockerfile
...略...

# php.iniの設定
ADD php.ini /usr/local/etc/php/

+ # Apacheの設定
+ ADD 000-default.conf /etc/apache2/sites-enabled/

Dockerfileを編集したのでコンテナ起動時にイメージも再ビルドします。

docker compose up --build

動作確認

http://localhost:8000/にアクセスしてLaravelのホーム画面が表示されればOKです。

[Laravel] DB接続

.envファイルのDB関連の値をcompose.yamlで指定した値に変更します。

.env
- DB_CONNECTION=sqlite
- # DB_HOST=127.0.0.1
- # DB_PORT=3306
- # DB_DATABASE=laravel
- # DB_USERNAME=root
- # DB_PASSWORD=
+ DB_CONNECTION=mysql
+ DB_HOST=db
+ DB_PORT=3306
+ DB_DATABASE=local_db
+ DB_USERNAME=admin
+ DB_PASSWORD=password123

.envファイルを編集したのでLaravel側のキャッシュをクリアしておきます。

🤖

php artisan config:clear

マイグレーションをします。

🤖

php artisan migrate

テーブルが作成できればOKです。

[Laravel] .envファイルを暗号化

こちらは必須では無いですが.envの管理がGitHubでできるようになり便利なので以下の対応します。

  • 環境ごとに分ける。
  • 暗号化してGitHubで管理する。

環境ごとに分ける。

アプリケーションの環境変数を読み込む前に、LaravelはAPP_ENV環境変数が外部から提供されているか、もしくは--env CLI引数が指定されているかを判断します。その場合、Laravelは.env.[APP_ENV]ファイルが存在すれば、それを読み込もうとします。存在しない場合は、デフォルトの.envファイルを読み込みます。
https://readouble.com/laravel/12.x/ja/configuration.html

まずは.env.env.localにリネームします。

mv .env .env.local

アプリケーションの環境変数を読み込む前にAPP_ENV環境変数がコンテナにセットされている必要があるためcompose.yamlAPP_ENV環境変数をセットします。

yaml
...省略...
# ----------------------------------
# Apache + PHP
# ----------------------------------
  app:
    container_name: local_app
    build: ./docker/app
    environment:
+      - APP_ENV=local
    volumes:
      - ./src:/var/www/html
    ports:
      - 8000:80
    depends_on:
      - db

これでコンテナを再起動します。

docker compose up --build

.env.localを読むようになっています。

動作確認したい方はこちら
  1. .env.localの先頭のAPP_NAMEAPP_NAME=Laravel-localのように変更。
  2. src/resources/views/welcome.blade.phpの適当な箇所に{{ config('app.name') }}を設置。
  3. Laravel-localと表示されればOK。
    (反映されない場合はコンテナを再起動させるか、🤖php artisan config:clearでキャッシュクリア)

暗号化してGithubで管理する。

アプリケーションを使用する開発者/サーバごとに異なる環境設定が必要になる可能性があるため、.envファイルをアプリケーションのソース管理にコミットしないでください。さらに、機密性の高い資格情報が公開されるため、侵入者がソース管理リポジトリにアクセスした場合のセキュリティリスクになります。

しかしながら、Laravelの組み込みの環境の暗号化を使用して、環境ファイルを暗号化することも可能です。暗号化した環境ファイルは、安全にソース管理下に置けます。
https://readouble.com/laravel/12.x/ja/configuration.html

こちらの対応をします。

暗号化

php artisan env:encrypt --env=local

選択肢が出ますが特に理由がない限りは「Generate a random encryption key」の方でOKです。

暗号化された.env.local.encryptedファイルが出来上がりました。

複合化

暗号化で作成された.env.local.encryptedファイルを元に複合化を試します。

すでに.env.localが存在しているとエラーになるため、まずは.env.localを削除してください。

rm -rf .env.local

復号化キーを指定して実行しすると.env.localができました。

php artisan env:decrypt --env=local --key=base64:ieM6ctDzLBHuBD5GVCMzuCRDEHCPalynsItJl6A+lnw=

.env.localを編集した場合は?

.env.localを編集した場合、再度暗号化して.env.local.encryptedの中身を更新する必要があるため、--forceオプションをつけて暗号化を実行すればOKです。

php artisan env:encrypt --env=local --force

.gitignoreに追加

.env.localはコミットしないのでgitの管理から外します。

.gitignore
+ .env.local

まとめ

今回はローカル開発環境を整えました!
次はconoha VPSへssh接続します。

  1. [conoha VPSにDocker + Laravel構築①] ベースのcompose.yamlを作成する (←今ここ)
  2. [conoha VPSにDocker + Laravel構築②] VPSへSSH接続する (←次を見る)
  3. [conoha VPSにDocker + Laravel構築③] VPSでコンテナを起動する
  4. [conoha VPSにDocker + Laravel構築④] GitHubActionsでデプロイする
  5. [conoha VPSにDocker + Laravel構築⑤] SSL対応 ※後日予定

Discussion