Docker compose の使い方 〜備忘録〜

# はじめに

Webエンジニアとして業務することになったため、業務で使用する場面が来たときに
すぐに振り返りができるよう docker compose の使い方をまとめておきます。

# そもそも　Docker Compose　って何 ? 

Docker Compose は複数のDockerコンテナを定義、構成、実行するためのツールです。

環境構築をローカルマシンに依存せず簡単に行えることから、近年の開発現場では、よく利用されています。
Docker そのものの説明はこちらへは含めていません。

Docker Composeは、主にDockerコンテナの複数のインスタンスを定義するために使用され、各コンテナの設定が含まれています。

コンテナイメージ、環境変数、ボリューム、ネットワークなどがComposeファイルに含まれます。
Docker Composeは、複数のコンテナを起動することができ、コンテナ同士の通信も容易に行うことができます。

## Docker Compose を利用するメリット

#### コンテナを定義の簡素化する
Docker Composeファイルを使用すると、複数のコンテナを簡単に定義することができます。各コンテナの設定を一元化し、再利用可能なコードとして扱うことができます。

#### 複数のコンテナを管理しやすい
Docker Composeを使用すると、複数のコンテナを管理することができます。一度に複数のコンテナを起動、停止、再起動できるため、管理が容易になります。

#### 環境構築を自動化できる
Docker Composeを使用すると、複数のコンテナを自動的に起動することができるため、環境構築を自動化することができます。これにより、新しい開発環境を簡単にセットアップすることができます。

これらは Docker Compose を利用する基本的なメリットです。

# Docker Composeの使い方

それでは、Docker Compose　の使い方を学習していきましょう。

