【Docker Compose】今更聞けない、docker-compose.ymlの書き方や仕組み

# はじめに
こんにちは、エンジニア2年目の嶋田です。
まずは、この記事を開いていただきありがとうございます！

先日、先輩に教わりながら環境構築をしていた際に、ymlファイルの役割を教えていただきました。
もっときちんと理解したいと思ったのでここに学んだことをアウトプットしようと思いました。

なので！
今回は、Docker composeで複数コンテナを使用する際に作成するdocker-compose.ymlファイルについて使い方や仕組みをまとめていきたいと思います。
是非、最後までお付き合いください！

# 目次

- [DockerとDocker Composeの違い](#dockerとdocker-composeの違い)
- [Dockerfileとdocker-compose.ymlファイルの違い](#dockerfileとdocker-composeymlファイルの違い)
- [Docker-compose.ymlファイルの基本構造](#docker-composeymlファイルの基本構造)
- [Docker Composeの実行](#docker-composeの実行)
- [最後に](#最後に)


# DockerとDocker Composeの違い
DockerとDocker Composeはコンテナ化技術を使用するためのツールであり、それぞれ異なる役割と用途を持っています。このセクションでは、DockerとDocker Composeの基本的な役割と用途について詳しく説明し、両者の違いとそれぞれの利点について述べます。

## Dockerの役割と用途
Dockerは個々のコンテナを作成、管理、実行するためのツールです。以下はDockerの主な役割と用途です。

- **コンテナの作成**: Dockerはイメージからコンテナを作成し、アプリケーションやサービスを隔離された環境で実行するのに役立ちます。

- **コンテナの管理**: Dockerはコンテナのライフサイクルを管理し、コンテナの起動、停止、削除などの操作を提供します。

- **イメージの管理**: Dockerはアプリケーションの実行に必要なイメージを作成し、保存、共有するための仕組みを提供します。

## Docker Composeの役割と用途
Docker Composeは、複数のコンテナを協調して実行するためのツールであり、Dockerコンテナのオーケストレーションに特化しています。以下はDocker Composeの主な役割と用途です。

- **マルチコンテナアプリケーションの定義**: Docker Composeは複数のコンテナを1つのアプリケーションとしてまとめ、関連するコンテナを協調して実行できるようにします。

- **複数コンテナの連携**: Docker Composeは異なるコンテナ間で通信を確立し、データや情報を共有するための機能を提供します。

- **シンプルな環境設定**: Docker Composeは環境変数やボリュームなどの設定を1つのYAMLファイルにまとめ、管理しやすくします。

## DockerとDocker Composeの違い一覧

| 項目                | Docker                                | Docker Compose                      |
|---------------------|---------------------------------------|------------------------------------|
| コンテナの単位     | 単一コンテナ                           | マルチコンテナ                        |
| 管理単位           | 個別管理                              | グループ管理                           |
| 環境設定の複雑さ | コンテナごとに環境設定を行う         | YAMLファイルに設定をまとめて簡略化  |


## それぞれの利点と選択するときのポイント

**Dockerの利点**:

- 個々のコンテナの管理が必要な場合
- シングルコンテナのアプリケーションを実行する場合
- イメージのビルドと保存が中心の場合

**Docker Composeの利点**:

- 複数のコンテナを協調して実行する必要がある場合
- 関連するコンテナをグループ化して管理したい場合
- マルチコンテナアプリケーションの簡単な設定と管理が必要な場合


# Dockerfileとdocker-compose.ymlファイルの違い

## Dockerfileの役割

Dockerfileの主な役割はDockerイメージを構築することです。以下はDockerfileの役割について詳細に説明します。

- **イメージの構築**: DockerfileはDockerイメージを構築するための指示書です。このファイルには、ベースとなるDockerイメージの指定や、パッケージのインストール、設定ファイルの追加など、イメージの構築手順が記述されます。

- **アプリケーションの設定**: Dockerfileはアプリケーションの設定を含めるために使用されます。これには環境変数の設定、ボリュームのマウント、ポートの公開などが含まれます。

- **イメージのビルド**: DockerfileからDockerイメージをビルドするためには、`docker build`コマンドを使用します。これにより、Dockerfileで指定された手順に従ってイメージが作成されます。このイメージはコンテナではなく、イメージ自体を表します。

## docker-compose.ymlの役割

docker-compose.ymlファイルは、複数のDockerコンテナを協調して管理するための設定ファイルです。以下はdocker-compose.ymlファイルの役割について詳細に説明します。

- **マルチコンテナアプリケーションの定義**: docker-compose.ymlファイルは複数のDockerコンテナを1つのアプリケーションとしてまとめ、コンテナ間の依存関係や設定を定義します。

- **複数コンテナの管理**: docker-compose.ymlファイルにより、複数のコンテナを一括で管理できます。コンテナのビルド、起動、停止、削除などの操作を簡単に行えます。

- **設定の統合**: docker-compose.ymlファイルには、各コンテナの設定情報（例: イメージ、ポート、ボリュームなど）が含まれており、複数のコンテナ間で設定を統合管理できます。

docker-compose.ymlファイルは、`docker-compose`コマンドを使用して複数のコンテナを一括して操作でき、イメージのビルドやコンテナの作成が容易に行えます。これにより、複雑なマルチコンテナ環境を簡単に構築および管理できます。

# Docker-compose.ymlファイルの基本構造
Docker-compose.ymlファイルの書き方について、サンプルを通じて以下の項目を理解していきましょう！！

```yml
version: '3' # (1)

services: # （2）
  web:
    image: nginx:alpine # (3)
    container_name: laravel-web # (4)
    volumes: # (5)
      - ./laravel:/var/www/html
    ports: # (6)
      - "8080:80"
    depends_on: # (7)
      - app
    networks: # (8)
      - laravel

  app:
    image: composer:latest
    container_name: laravel-app
    volumes:
      - ./laravel:/var/www/html
    working_dir: /var/www/html # (9)
    command: ["composer", "install"] # (10)
    networks:
      - laravel

  db:
    image: mysql:5.7
    container_name: laravel-db
    environment: # (11)
      MYSQL_ROOT_PASSWORD: root_password
      MYSQL_DATABASE: laravel_db
      MYSQL_USER: laravel_user
      MYSQL_PASSWORD: laravel_password
    volumes:
      - laravel-db-data:/var/lib/mysql
    networks:
      - laravel

networks: # (12)
  laravel:
    driver: bridge

volumes: # (13)
  laravel-db-data:
```

| 番号　 | 設定項目         | 説明                                                                                      |
|------|--------------------|-------------------------------------------------------------------------------------------|
| (1)  | version            | Docker Composeファイルのバージョン指定。ここではバージョン3を使用しています。         |
| (2)  | services           | サービス（コンテナ）の定義セクション。                                                 |
| (3)  | image              | Dockerイメージを指定して、コンテナを作成します。                                      |
| (4)  | container_name     | コンテナの名前を指定し、一意に識別します。                                           |
| (5)  | volumes            | コンテナとホストマシンのディレクトリを関連付け、データを共有します。               |
| (6)  | ports              | ホストマシンのポートとコンテナのポートをマッピングして、外部からアクセス可能にします。 |
| (7)  | depends_on         | サービス間の依存関係を定義し、Docker Composeが依存関係を管理します。                 |
| (8)  | networks           | サービスが所属するネットワークを指定します。                                          |
| (9)  | working_dir        | コンテナ内の作業ディレクトリを指定します。                                           |
| (10) | command            | コンテナが起動したときに実行するコマンドを指定します。                                |
| (11) | environment        | コンテナ内で使用される環境変数を設定します。                                          |
| (12) | networks           | ネットワークの設定セクションで、ネットワーク「laravel」の設定が行われています。          |
| (13) | volumes            | ボリュームの設定セクションで、ボリューム「laravel-db-data」の設定が行われています。     |


# Docker Composeの実行
Docker Composeを使ってコンテナを操作する方法についてよく使用するコマンドを紹介します。

## （１）up - コンテナ作成・起動
```bash
$ docker-compose up
```

## (2)ps - コンテナ一覧表示
```bash
$ docker-compose ps
```

## (3)logs - ログ表示
```bash
$ docker-compose logs [サービス名]
```
## (4)run - コンテナ作成後、コマンド実行
```bash
$ docker-compose run [サービス名] [コマンド]
```
## (5)exec - コマンド実行
```bash
$ docker-compose exec [サービス名] [コマンド]
```
## (6)down - コンテナの停止
```bash
docker-compose down
```

# 最後に
最後までお付き合いいただきありがとうございました。
大枠はアウトプットできたかなと思っていますが、まだまだ勉強中なので
あとは実際に使用しながら慣れて、理解を深めていきます！
間違っている点などございましたら、遠慮なくご指摘いただければありがたいです🙇‍♂️

# 参考資料

https://docs.docker.jp/v1.9/compose/compose-file.html

https://docs.docker.jp/compose/reference/docker-compose.html

https://o2mamiblog.com/docker-beginner-2/