【Dockcer】複数のdockerコンテナを使ったdocker-compose.ymlの書き方
今回は複数のdockerコンテナを使ったdocker-compose.ymlの紹介です。
作成手順
今回は理解を深めるためにも一つずつ順にコンテナの作成を行い、実行確認をしていきますので、ハンズオン形式で行えますので、ぜひ一緒に理解していきましょう。
- Nginxコンテナの作成
- docker-compose.ymlの作成
- dockerコンテナの起動
- Nginxコンテナを実用的に使えるように修正
- default.confの作成
- NginxコンテナのDockerfileの作成
- docker-composeの書き換え
- PHPコンテナの作成
- php.iniの作成
- PHPコンテナ用のDockerfileの作成
プロジェクト作成
まずはdockerを使ったアプリを格納するディレクトリの作成を行います。
mkdir docker-laravel-app
cd docker-laravel-app
スポンサードサーチ
docker-compose.ymlファイルの作成
ディレクトリ内にymlファイルをdocker-compose.ymlファイルを作成します。
touch docker-compose.yml
Nginxコンテナの作成
Nginxコンテナを作っていきます。
nginxとはWebサーバーです。
NGINXコンテナはWebサーバとして機能し、クライアントからのHTTPリクエストを処理します。
- 静的ファイル(例: HTML, CSS, JavaScript, 画像)の配信。
- リバースプロキシとして機能し、PHP-FPMコンテナへのリクエストを転送する。
- ロードバランシングやキャッシュなどの機能を提供する。
ymlファイルにNginxの作成記述を行います。
version: "3"
services:
web:
image: "nginx:latest"
ports:
- "8080:80"
コンテナの起動
Nginxコンテナを作る準備ができたら、コンテナを立ち上げます。
docker-compose up
以下のようにログが表示されれば、コンテナが起動しています。
[+] Running 1/1
⠿ Container docker-laravel-app-web-1 Created
自身で作成したポート番号にアクセスすれば、ローカルでNginxが表示されます
スポンサードサーチ
Nginxコンテナを実用的に使えるように修正
containerディレクトリとWebコンテナの作成
containerディレクトリ配下にNginxコンテナで使用するディレクトリの作成を行います。
mkdir container
cd container
mkdir web
現時点では以下のプロジェクト構造になっています
├── container
│ └── web
├── docker-compose.yml
default.confの作成
default.confとはアプリケーションやサービスのデフォルト設定を定義するための構成ファイルです。
cd web
touch default.conf
default.confの記述
container/web/default.conf
server {
listen 80; # IPv4のポート80で待機
listen [::]:80; # IPv6のポート80で待機
root /var/www/html/public; # ドキュメントルートディレクトリを設定
add_header X-Frame-Options "SAMEORIGIN"; # クリックジャッキング防止
add_header X-Content-Type-Options "nosniff"; # MIME タイプのスニッフィング防止
index index.php; # デフォルトのインデックスファイルを設定
charset utf-8; # 文字セットをUTF-8に設定
location / {
try_files $uri $uri/ /index.php?$query_string; # ファイルを試してなければ index.php に渡す
}
location = /favicon.ico { access_log off; log_not_found off; } # favicon.ico のログを無効にする
location = /robots.txt { access_log off; log_not_found off; } # robots.txt のログを無効にする
error_page 404 /index.php; # 404エラーをindex.php にリダイレクト
location ~ \.php$ {
fastcgi_pass php:9000; # PHPリクエストをPHPコンテナに渡す
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; # スクリプトのファイル名を設定
include fastcgi_params; # デフォルトのFastCGIパラメータを含む
}
location ~ /\.(?!well-known).* {
deny all; # 隠しファイルへのアクセスを拒否(.well-known を除く)
}
}
Dockerfileの作成
Nginxコンテナを起動する用のDockerfileを作成します。
touch Dockerfile
Dockerfileの記述
container/web/Dockerfile
作成したDockerfileにNginxコンテナ用の記述を行なっていきます
# AlpineベースのNginxイメージを使用
FROM nginx:stable-alpine
# 作成したNginxの設定ファイルをコンテナ内にコピー
COPY ./container/web/default.conf /etc/nginx/conf.d/default.conf
docker-compose.ymlファイルの更新
先ほどはNginxのみの起動でしたが、今回はphpコンテナ追加ののため、docker-compose.ymlファイルを更新します
version: "3"
services:
# PHP-FPMベースのイメージ
php:
image: php:7.4-fpm
volumes:
- "./src:/var/www/html" # PHPアプリケーションのソースコードをマウントするなど、適宜設定
networks:
- backend # 同じネットワークを共有することで、NGINXから接続できるようにする
# NGINXコンテナの定義
web:
container_name: "web"
build:
dockerfile: "./container/web/Dockerfile"
ports:
- "80:80"
volumes:
- "./src:/var/www/html"
depends_on:
- php # NGINXが起動する前にPHP-FPMが起動するように依存関係を設定する
networks:
- backend
networks:
backend: # バックエンド用の共有ネットワークを定義
dockerコンテナを立ち上げ直します。
docker-compose stop
docker-compose up --build
rootにファイルがないため、「File not Found.」と表示されますがこれは正しい挙動なので問題ありません。
tree
現時点でのプロジェクト構造のは以下のようになっています
kami@kami docker-laravel-app % tree
.
├── container
│ └── web
│ ├── Dockerfile
│ └── default.conf
├── docker-compose.yml
└── src
PHPコンテナの作成
次にphpコンテナを作成します
cd container
mkdir php
cd php
touch php.ini
PHPコンテナでは、PHPアプリケーションの処理を担当します。
- PHPコードを実行する。
- PHPアプリケーションの依存関係を管理する(例: Composerを使用してライブラリをインストール)。
- NGINXコンテナからのリクエストに応じてPHPスクリプトを実行し、その結果を返す。
php.iniの作成
php.iniとは、PHPの動作や挙動を制御するための設の設定ファイルです。
[Date]
date.timezone = "Asia/Tokyo" # タイムゾーンを東京に設定
[mbstring]
mbstring.internal_encoding = "UTF-8" # 内部エンコーディングを UTF-8 に設定
mbstring.language = "Japanese" # 言語を日本語に設定
Dockerfileの作成
PHPコンテナ用のDockerfileを作成します。
touch Dockerfile
Dockerfileは、PHP-FPMを実行するためのコンテナイメージを作成する手順を定義しています。
# PHPのベースイメージ
FROM php:fpm-buster
# 作成した設定ファイル(php.ini)をコンテナ内にコピー
COPY ./container/php/php.ini /usr/local/etc/php/php.ini
# コンテナ内で作業ディレクトリを設定
WORKDIR /var/www/html
- FROM php:fpm-buster
- 意味: ベースイメージとして php:fpm-buster を使用します。これは、PHP-FPMを含むDebian Busterベースの公式PHPイメージです。
役割: この行は、新しいコンテナイメージの基本となる既存のイメージを指定します。このイメージにはPHPとFPM(FastCGI Process Manager)が既にインストールされています。
- 意味: ベースイメージとして php:fpm-buster を使用します。これは、PHP-FPMを含むDebian Busterベースの公式PHPイメージです。
- COPY ./container/php/php.ini /usr/local/etc/php/php.ini
- 意味: ローカルマシンの ./container/php/php.ini ファイルをコンテナ内の /usr/local/etc/php/php.ini にコピーします。
- 役割: この行は、カスタムPHP設定ファイルをコンテナに追加します。これにより、デフォルトの設定を上書きして、特定のPHP設定を適用できます。
- WORKDIR /var/www/html
- 意味: コンテナ内の作業ディレクトリを /var/www/html に設定します。
- 役割: この行は、コンテナ内でコマンドを実行する際のデフォルトのディレクトリを指定します。このディレクトリは、一般的にWebサーバがドキュメントルートとして使用する場所です。
ファイルの作成が終われば、コンテナを再起動かけて、動いているかを確認します。
docker-compose stop
docker-compose up --build
スポンサードサーチ
Laravelプロジェクトの作成
コンテナ名をつける
ここで気づいたと思いますが、アタッチする時の名前が少々面倒ですよね
container_nameをつけることで、アタッチがわかりやすくなりました
container_name: php
container_name: web
PHPコンテナのDockerfineの作成
必要なパッケージとcomposerをPHPコンテナ内でインストールします。
# PHP 7.4 FPM (FastCGI Process Manager)
# PHP-FPMベースのイメージを使用
FROM php:7.4-fpm
# 必要なパッケージをインストールし、キャッシュをクリア
# Git をインストール
# unzip をインストール
# パッケージリストのキャッシュを削除
RUN apt-get update && apt-get install -y \
git \
unzip \
&& rm -rf /var/lib/apt/lists/*
# Composer をインストール
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
# 作成した設定ファイル(php.ini)をコンテナ内にコピー
COPY ./container/php/php.ini /usr/local/etc/php/php.ini
# コンテナ内で作業ディレクトリを設定
WORKDIR /var/www/html
# ストレージとキャッシュディレクトリを作成し、その所有権を www-data ユーザーに変更
RUN mkdir -p /var/www/html/storage /var/www/html/bootstrap/cache && \
chown -R www-data:www-data /var/www/html/storage /var/www/html/bootstrap/cache
docker-compose.ymlファイルの更新
version: "3"
services:
php:
container_name: "php" # PHPコンテナの名
build:
context: . # ビルドコンテキストを設定
dockerfile: ./container/php/Dockerfile # PHP用Dockerfileを指定
volumes:
- "./src:/var/www/html" # ソースコードディレクトリをマウント
networks:
- backend # バックエンドネットワークに接続
web:
container_name: "web" # Nginxコンテナの名
build:
dockerfile: "./container/web/Dockerfile" # Nginx用Dockerfileを指定
ports:
- "8080:80" # ホストのポート8080をコンテナのポート80にマッピング
volumes:
- "./src:/var/www/html" # ソースコードディレクトリをマウント
depends_on:
- php # PHPサービスが開始されるまで待機
networks:
- backend # バックエンドネットワークに接続
networks:
backend: # バックエンドネットワークを定義
Laravelプロジェクトの作成
PHPコンテナ内でLaravelのプロジェクトを作成するようにします。
phpコンテナにアタッチしてcomposerを使ってLaravelのアプリを作成します。
カレントディレクトリはDockerfileで指定した「/var/www/html」です。
docker exec -it php bash
composer create-project --prefer-dist "laravel/laravel=" .
composerでプロジェクトが成功すれば、localhostでのページが変わります。
プロジェクト作成が行われれば、「src」ディレクリにファイルが追加されます
MySQLコンテナの作成
実際のアプリはデータベースを使用することになると予想できるので、DB用のディレクトリを作成します。
cd container
mkdir db
cd db
MySQLの設定ファイルを作成します。
touch my.conf
confにはMySQLサーバーの設定とMySQLクライアントの設定を記述しています
- [mysqld] セクション:MySQLサーバーの設定を定義します。
- character-set-server=utf8mb4:サーバーのデフォルトの文字セットをUTF-8MB4に設定します。これにより、新しく作成されるデータベースやテーブルはUTF-8MB4でエンコードされます。
- [client] セクション:MySQLクライアントの設定を定義します。
- default-character-set=utf8mb4:クライアントが接続する際のデフォルトの文字セットをUTF-8MB4に設定します。これにより、クライアントがサーバーに接続するときにUTF-8MB4でデータを送受信することが保証されます。
docker-compose.ymlファイルの更新
dbコンテナを追加するために、docker-compose.ymlファイルの更新します
version: "3"
services:
php:
container_name: php # PHPコンテナの名
build:
context: . # ビルドコンテキストを設定
dockerfile: ./container/php/Dockerfile # PHP用Dockerfileを指定
volumes:
- ./src:/var/www/html # ソースコードディレクトリをマウント
networks:
- default # バックエンドネットワークを default ネットワークに変更
- backend # バックエンドネットワークに接続
web:
container_name: web # Nginxコンテナの名
build:
dockerfile: ./container/web/Dockerfile # Nginx用Dockerfileを指定
ports:
- 8080:80 # ホストのポート8080をコンテナのポート80にマッピング
volumes:
- ./src:/var/www/html # ソースコードディレクトリをマウント
depends_on:
- php # PHPサービスが開始されるまで待機
- db # dbサービスが開始されるまで待機
networks:
- backend # バックエンドネットワークに接続
db:
container_name: db # コンテナ名
build:
dockerfile: ./container/db/Dockerfile # コンテナの作成に使用するDockerfileのパス
ports:
- 3306:3306 # ホスト側のポート:コンテナ側のポートを指定
environment:
- MYSQL_DATABASE:database # 環境変数の指定
- MYSQL_ROOT_PASSWORD:password # 環境変数の指定
- MYSQL_USER:laravel # 環境変数の指定
- MYSQL_PASSWORD:password # 環境変数の指定
volumes:
- ./container/db/data:/var/lib/mysql # srcディレクトリ内のファイルをコンテナ内の~/var/www/html配下にマウント
networks:
- default # デフォルトネットワークに接続
- backend # バックエンドネットワークに接続
networks:
default: # デフォルトネットワークを定義
driver: bridge
backend: # バックエンドネットワークを定義
driver: bridge
docker-compose.ymlファイルの更新が終われば、コンテナの再起動をしてください。
.envの設定
「.env」 ファイルでデータベースの接続先の設定を行います。
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=database
DB_USERNAME=laravel
DB_PASSWORD=password
コンテナを立ち上げ直す
ここまで行えば設定は終了なので、コンテナを一から作り直しておきます。
docker-compose down
doxker-compose up --build
dbコンテナが作成されれば、dataディレクトリが作成されます。
設定は以上になります
まとめ
まとめではDockerfileとdocker-compose.yamlの要約をしています
Dockerfileのまとめ
# PHP 7.4 FPM (FastCGI Process Manager)
# PHP-FPMベースのイメージを使用
FROM php:7.4-fpm
# 必要なパッケージをインストールし、キャッシュをクリア
# Git をインストール
# unzip をインストール
# パッケージリストのキャッシュを削除
RUN apt-get update && apt-get install -y \
git \
unzip \
&& rm -rf /var/lib/apt/lists/*
# Composer をインストール
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
# 作成した設定ファイル(php.ini)をコンテナ内にコピー
COPY ./container/php/php.ini /usr/local/etc/php/php.ini
# コンテナ内で作業ディレクトリを設定
WORKDIR /var/www/html
# ストレージとキャッシュディレクトリを作成し、その所有権を www-data ユーザーに変更
RUN mkdir -p /var/www/html/storage /var/www/html/bootstrap/cache && \
chown -R www-data:www-data /var/www/html/storage /var/www/html/bootstrap/cache
ベースイメージ
php:7.4-fpm
イメージを使用。- 役割: PHP 7.4 FPM (FastCGI Process Manager) をベースとした環境を提供。
パッケージのインストール
apt-get update
とapt-get install -y
を使用して、必要なパッケージ(git
とunzip
)をインストール。- 役割: ソースコード管理(Git)やアーカイブの解凍(unzip)に必要なツールを追加。
- キャッシュをクリアするために、
rm -rf /var/lib/apt/lists/*
を実行。
Composerのインストール
- Composer(PHPの依存管理ツール)をインストール。
curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
コマンドを使用。- 役割: PHPパッケージの管理と依存関係の解決を容易にするため。
設定ファイルのコピー
- ローカルの
php.ini
設定ファイルをコンテナ内の適切なディレクトリにコピー。 COPY ./container/php/php.ini /usr/local/etc/php/php.ini
- 役割: カスタマイズされたPHP設定をコンテナに適用。
作業ディレクトリの設定
WORKDIR /var/www/html
- 役割: コンテナ内のデフォルト作業ディレクトリを設定。
ディレクトリの作成と所有権の変更
mkdir -p /var/www/html/storage /var/www/html/bootstrap/cache
でディレクトリを作成。chown -R www-data:www-data /var/www/html/storage /var/www/html/bootstrap/cache
で所有権を変更。- 役割: Laravelアプリケーションのストレージとキャッシュディレクトリの作成と適切な権限の設定。
docker-compose.yamlのまとめ
version: "3"
services:
php:
container_name: php # PHPコンテナの名
build:
context: . # ビルドコンテキストを設定
dockerfile: ./container/php/Dockerfile # PHP用Dockerfileを指定
volumes:
- ./src:/var/www/html # ソースコードディレクトリをマウント
networks:
- default # バックエンドネットワークを default ネットワークに変更
- backend # バックエンドネットワークに接続
web:
container_name: web # Nginxコンテナの名
build:
dockerfile: ./container/web/Dockerfile # Nginx用Dockerfileを指定
ports:
- 8080:80 # ホストのポート8080をコンテナのポート80にマッピング
volumes:
- ./src:/var/www/html # ソースコードディレクトリをマウント
depends_on:
- php # PHPサービスが開始されるまで待機
- db # dbサービスが開始されるまで待機
networks:
- backend # バックエンドネットワークに接続
db:
container_name: db # コンテナ名
build:
dockerfile: ./container/db/Dockerfile # コンテナの作成に使用するDockerfileのパス
ports:
- 3306:3306 # ホスト側のポート:コンテナ側のポートを指定
environment:
- MYSQL_DATABASE:database # 環境変数の指定
- MYSQL_ROOT_PASSWORD:password # 環境変数の指定
- MYSQL_USER:laravel # 環境変数の指定
- MYSQL_PASSWORD:password # 環境変数の指定
volumes:
- ./container/db/data:/var/lib/mysql # srcディレクトリ内のファイルをコンテナ内の~/var/www/html配下にマウント
networks:
- default # デフォルトネットワークに接続
- backend # バックエンドネットワークに接続
networks:
default: # デフォルトネットワークを定義
driver: bridge
backend: # バックエンドネットワークを定義
driver: bridge
PHPコンテナ
PHPアプリケーションの実行環境を提供します。
ビルド設定
- コンテキスト: カレントディレクトリ
- Dockerfile: ./container/php/Dockerfile
ボリューム
- ./src をコンテナ内の /var/www/html にマウント
ネットワーク
- default ネットワークおよび backend ネットワークに接続
Webコンテナ
Nginxウェブサーバーとして機能し、クライアントからのHTTPリクエストを処理
ビルド設定
- Dockerfile:
./container/web/Dockerfile
ポートマッピング
- ホストのポート
8080
をコンテナのポート80
にマッピング
ボリューム
./src
をコンテナ内の/var/www/html
にマウント
依存関係
- php サービスおよび db サービスが開始されるまで待機する
ネットワーク
- backend ネットワークに接続する
DBコンテナ
データベースサーバーとして機能し、データの永続化を担当する
ビルド設定
- Dockerfile: ./container/db/Dockerfile
ポートマッピング
ホストのポート 3306 をコンテナのポート 3306 にマッピング
環境変数
環境変数は「.env」に記述します。
- MYSQL_DATABASE=database
- MYSQL_ROOT_PASSWORD=password
- MYSQL_USER=laravel
- MYSQL_PASSWORD=password
ボリューム
- ./container/db/data をコンテナ内の /var/lib/mysql にマウント
ネットワーク
default ネットワークおよび backend ネットワークに接続
- default: ブリッジドライバーを使用するデフォルトネットワーク
- backend: ブリッジドライバーを使用するバックエンドネットワーク