:::note warn
Docker Composeを利用するには、事前にインストールする必要があります。
[公式](https://docs.docker.com/compose/install/)へ記載の手順でインストールしておきましょう。
:::

Docker Compose を利用する手順をおおまかにまとめると、以下の3ステップです。

1. Docker Hub　から使用したい環境のイメージがあるか確認
1. Docker Compose / Dockerfile を作成
1. docker compose コマンドでコンテナを起動

### 1. Docker Hub　から使用したい環境のイメージがあるか確認

[DockerHub](https://hub.docker.com/search?q=)から、使用したイメージが存在するかを確認します。
例えば、MySQLを使用する際には、検索バーへMySQLと入力すると
[こちら](https://hub.docker.com/_/mysql)のOfficial Imageを見つけることができます。

主要なソフトウェアや実行環境はimageとして、提供されている場合が多いので、
まずはDocker Hubで検索してみると良いでしょう。


### 2. Docker Compose / Dockerfile を作成

image　を見つけられたら、docker compose / Dockerfile　を準備します。

以下に docker compose の書き方の紹介ようにサンプルを記載します。
（実際に自分が作成したものからは、内容を変えているため以下内容での動作確認はしていません。）

```yaml:docker-compose.yml
# docker compose で使用するバージョンを指定
version: 3.8
# services 配下にアプリケーションを動かすための各要素のこと
# この例では web と db が Serviceとして定義しています。
services:
  web:
    # 使用するimage名を指定する
    image: php:8.2.4-apache-bullseye
    # compose ファイルを実行し、build する時のPathを指定
    build:
    # Docker イメージをビルドする際に使用するDocker ファイルを指定するためのオプション
      context: .
      dockerfile: Dockerfile
    # コンテナを実行するプラットフォームを指定する
    platform: linux/amd64
    # コンテナの名前を定義
    container_name: コンテナ名
    # コンテナへマウントする設定ファイルのPathを指定
    volumes:
      - ./www/:/var/www/html/
    # コンテナがホストシステムと同じ特権を持つか指定
    # image　が信頼できない場合は オプションは指定しないことが推奨される
    # privileged: true
    # Docker イメージを立ち上げる時のポート番号
    # - ホストのポート番号:コンテナのポート番号
    ports:
      - 80:80
    # サービス同士の依存関係を指定
    depends_on:
      - db

  db:
    image: mysql:8.0.32-debian
    platform: linux/x86_64
    # コンテナ内で使用する環境変数を定義することができます
    environment:
      MYSQL_DATABASE: database
      MYSQL_USER: user
      MYSQL_PASSWORD: password
      MYSQL_ROOT_PASSWORD: root
    ports:
      - 330６:3306
    # コンテナを起動した際に実行されるコマンドを定義
    command: mysqld --character-set-server=utf8mb4
    volumes:
      - data:/var/lib/mysql
      # ホストのファイル:コンテナ内のファイルを指定
      # MySQLコンテナが起動した際に、init.sqlファイルがコンテナ内のMySQLサーバによって実行
      - ./db/init.sql:/docker-entrypoint-initdb.d/init.sql

# 名前付きの volume として指定
volumes:
  data:
```

サービス間の通信については、基本的に何も設定せずともデフォルトネットワークで接続できます。
異なるネットワークの docker compose を定義する場合は`networks`オプションを使用します。

```
# 各サービスが属するネットワークを定義
networks:
  network:
    # Docker Engine によって自動的に作成されるブリッジネットワークを使用する
    # ブリッジネットワークは、コンテナ間の通信を可能にするためのデフォルトのネットワークドライバー
    driver: bridge
```

ネットワークは実装が必要になった際に追記することにします。


Dockerfile でよく使用するサンプルを示します。
FROM / RUN / COPY / EXPOSE など基礎的なコマンドの学習用に定義しているだけなので、動作確認はしていません。

```Dockerfile:Dockerfile
# FROM : ベースとなるイメージを指定します
FROM php:8.2.4-apache-bullseye
# RUN : Docker イメージ内でコマンドを実行します
RUN apt-get update && rm /etc/apt/sources.list
# COPY : ファイルやディレクトリをイメージ内にコピーします。
# ホストマシン上のファイルやディレクトリをイメージないにコピーします
COPY index.php /var/www/html/
# EXPOSE : Docker コンテナが外部に公開するポート番号を指定します
EXPOSE 80
# CMD : Dockerコンテナが起動された際に実行されるデフォルトのコマンドを指定します。
# CMDにはコマンドライン引数を追加することができますが、
# Dockerfile内には複数のCMDを指定することができません。
CMD ["apache2ctl", "-D", "FOREGROUND"]
```

なお、docker compose ファイル単体でも、コンテナ自体を稼働させることは可能です。

ただし、定義したコンテナに対して個別に何らかの処理を加える場合は、
コンテナイメージの build をDockerfile 経由で行う、あるいは compose側でコマンドを指定するのいずれかになります。

ここまでの準備ができたら、docker-compose コマンドでコンテナを起動し、必要な操作をおこなっていきます。

### 3. docker compose コマンドでコンテナを起動

コンテナの起動〜削除までによく使用するコマンドを紹介しておきます。

```zsh
# イメージをcacheせずにbuildする
docker compose build --no-cache
# コンテナを起動する
docker compose up -d
# コンテナを削除する
docker compose down
# コンテナのイメージ、ボリュームも含めて完全に削除する
docker compose down --rmi all --volumes

# コンテナへログインして状況を確認したい時
docker compose exec -it service名 コマンド 
# webのコンテナへのログイン時のコマンド例
docker compose exec -it web /bin/bash
# dbコンテナの mysql ログイン時のコマンド例
docker compose exec -it db mysql -u root -p
```

ちなみに、docker 関連のコマンドは長くなってしまうので、エイリアス登録してる方が便利です。

# まとめ

最低限ですが、docker compose ファイルを作成し、環境構築できるようにはなりました。

現状は自分で環境を作れるようになることと、記事のリリースを優先しているため、
現状は基礎の基礎の範囲になりますが、実際に学んだ内容はこの記事へ追記してまとめていきます。

特に、Docker Compose のトラブルシューティング　は時間ができたら追加する予定です。