【Docker使えるようになりたい】【#20 DockerCompose】DBコンテナを使う(DockerComposeで楽に構築)

DockerComposeについて

Dockerを使って複数のコンテナを動かして動作するアプリのことを「マルチコンテナアプリケーション」と呼びます。

今までは、「マルチコンテナアプリケーション」を構築するには、前回の記事のように手動で使用するコンテナに対してコマンドを実行する必要がありました。
しかしコンテナが増えてくるとそれぞれの依存関係や起動・再起動の手間がかかります。

そこで開発されたのが、「DockerCompose」になります。

これを使うことで、1つのファイルに複数のコンテナの依存関係や実行時の細かい設定などをまとめておけるという利点があります。
また、DockerComposeで起動されるコンテナはすべて実行したDockerCompose用のブリッジネットワークに接続されるので、自動で環境を分離することができるようになっています。

前回の記事の内容をDockerComposeを使って効率化する

前回の記事では、Dockerfileとコマンドを駆使してコンテナを手動で実行していました。
以下のリンクの前回の記事の面倒くさい手順を見てから、この記事を読むと、よりDockerComposeの利便性が分かりやすいと思います。

まず、DockerComposeを使うには、専用の「docker-compose.yml」を用意する必要があります。

DockerComposeが担うのは、docker container runなどのコンテナを実行する部分がメインなので、独自イメージを作るような手順は、Dockerfileに記述する必要があります。

とりあえずは、「docker-compose.yml」を中身は空でいいので、プロジェクトフォルダの「ルートディレクトリ」に配置してください。

ソースコードの内容は、前回の記事と同じ内容になります。

今回のフォルダ構成は前回の記事と同じような構成ではありますが、「」がルートディレクトリに出ています。
これは、APIサーバーを作成するときにdocker-compose.ymlDevContaienrを連携させるために外に出しました。

todoApp/
├── docker-compose.yml     <- 追加
├── .devcontainer          <- 移動
   └── devcontainer.json  <- 移動
├── goApi/
│   ├── Dockerfile
│   ├── go.mod
│   ├── go.sum
│   └── main.go
└── pgdb/
    ├── Dockerfile
    └── init.sql

SQLコンテナ管理をDockerComposeで行う

この節で編集するのは、docker-compose.yamlだけになります。
それ以外のpgdbフォルダ内にあるファイルは、前回の記事の使いまわしになるので、この記事から読んでいる方は、前回の記事のコードをコピーして使ってください。

まずは、SQLコンテナだけ実行するためのdocker-compose.ymlを記述していきます。

docker-compose.yml
# docker-composeのバージョン
# もう書かなくてもいい気もする
version: '3.9'
services:
  # サービス名
  pgdb:
    # ビルドしたいDockerfileがあるディレクトリを指定
    build: ./pgdb
    # envファイルのパスを指定
    env_file: ./pgdb/.env
    # ボリュームのバインド先を指定
    volumes:
      - db-volume:/var/lib/postgresql/data
    # ネットワークのバインド先を指定
    networks:
      - db-bridge

# ネットワークの作成
networks:
  db-bridge:

# ボリュームの作成
volumes:
  db-volume:
  • version: Docker Composeファイルのバージョンを指定します。
  • services: 起動するコンテナをサービスと定義しています。
    • pgdb: サービス名(自由に設定可能)。
      • build: イメージをビルドする際のビルドコンテキストを指定します。./pgdbディレクトリ内のDockerfileを使用します。
      • env_file: 環境変数を定義したファイルへのパスを指定します。
      • volumes: ホストとコンテナ間で共有するボリュームを定義します。
      • networks: コンテナが接続するネットワークを指定します。
  • networks: ネットワークを定義します。
    • db-bridge: ブリッジネットワークの名前です。
  • volumes: ボリュームを定義します。
    • db-volume: データを永続化するためのボリュームです。

上記のdocker-compose.ymlは、以下のdockerコマンドを実行したのと同じ意味になります。

# ネットワークの作成
docker network create db-bridge

# ボリュームの作成
docker volume create db-volume

# pgdbサービスのイメージビルド
docker image build -t todoapp_pgdb ./pgdb

