【Dockcer】複数のdockerコンテナを使ったdocker-compose.ymlの書き方 

2024年8月4日Docker

docker
ミニマリスト_カミ

kamiです。
TwitterYoutubeもやってます。

今回は複数の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が表示されます

http://localhost:8080

スポンサードサーチ

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ファイルの更新

icon

先ほどは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コンテナの作成

icon

次に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
  1. FROM php:fpm-buster
    • 意味: ベースイメージとして php:fpm-buster を使用します。これは、PHP-FPMを含むDebian Busterベースの公式PHPイメージです。
      役割: この行は、新しいコンテナイメージの基本となる既存のイメージを指定します。このイメージにはPHPとFPM(FastCGI Process Manager)が既にインストールされています。
  2. COPY ./container/php/php.ini /usr/local/etc/php/php.ini
    • 意味: ローカルマシンの ./container/php/php.ini ファイルをコンテナ内の /usr/local/etc/php/php.ini にコピーします。
    • 役割: この行は、カスタムPHP設定ファイルをコンテナに追加します。これにより、デフォルトの設定を上書きして、特定のPHP設定を適用できます。
  3. WORKDIR /var/www/html
    • 意味: コンテナ内の作業ディレクトリを /var/www/html に設定します。
    • 役割: この行は、コンテナ内でコマンドを実行する際のデフォルトのディレクトリを指定します。このディレクトリは、一般的にWebサーバがドキュメントルートとして使用する場所です。

ファイルの作成が終われば、コンテナを再起動かけて、動いているかを確認します。

docker-compose stop
docker-compose up --build

スポンサードサーチ

Laravelプロジェクトの作成

コンテナ名をつける

icon

ここで気づいたと思いますが、アタッチする時の名前が少々面倒ですよね

icon

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でのページが変わります。

http://localhost:8080

プロジェクト作成が行われれば、「src」ディレクリにファイルが追加されます

MySQLコンテナの作成

実際のアプリはデータベースを使用することになると予想できるので、DB用のディレクトリを作成します。

cd container
mkdir db
cd db
icon

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 updateapt-get install -y を使用して、必要なパッケージ(gitunzip)をインストール。
  • 役割: ソースコード管理(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: ブリッジドライバーを使用するバックエンドネットワーク

DockerDocker

Posted by kami