Dockerとコンテナ技術 その19:docker compose 実践 WebAPIサーバーとDBサーバーを作成②

以前の記事で複数コンテナを扱うdocker composeについてまとめました。

キョウタコの技術日記

Docker Composeとは、一度に複数のコンテナを作成・実行できるソフトウェアのことです。Docker内に同梱され…

キョウタコの技術日記

Docker Composeで利用するキーや階層構造の主な記述方法についてまとめていきます。Docker Compose…

キョウタコの技術日記

コンテナの仮想環境が作成できるようになったので、次は起動しているコンテナでの操作を実行できるようにしていきます。今回はコ…

今回の記事ではdocker-compose.yamlを作成し、DBサーバーの立ち上げと初期化までの動作確認を行います。

WebAPIの完成イメージ

今回のWebAPIはAPIサーバーにJavaのSpring Boot、DBサーバーにPostgresSQLを利用して外部からポート8080でAPIサーバーにアクセスし、DBのデータを取得後レスポンスを返すという簡単なものを作成していきます。
イメージとしては以下のようなものを作成していきます。

docker-compose.yamlファイルを作成する

docker-compose.yamlファイルを作成して、そこにAPIサーバーとDBサーバーの情報を記述して、docker composeコマンドで実行できるようにしていきます。
前回作成したwebapiフォルダ直下、spring bootのプロジェクトが格納されているapiフォルダと同じ階層にdocker-compose.yamlファイルを作成しましょう。

webapi
├── api
│   ├── HELP.md
│   ├── build.gradle
│   ....
│
└── docker-compose.yaml

APIサーバーをdocker-compose.yamlで記述する

前回の記事でAPIサーバーのカスタムイメージとsprng bootのプロジェクトは作成したので、docker composeでそれらを起動できるようにファイルに記述していきましょう。
以下のように記述してください。

version: '3.9'
services:
  api:
    build: ./api
    ports:
      - 8080:8080

この記述によって、apiというコンテナを./apiをルートとして作成します。

DBサーバーをdocker-compose.yamlで記述する

次にDBサーバーも記述していきます。
APIサーバーの場合はカスタムイメージやspring bootのプロジェクトを作成する必要がありましたが、DBサーバーの場合はDocker Hub上のイメージを利用するためdocker-compose.yamlにそのまま記述していきます。
以下の記述をdocker-compose.yamlのAPIサーバーの記述の後に追加してください。

  db:
    image: postgres:15
    ports:
      - 5432:5432
    environment: 
      - POSTGRES_PASSWORD=postgres
      - POSTGRES_USER=postgres
      - POSTGRES_DB=appdb
    volumes:
      - db-volume:/var/lib/postgresql/data
      - ./db/initdb:/docker-entrypoint-initdb.d

environmentは環境変数を設定する項目で、volumesは接続するボリュームの設定が行えます。
volumesの最初のdb-volume:/var/lib/postgresql/dataという記述で、db-volumeというボリューム領域のデータを/var/lib/postgresql/dataというファイルにアタッチしています。
次の./db/initdb:/docker-entrypoint-initdb.dという記述で./db/initdbというホストのパスを/docker-entrypoint-nitdb.dにバインドマウントしています。
/docker-entrypoint-nitdb.dはコンテナ起動時に中のSQLを実行するための特殊なフォルダであり、DBの初期化に利用します。

Volume領域の作成

最後にボリューム領域の作成を行います。
以下の記述をdocker-compose.yamlに追加してください。

volumes:
  db-volume:

これにより、db-volumeという名前のボリューム領域が作成されます。

DB初期化用のSQLを作成

docker-compose.yamlの作成が完了したので、DBコンテナ起動時に実行する初期化用のSQLを作成していきましょう。
上記の通り、バインドマウントするホスト側の./db/initdb配下にSQLを作成していきます。

以下のように新規でフォルダ・ファイルを作成してください。

webapi
├── api
│   ├── HELP.md
│   ....
│
├── db
│   └── initdb
│       ├── 1-create-animals.sql
│       └── 2-insert-animals.sql
└── docker-compose.yaml

1-create-animals.sqlでテーブルを作成し、2-insert-animals.sqlで初期データを挿入していきます。

1-create-animals.sqlに記述

animalsというテーブルを作成するためのSQLを1-create-animals.sqlに記述していきます。
以下のように記述してください。

CREATE TABLE animals (
  id SERIAL,
  animal_name VARCHAR(255) NOT NULL,
  cry VARCHAR(255) NOT NULL,
  PRIMARY KEY (id)
);

2-insert-animals.sqlに記述

animalsにデータを挿入するためのSQLを2-insert-animals.sqlに記述していきます。
以下のように記述してください。

INSERT INTO animals (animal_name, cry)
VALUES
  ('dog', 'wang wang'),
  ('cat', 'meow meow'),
  ('cow', 'moo moo'),
  ('sheep', 'baa baa'),
  ('pig', 'oink oink'),
  ('chicken', 'cluck cluck')
;

これで、DBサーバーの初期化の準備が完了しました。

docker composeでDBコンテナだけを起動してみる

DBサーバーだけを起動する

では、今回設定したDBサーバーが正しくできるのかを確認するために、docker composeコマンドを使ってDBサーバーだけを起動してみましょう。
以下のコマンドを実行してください。

docker compose up db -d

実行すると以下のように表示され、コンテナが一つだけ起動しているのがわかります。

では、SQLによる初期化ができているのかも確認してみましょう。
以下のコマンドを実行してください。

docker compose exec db bash

実行後、以下のようにDBコンテナに入ることができます。

psqlコマンドでDBの中身を確認する

psqlコマンドでDBの中身をみていきましょう。
以下のコマンドを実行してpostgresのDBに入ってください。

psql -U postgres

実行後、以下のような表示になると思います。

まずは、\lを入力してデータベースが作成されているかを確認しましょう。
実行後、以下のように表示されappdbというデータベースが作成されているのがわかります。

ではこのappdbに接続します。
\c appdbと入力してください。
以下のように表示されます。

animalsテーブルが作成されているかを確認しましょう。
\dtと入力してください。

animalsテーブルが作成されています。
最後にデータを確認しましょう。
以下のSQLを実行します。

SELECT * FROM animals;

以下のように表示されれば成功です。

以上で、DBサーバーの作成と初期化が設定できていることが確認できました。

まとめ

今回の記事では、docker-compose.yamlの作成とDBサーバーの作成が完了しました。
ここまででAPIサーバーとDBサーバーの準備ができたので、次の記事では2つのサーバーを1つのアプリとして使えるようにしていきます。
ここまで読んでいただきありがとうございました。
それでは、また。