今日はPostgreSQLを用いて,DB通信を行いたい.
まずロードマップとして
1.docker-compose.ymlを作成
2.Docker起動
3.動作確認
このようにすすめていきたい.
1.docker-compose.ymlを作成
そもそもdocker-compose.ymlとは,Docker Composeが読む,複数コンテナをどう起動するかを記述した設定ファイルのこと.言い換えると,アプリ(app)やデータベース(db)のような複数サービスを一つのコマンドで同時に起動できるようにするものだ.
今回は最小構成ということで
services:
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: app
POSTGRES_PASSWORD: app
POSTGRES_DB: appdb
ports:
- "5432:5432"
volumes:
- db_data:/var/lib/postgresql/data
volumes:
db_data:
このように記述した.
内容の解説として,
services:は,起動するコンテナ群の定義
db:は,サービス名(ここではデータベース)
image:は,使用するDockerイメージ名(postgresがイメージ名で,16-alpineがタグ)
environment:は,環境変数を設定(PostgreSQLのユーザー・パスワードなど)
ports:は,ホストポート:コンテナポート(外部アクセス用)のように記述する
volumes:は,データ永続化(コンテナ削除でもDBのデータ保持)をし,db_dataという名前でDockerが自動的にボリュームを作成し管理する.
docker compose upを実行すると,PostgreSQLなどの外部サービスを簡単に立ち上げ,アプリと連携できるようになる.
2.DBコンテナを起動して確認する
プロジェクト直下で
docker compose up -d
を実行する.-dはバックグラウンド実行の意味.
そして起動確認は
docker ps
これでIMAGEの欄に,postgres:16-alpineのコンテナが表示されていればDBコンテナが稼働中である.よって成功した.
また,ログの確認をする,PostgreSQLの初期化は最初の一回だけのみで,それ以降はDockerのボリュームデータにデータが保存されるため,再初期化せずにすぐ起動する.
docker compose logs db | tail -n 10
これで,出力の末尾にdatabase system is ready to accept connectionsが表示されたら起動完了.
これまでは,DBコンテナ単体を正しく起動,確認までを完了させた段階.
3.アプリコンテナを用意して,DBと同時に起動する
まず初めに,Dockerfileとdocker-compose.ymlをルート直下に移動させる.
次に,docker-compose.ymlにappを追加する.
services:
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: app
POSTGRES_PASSWORD: app
POSTGRES_DB: appdb
volumes:
- db_data:/var/lib/postgresql/data
app:
build: .
ports:
- "8080:8080"
depends_on:
- db
volumes:
db_data:
内容の解説だが,
build: .は,Dockerfileのあるディレクトリを指定して,.は,カレントディレクトリを表す.
ports: -"8080:8080"は,左がホスト(自分のPC)側のポートで,右がコンテナ内でGoアプリが使うポートだ.
depends_on: -dbは,appコンテナを起動する前に,dbコンテナを先に起動する指示のこと.これでアプリが起動する前にDBが立ち上がる.
これで,この1ファイルで2コンテナ(アプリ+DB)をまとめて管理できるようになった.
次に起動してみる.
docker compose up --build
これで動作確認をしてみると,failed to solve: failed to compute cache key: failed to calculate checksum of ref ~~~~: "/go.sum": not foundというエラーが出てきた.ビルドのコンテキストとCOPYパス不一致で,go.sumが見つからないとのことだ.Dockerfile内のCOPYのgo.sumとgo.modの参照先がカレントディレクトリになっているので,これをbackend/go.sum,backend/go.mod,また他の部分もbackend/.に変更する.
最終的にこうなる
FROM golang:1.23.0-alpine AS builder
WORKDIR /app
COPY backend/go.mod backend/go.sum .
RUN go mod download
COPY backend/. .
RUN CGO_ENABLED=0 GOOS=linux go build -v -o /app/main .
FROM alpine:latest
COPY --from=builder /app/main /main
EXPOSE 8080
CMD ["/main"]
5行目の右端を./から.に変更した.意味の違いはないが,他と共通化した.
これでcurlを使って見事接続できた.