第4章:Docker Compose

はじめに

Docker Composeは、複数のコンテナを定義・管理するためのツールです。本章では、Compose仕様とInceptionへの適用を学びます。

---

1. Docker Composeの基本

1.1 概要

Docker Compose:
- 複数コンテナのオーケストレーション
- YAMLファイルで定義
- 単一コマンドで全サービス管理

利点:
1. 宣言的な設定
2. 再現可能な環境
3. サービス間の依存関係管理
4. ネットワークの自動作成

1.2 バージョン

# Compose Specification(現行)
# バージョン指定不要(Docker Compose V2)

services:
  nginx:
    image: nginx:alpine

# 旧形式(参考)
version: "3.8"
services:
  nginx:
    image: nginx:alpine

---

2. docker-compose.yml構造

2.1 基本構造

# トップレベルキー
services:    # サービス定義(必須)
networks:    # ネットワーク定義
volumes:     # ボリューム定義
configs:     # 設定ファイル
secrets:     # シークレット

# サービス定義
services:
  service_name:
    image: image_name
    build: ./path
    ports:
      - "8080:80"
    volumes:
      - volume:/path
    environment:
      - VAR=value
    networks:
      - network_name

2.2 サービス設定

services:
  nginx:
    # ビルド設定
    build:
      context: ./requirements/nginx
      dockerfile: Dockerfile
      args:
        - VERSION=1.0

    # イメージ指定(build優先)
    image: nginx:1.25-alpine

    # コンテナ名
    container_name: nginx

    # ホスト名
    hostname: nginx

    # 依存関係
    depends_on:
      - wordpress

    # 再起動ポリシー
    restart: always  # on-failure, unless-stopped

    # ポートマッピング
    ports:
      - "443:443"

    # ネットワーク
    networks:
      - inception

    # ボリューム
    volumes:
      - wordpress_data:/var/www/html

    # 環境変数
    environment:
      - DOMAIN_NAME=${DOMAIN_NAME}
    env_file:
      - .env

---

3. ネットワーク設定

3.1 ネットワーク定義

networks:
  inception:
    driver: bridge
    name: inception
    # ipam:
    #   config:
    #     - subnet: 172.20.0.0/16

services:
  nginx:
    networks:
      - inception
  wordpress:
    networks:
      - inception
  mariadb:
    networks:
      - inception

3.2 サービス間通信

# 同一ネットワーク内では
# サービス名で名前解決可能

services:
  nginx:
    # wordpress:9000 で接続可能
    networks:
      - inception

  wordpress:
    environment:
      - WORDPRESS_DB_HOST=mariadb
      # mariadb:3306 で接続
    networks:
      - inception

  mariadb:
    networks:
      - inception

---

4. ボリューム設定

4.1 ボリューム定義

volumes:
  wordpress_data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /home/${USER}/data/wordpress

  mariadb_data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /home/${USER}/data/mariadb

4.2 マウント方法

services:
  wordpress:
    volumes:
      # Named Volume
      - wordpress_data:/var/www/html

      # Bind Mount(短縮形)
      - ./config:/etc/config:ro

      # Bind Mount(詳細形式)
      - type: bind
        source: ./config
        target: /etc/config
        read_only: true

      # tmpfs
      - type: tmpfs
        target: /tmp

---

5. 環境変数

5.1 設定方法

services:
  mariadb:
    # 直接指定
    environment:
      - MYSQL_ROOT_PASSWORD=secret
      - MYSQL_DATABASE=wordpress

    # 変数展開
    environment:
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}

    # ファイルから読み込み
    env_file:
      - .env
      - .env.local

5.2 .envファイル

# .env
DOMAIN_NAME=login.42.fr
MYSQL_DATABASE=wordpress
MYSQL_USER=wpuser
MYSQL_PASSWORD=wppass123
MYSQL_ROOT_PASSWORD=rootpass123

WP_ADMIN_USER=admin
WP_ADMIN_PASSWORD=admin123
WP_ADMIN_EMAIL=admin@42.fr

# .gitignoreに追加必須

---

6. Inception完全版

6.1 docker-compose.yml

