docker-compose.yamlとDockerfileのまとめ

# はじめに
- この記事では**docker-compose.yamlの使い方**に関してまとめています。具体的には**DockerファイルやImageを使用したコンテナの立ち上げ方**と、その時に使用する**主要なプロパティ**に関してまとめています。

# 目次
1.**Imageを使用してコンテナを立ち上げる**
2.**Dockerfileを使用してコンテナを立ち上げる**
3.**コンテナの立ち上げに際して使用する主なプロパティ**

# Imageを使用してコンテナを立ち上げる
- 基本的にDockerのコンテナはImageを使用すると楽です。以下のように指定します。
```yaml:docker-compose.yaml
  postgres:
    image: postgres:16-alpine
```

このように指定すると指定したコンテナイメージを自動的にDocker上で構築してくれます。ちなみにその時の最新バージョンが自動的に立ち上がります。

# Dockerfileを使用してコンテナを立ち上げる
- 先ほど説明したImageを使用したコンテナの立ち上げ方は公式に用意されたものを使用しています。しかし自分でそのイメージを用意することもできます。それが**Dockerfile**です。
- わざわざ自分でイメージを作成するメリットとしては**柔軟なカスタマイズ性**が挙げられます。例えば**テストの自動化**や**開発者向けオプションや本番環境向けのオプションの切り替えなど切り替えを柔軟にする**ことを設定できます。
### Dockerファイルを使用するときのdocker-compose.yamlはこんな感じ
- 以下は実際に使用していたdocker-compose.yamlファイルです。
```yaml:docker-compose.yaml
  backend:
      build:
        context: ./backend
        dockerfile: Dockerfile.dev
      container_name: backend-dev
      ports:
        - "8080:8080"
      volumes:
        - ./backend:/app        # backend フォルダ丸ごとマウント
      env_file:
        - ./backend/.env
      depends_on:
        - postgres
        - mailhog
```
- ここで[context]はDockerfileがどこに存在しているかを指定しているだけです。そして実際のDockerfileの名称を[dockerfile]の後に置くことで指定しています。
- [volums]でローカルマシンのbackendフォルダをDockerの仮想マシンのappディレクトリに丸ごとマウントしています。
- 上記のようにDockerfileを使用した場合は**docker compose up -d --build**でDockerfileを使用しているコンテナを一度立ち上げる必要があります。

### Dockerfileはこんな感じ
- ここで実際に私が使用していたwebサーバーのバックエンドのDockerfileを紹介します。
```Dockerfile
# Dockerfile.dev
FROM golang:1.24-alpine

# git, bash, ca-certificates, air を一気に
RUN apk add --no-cache git bash ca-certificates \
&& go install github.com/air-verse/air@latest

WORKDIR /app

# 依存を先に解決してキャッシュ
COPY go.mod go.sum ./
RUN go mod download

# air の設定ファイル
COPY .air.toml ./

# ソースは docker-compose のボリュームマウントで ./backend→/app に反映される
ENTRYPOINT ["air", "-c", ".air.toml"]
```

一つずつ解説していきます。
```Dockerfile
# Dockerfile.dev
FROM golang:1.24-alpine
```
- 上記はDockerの仮想コンテナ上でgo言語を使用するために必要なモジュール一式です。これを用いないと何も始まりません。
```Dockerfile
# git, bash, ca-certificates, air を一気に
RUN apk add --no-cache git bash ca-certificates \
&& go install github.com/air-verse/air@latest
```
- 上記は先ほどインストールしたGo 1.24 + Alpineに入っている標準マネージャーであるapkを用いて一度に以下のものをインストールしています。
    - git(モジュール取得用)
    - bash(シェルスクリプト実行用)
    - ca-certificates（HTTPS 通信のための証明書バンドル）
    - air(Go製のホットリロードツール)

```Dockerfile
WORKDIR /app
```
- 以降の命令やコンテナ起動時のカレントディレクトリを/appに設定します。
- この後に登場するCOPYやRUNもこのディレクトリ基準で実行されます

```Dockerfile
# 依存を先に解決してキャッシュ
COPY go.mod go.sum ./
RUN go mod download
```
- 今回は先にローカル環境で開発していることを前提としているので、go.modとgo.sumを先にダウンロードしておいてキャッシュしておきます。

```Dockerfile
# air の設定ファイル
COPY .air.toml ./

# ソースは docker-compose のボリュームマウントで ./backend→/app に反映される
ENTRYPOINT ["air", "-c", ".air.toml"]
```
- ここでairの設定ファイルをイメージにコピーします。
- そしてコンテナ起動時に**air -c air.toml**コマンドを実行することでソースが変更されてもホットリロードができるようにします。

# docker-compose.yamlを構築する上で最低限抑えたいキー
- **image**
    - これがないと始まらない。既存のイメージを指定して起動させます。
    ```yaml:docker-compose.yaml
        image: postgres:16-alpine
    ```

- **depends_on**
    - コンテナの起動順序を指定できます。例えば下記のような記述があれば、postgresというコンテナが立ち上がった後にpgadminが立ち上がります。
    ```yaml:docker-compose.yaml
    pgadmin:
        depends_on:
          - postgres
    ```
    - こうすることで依存関係で発生する問題を解消できます。

- **volumes**
    - ホストとコンテナのファイル共有ができます。
    - 「：」を境に左側がホストのフォルダで右側がコンテナのフォルダです。こうすることで左側のフォルダと右側のフォルダを共有させることができます。
    ```yaml:docker-compose.yaml
        volumes:
        - ./backend:/app        # backend フォルダ丸ごとマウント
    ```

- **env_file**
    - このキーで.envファイルを指定することで、このファイルを読み込んでDockerのコンテナで環境変数として設定してくれます。
    ```yaml:docker-compose.yaml
        env_file:
        - ./backend/.env
    ```

# 終わりに
- 今回はDockerにおける基本的な使用方法をまとめました。しかし、まだまだ奥が深そうな匂いはしています。。。