Docker Composeで開発環境を構築する実践ガイド
Docker Composeを使ってWebアプリの開発環境(Nginx + App + DB)を構築する手順を、実際のdocker-compose.ymlを交えて解説します。
Docker Composeとは
Docker Composeは複数のコンテナをまとめて定義・起動するためのツールです。docker-compose.yml に構成を書いておけば、docker compose up の一発で全コンテナが立ち上がります。
本記事では Nginx(リバースプロキシ)+ Go アプリ + PostgreSQL という典型的な3層構成を例に進めます。
ディレクトリ構成
project/
├── docker-compose.yml
├── nginx/
│ └── default.conf
├── app/
│ ├── Dockerfile
│ └── main.go
└── db/
└── init.sql
docker-compose.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
| version: "3.9"
services:
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: appuser
POSTGRES_PASSWORD: secret
POSTGRES_DB: appdb
volumes:
- db_data:/var/lib/postgresql/data
- ./db/init.sql:/docker-entrypoint-initdb.d/init.sql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U appuser -d appdb"]
interval: 5s
timeout: 5s
retries: 5
app:
build: ./app
environment:
DATABASE_URL: postgres://appuser:secret@db:5432/appdb?sslmode=disable
depends_on:
db:
condition: service_healthy
ports:
- "8080:8080"
nginx:
image: nginx:1.25-alpine
volumes:
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
ports:
- "80:80"
depends_on:
- app
volumes:
db_data:
|
depends_on に condition: service_healthy を使うことで、PostgreSQLが起動してから(pg_isready が通ってから)アプリを起動できます。これがないと、DB接続前にアプリが先に起動してしまい、起動時のマイグレーションが失敗するケースがあります。
Nginxの設定
1
2
3
4
5
6
7
8
9
10
| server {
listen 80;
location / {
proxy_pass http://app:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
|
Compose内のサービスはサービス名でDNS解決できるため、http://app:8080 という指定で通信できます。
アプリのDockerfile
マルチステージビルドでイメージサイズを小さくします。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| # ビルドステージ
FROM golang:1.22-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o server .
# 実行ステージ
FROM alpine:3.19
RUN apk add --no-cache ca-certificates
WORKDIR /app
COPY --from=builder /app/server .
EXPOSE 8080
CMD ["./server"]
|
CGO_ENABLED=0 でCGOを無効にすることで、alpineの最小イメージで動かせる静的バイナリを生成します。
よく使うコマンド
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| # 起動(-d でバックグラウンド)
docker compose up -d
# ログ確認(サービス名省略で全コンテナ)
docker compose logs -f app
# コンテナに入る
docker compose exec app sh
docker compose exec db psql -U appuser -d appdb
# 停止(コンテナとネットワークを削除)
docker compose down
# ボリュームも含めて全削除
docker compose down -v
# 特定サービスだけ再ビルド
docker compose build app
docker compose up -d --no-deps app
|
本番環境との使い分け
開発環境では volumes でソースコードをマウントしてホットリロードを使いたいことが多いです。docker-compose.override.yml を使うと、開発時だけ追加設定を重ねられます。
1
2
3
4
5
6
| # docker-compose.override.yml(開発時のみ自動読み込み)
services:
app:
volumes:
- ./app:/app
command: air # ホットリロードツール
|
本番では docker-compose.prod.yml を別途用意し、-f で明示的に指定します。
1
| docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
|
まとめ
healthcheck + depends_on: condition: service_healthy で起動順序を制御する- Nginxのリバースプロキシ設定でサービス名をDNSとして使う
- マルチステージビルドでイメージを軽量化する
override.yml で開発/本番の設定を分離する
Docker Composeを使えばチームメンバー全員が同じ環境を再現できるため、「自分のマシンでは動く」問題を大幅に減らせます。