services:
  nginx:
    build:
      context: ./requirements/nginx
      dockerfile: Dockerfile
    container_name: nginx
    ports:
      - "443:443"
    volumes:
      - wordpress_data:/var/www/html:ro
    networks:
      - inception
    depends_on:
      - wordpress
    restart: always

  wordpress:
    build:
      context: ./requirements/wordpress
      dockerfile: Dockerfile
    container_name: wordpress
    volumes:
      - wordpress_data:/var/www/html
    networks:
      - inception
    depends_on:
      - mariadb
    environment:
      - DOMAIN_NAME=${DOMAIN_NAME}
      - WORDPRESS_DB_HOST=mariadb
      - MYSQL_DATABASE=${MYSQL_DATABASE}
      - MYSQL_USER=${MYSQL_USER}
      - MYSQL_PASSWORD=${MYSQL_PASSWORD}
      - WP_TITLE=${WP_TITLE}
      - WP_ADMIN_USER=${WP_ADMIN_USER}
      - WP_ADMIN_PASSWORD=${WP_ADMIN_PASSWORD}
      - WP_ADMIN_EMAIL=${WP_ADMIN_EMAIL}
      - WP_USER=${WP_USER}
      - WP_USER_EMAIL=${WP_USER_EMAIL}
      - WP_USER_PASSWORD=${WP_USER_PASSWORD}
    restart: always

  mariadb:
    build:
      context: ./requirements/mariadb
      dockerfile: Dockerfile
    container_name: mariadb
    volumes:
      - mariadb_data:/var/lib/mysql
    networks:
      - inception
    environment:
      - MYSQL_DATABASE=${MYSQL_DATABASE}
      - MYSQL_USER=${MYSQL_USER}
      - MYSQL_PASSWORD=${MYSQL_PASSWORD}
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
    restart: always

volumes:
  wordpress_data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /home/${USER}/data/wordpress

  mariadb_data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /home/${USER}/data/mariadb

networks:
  inception:
    driver: bridge
    name: inception

---

7. Composeコマンド

7.1 基本操作

# 起動(バックグラウンド)
docker-compose up -d
docker compose up -d  # V2

# ビルドして起動
docker-compose up -d --build

# 停止
docker-compose down

# 停止してボリューム削除
docker-compose down -v

# ログ確認
docker-compose logs
docker-compose logs -f nginx

# サービス状態
docker-compose ps

# コンテナ内でコマンド実行
docker-compose exec nginx sh

7.2 ビルドと再構築

# ビルドのみ
docker-compose build

# 特定サービスのみビルド
docker-compose build nginx

# キャッシュなしでビルド
docker-compose build --no-cache

# 再起動
docker-compose restart
docker-compose restart nginx

---

8. Makefile

8.1 Inception用Makefile

NAME = inception

# データディレクトリ
DATA_PATH = /home/$(USER)/data

all: setup build up

setup:
	@mkdir -p $(DATA_PATH)/wordpress
	@mkdir -p $(DATA_PATH)/mariadb

build:
	@docker-compose -f srcs/docker-compose.yml build

up:
	@docker-compose -f srcs/docker-compose.yml up -d

down:
	@docker-compose -f srcs/docker-compose.yml down

stop:
	@docker-compose -f srcs/docker-compose.yml stop

start:
	@docker-compose -f srcs/docker-compose.yml start

logs:
	@docker-compose -f srcs/docker-compose.yml logs -f

ps:
	@docker-compose -f srcs/docker-compose.yml ps

clean: down
	@docker system prune -af

fclean: clean
	@docker volume rm -f $(docker volume ls -q) 2>/dev/null || true
	@rm -rf $(DATA_PATH)

re: fclean all

.PHONY: all setup build up down stop start logs ps clean fclean re

---

9. depends_onと健全性チェック

9.1 healthcheck

services:
  mariadb:
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s

  wordpress:
    depends_on:
      mariadb:
        condition: service_healthy

9.2 起動順序の保証

services:
  wordpress:
    depends_on:
      mariadb:
        condition: service_healthy
    # または初期化スクリプトで待機

# 初期化スクリプトでの待機例
while ! mysqladmin ping -h"${DB_HOST}" --silent; do
    echo "Waiting for MariaDB..."
    sleep 2
done

---

まとめ

本章で学んだこと:

  • Compose基本: YAMLファイル構造
  • サービス設定: build, image, ports
  • ネットワーク: サービス間通信
  • ボリューム: 永続化設定
  • 環境変数: .envファイル
  • 完全版設定: Inception構成
  • コマンド: up, down, build, logs
  • Makefile: 自動化
  • healthcheck: 起動順序制御

次章では、各サービスの詳細構築を学びます。