はじめに
前回の記事ではFlowをコンテナ上で動かすためにdockerファイルを作成しました。
今回はDBもコンテナ化させたく、docker-composeで構築をしてみました。
前回のおさらい
前回はWindows上で動かしていたFlowをコンテナ上で動かすための実装をしました。
Dockerfile、エントリーポイント用のシェルスクリプトを作成し、無事にコンテナ上で動かしてスタートページが表示されるのを確認できました。
Project
├ Configuration/
| ├ Settings.yaml
| └ Settings.yaml_forDocker(★)
├ Data/
| ├ Logs/
| ├ Persistent/
| └ Temporary/
├ Docker/
| └ php
| ├ Dockerfile(★)
| └ entrypoint.sh(★)
├ Packages/
| ├ Application/
| ├ Framework/
| └ Libraries/
├ Web/
├ composer.json
├ composer.lock
├ flow
└ flow.bat
# ベースイメージ
FROM php:8.2-cli
# 必要なPHP拡張モジュールをインストール
RUN docker-php-ext-install pdo_mysql
# 作業ディレクトリを設定
WORKDIR /app
# 非rootユーザーを作成
RUN adduser --disabled-password --gecos '' appuser
# アプリケーションコードをコピー
COPY ./ /app
# エントリポイントスクリプトをコピー
COPY ./Docker/php/entrypoint.sh /usr/local/bin/entrypoint.sh
# スクリプトを実行
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
#!/bin/bash
# Data配下のファイルを削除
rm -r /app/Data
# Docker用の設定ファイルに置き換え
rm /app/Configuration/Settings.yaml
cp /app/Configuration/Settings.yaml_forDocker /app/Configuration/Settings.yaml
# 実行できるように権限を変更
chown -R appuser /app
chmod -R 775 /app
# サーバーを起動
su - appuser -c "cd /app ; ./flow server:run --host=0.0.0.0"
前回の問題点
前回はコンテナ上でFlowのHelloWorldが表示されるところまで確認で来ましたが、実は問題があることが後から発覚しました。
ユーザが作成したPHPファイル、具体的にはPackage/Application配下のファイルを読み込むことができず、起動しても作成したAPIにアクセスできなかったのです。
立ち上げたコンテナにdocker execで入り、該当のフォルダを確認したところ、Windows用のシンボリックリンクをコンテナ上にコピーしていたことで、正しい読み込みがなされていなかったのです。
root:/app# ls -l Packages/Application/
total 0
lrwxrwxrwx 1 appuser www-data 87 Jun 11 2024 Neos.Welcome -> /mnt/host/c/Upath/to/your/project/Quickstart/DistributionPackages/Neos.Welcome
root:/app#
root:/app#
root:/app# ls -l Packages/Application/Neos.Welcome/
ls: cannot access 'Packages/Application/Neos.Welcome/': No such file or directory
root@0af32e6443c6:/app#
Windows上ではPackage/Application配下のパッケージはプロジェクト直下のDistributionPackagesのシンボリックリンクとなっています。
そのため、Dockerfileでそのままコピーすると、windowsのリンク先を情報を引き継いでしまい、正しくファイルが読み込まれない原因となってしまいました。
修正 & 実装
以上を踏まえ、この問題の修正とdocker-composeを用いたDBコンテナ化を行っていきます。
docker-compose.yaml
以下のdocker-compose.yamlファイルを作成しました。
このファイルはプロジェクト直下に作成してます。
appのbuildではcontextでこのファイルがおかれているディレクトリ(プロジェクト直下)を指定し、これにより、Dockerfileの相対パスを書き直さなくて良いようにしています。
ちなみに、アプリケーションはバインドマウントしていません。
後述するエントリーポイントのスクリプト内に、プロジェクトの内容を書き換える処理が書いてあるためです。
コードを修正した際はコンテナの再作成が必要になりますが、現状は仕方ないですね、、、
services:
app:
build:
context: .
dockerfile: ./Docker/php/Dockerfile
ports:
- "8082:8081"
db:
image: mysql:8.0.36
volumes:
- db_data3:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: mydatabase
ports:
- "3306:3306"
volumes:
db_data3: {}
エントリーポイント(修正)
続いて、エントリーポイントのスクリプトも修正しました。
#!/bin/bash
# Data配下のファイルを削除
rm -rf /app/Data
# Docker用の設定ファイルに置き換え
rm /app/Configuration/Settings.yaml
cp /app/Configuration/Settings.yaml_forDocker /app/Configuration/Settings.yaml
# (追加)Application配下のファイルをDistributionPackagesの内容で置き換え
rm -f /app/Packages/Application/*
cp -r /app/DistributionPackages/* /app/Packages/Application/
# (追加)Neos.Welcomeの設定ファイルをDocker用に置き換え
rm /app/Packages/Application/Neos.Welcome/Configuration/Settings.yaml
cp /app/Packages/Application/Neos.Welcome/Configuration/Container/Settings.yaml /app/Packages/Application/Neos.Welcome/Configuration/Settings.yaml
# 実行できるように権限を変更
chown -R appuser /app
chmod -R 775 /app
# (追加)データベースマイグレーション
su - appuser -c "cd /app ; ./flow doctrine:update"
# サーバーを起動
su - appuser -c "cd /app ; ./flow server:run --host=0.0.0.0"
前述したPackages/Application配下がシンボリックリンクになってしまう問題ですが、リンク自体を削除した後に、リンク先のディレクトリをコピーしてくることで対応しました。
また、DB接続を伴うために、データベースのマイグレーションを行う記述も追加しています。
Settings.yaml
FlowとDBでコンテナ間通信を行うため、設定ファイルも変更する必要があります。
今まではhostにlocalhostを指定していましたが、docker-composeで定義したコンテナ名を指定しましょう。
Project
└ Packages/
├ Application/
| └ Neos.Welcome
| └ Configuration
| ├ Container
| | └ Settings.yaml(★追加)
| └ Settings.yaml
├ Framework/
└ Libraries/
Neos:
Flow:
persistence:
backendOptions:
driver: 'pdo_mysql'
charset: 'utf8mb4'
host: 'db'
dbname: 'mydatabase'
user: 'root'
password: 'root'
port: '3306'
driverOptions:
1002: 'SET SESSION wait_timeout=5'
動作確認
実装ができたので、コンテナを立ち上げましょう。
docker compose up --build
立ち上がったコンテナに対し、APIリクエストを送ります。
まずは登録APIから。

問題なく動いてそうです!
おわりに
ひとまず構築できたものの、バインドマウントしていないことによる開発者体験はあまりよろしくありません。
何かしら対策は考えたいですが、コンテナの知識をつけないと太刀打ちできなそうなので、もう少し勉強しようと思います。
とはいえ、うまく構築できてよかったです。
ここまでご覧いただきありがとうございました!