# pgdbコンテナの実行
docker container run --name todoapp_pgdb_1 \
  --env-file ./pgdb/.env \
  -v db-volume:/var/lib/postgresql/data \
  --network db-bridge \
  -d \
  todoapp_pgdb

実行

DockerComposeの実行は、DockerComposeがあるディレクトリに移動して、以下のコマンドを実行するだけですべて実行されます。

# コマンド
docker compose up

# デタッチドモードで実行
docker compose up -d

DockerComposeを使った場合に自動で生成される各構成要素の名前は以下のとおりです。

  • イメージ名 : ルートディレクトリ名-サービス名になります。
    • 例 : todoapp-pgdb
  • コンテナ名 : {ルートディレクトリ名}-{サービス名}-{数字}になります。
    • 例 : todoapp-pgdb-1
  • ネットワーク名 : {ルートディレクトリ名}_{ブリッジネットワーク名}
    • 例 : todoapp_db-bridge
  • ボリューム名 : {ルートディレクトリ名}_{ボリューム名}
    • 例 : todoapp_db-volume

停止

止めたい場合は、以下のコマンドを実行するだけで「コンテナの停止」「コンテナの削除」、「生成したネットワークの削除」、などの後片付けをしてくれます。

Volumeは永続化するための領域なのため自動で削除されません。
削除したい場合は、手動で削除する必要があります。

docker compose down

GoAPIサーバーコンテナ管理をDockerComposeで行う

前回の記事ではAPIサーバーの開発のためにDevContainerを使っていたのですが、DockerComposeを使いながらDevContaienrを使う方法をご紹介します。

前提として、DockerComposeからDevContainerを起動することはできません。

しかし、DevContaierからDockerComposeを起動することはできるのでその方法を使おうと考えています。

DevContainerでdocker-compose.yamlの設定を使ってDockerComposeで各コンテナを起動して、指定したコンテナにDevContainerで接続するという方法です。

DevContainerの編集

buildでDockerfileを対象にしてコンテナを生成していたところを、dockerComposeFile、serviceに変更して、DockerComposeをベースにコンテナに接続するように変更しています。

devcontainer.json
{
  "name": "Go DevContainer",
  "dockerComposeFile": "../docker-compose.yml",
  "service": "goapi",
  "workspaceFolder": "/workspace/goApi",
  "customizations": {
    "vscode": {
      "extensions": [
        "golang.go"
      ]
    }
  }
}
  • dockerComposeFile : docker-compose.ymlまだのパスを指定します。
  • service : DevContainerをつなげたいサービス業を指定します。

goApiフォルダ内のDockerfileを変更

既存のFROMはそのままで、コンテナ実行時にtailコマンドを実行して、コンテナがすぐに終了しないようにします。

最初にDockerComposeが動いてからDevContainerで接続するまでの間でコンテナが止まってしまうためです。

Dockerfile
FROM golang:1.23.2

CMD ["tail", "-f", "/dev/null"]

docker-compose.ymlにgoapiサービスを追加

docker-compose.yml
version: '3.9'

services:
  pgdb:
    build: 
      context: ./pgdb
      dockerfile: Dockerfile
    env_file:
      - ./pgdb/.env
    volumes:
      - db-volume:/var/lib/postgresql/data
    networks:
      - db-bridge
  goapi:
    build:
      context: ./goApi
      dockerfile: Dockerfile
    # ポートをバインド
    ports:
      - "8080:8080"
    # バインドマウントは相対を使える
    volumes:
      - ./goApi:/workspace/goApi
    networks:
      - db-bridge
    # データベースコンテナが先に起動しておいてほしい
    depends_on:
      - pgdb

networks:
  db-bridge:

volumes:
  db-volume:

docker-compose.ymlの中であれば、バインドマウントを使う場合の縛りであった絶対パス出ないといけないという縛りを解除する事ができて、相対パスを使うことができる

実行

以下の記事をもとに、.devcontaienrフォルダのあるディレクトリをVSCodeで開いてDevContainerで接続すればデータベースコンテナも自動で起動してくれます。

当然データベースへの接続も、DevContainer実行時に

停止

停止する場合も実行時と同じようにDevContainerの接続を切ると停止できます。

しばらく開発をしない場合は、docker compose downも実行しておくと、きれいな状態で終わらせることができます。

参考

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA