Docker Compose で Next.js + Go(Gin) + PostgreSQL の開発環境を構築してみた！

# はじめに

こんにちは！
副業で開発者側でDockerを起動させていたので、構築側も学ぼうと思い**Next.js (React 19) + Go(Gin) + PostgreSQL** をまとめて起動できる環境 を作ったので記事にしました。


https://github.com/yaya16888/docker

以下の本を参考にして作成しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3836145/48b19c8d-df19-42b9-8cf9-19deefd24306.png)

---

# 目次

1. [プロジェクト構成](#プロジェクト構成)
2. [技術スタック](#技術スタック)
3. [docker-compose.yml を読む](#docker-composeyml-を読む)
4. [構築ステップ](#構築ステップ)
5. [トラブルシューティング](#トラブルシューティング)
6. [参考リンク](#参考リンク)

---

## プロジェクト構成

```
repo-root/
├─ docker/
│  ├─ go/          # Go 用 Dockerfile
│  ├─ next/        # Next.js 用 Dockerfile
│  └─ db/init.sql  # 初期化スクリプト（任意）
├─ go/             # Gin ソース
│  └─ cmd/api/main.go
├─ next/           # Next.js ソース
├─ .air.toml       # Go ホットリロード設定
├─ docker-compose.yml
├─ .env.sample     # 開発用 ENV 雛形
└─ README.md
```

---

## 技術スタック

| カテゴリ    | 採用技術                                     | メモ                 |
| ------- | ---------------------------------------- | ------------------ |
| フロント    | **Next.js 15 / React 19 / Tailwind CSS** | App Router         |
| API     | **Go 1.22 + Gin**                        | Air v1.48 でホットリロード |
| DB      | **PostgreSQL 16**                        | ボリューム永続化           |
| 開発環境    | **Docker Compose v2**                    | 3 サービス同時管理         |
| ホットリロード | Air / Next.js HMR                        | 保存 👉 即ブラウザ反映      |

---

## docker-compose.yml 

```yaml
services:
  db:
    image: postgres:16
    environment:
      POSTGRES_USER: ${DB_USER}
      POSTGRES_PASSWORD: ${DB_PASS}
      POSTGRES_DB: ${DB_NAME}
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      retries: 5
    volumes:
      - db-data:/var/lib/postgresql/data
    ports: ["5432:5432"]

  api:
    build: { context: ., dockerfile: docker/go/Dockerfile }
    environment:
      DB_DSN: postgres://${DB_USER}:${DB_PASS}@db:5432/${DB_NAME}?sslmode=disable
      JWT_SECRET: ${JWT_SECRET}
    depends_on:
      db: { condition: service_healthy }
    volumes:
      - ./go:/app            # ホットリロード用バインド
    ports: ["8080:8080"]

  web:
    build: { context: ., dockerfile: docker/next/Dockerfile }
    environment:
      NEXT_PUBLIC_API_URL: http://localhost:8080
    depends_on: [api]
    volumes:
      - ./next:/app
    ports: ["3000:3000"]

volumes:
  db-data:
```

* **HealthCheck** で DB 完全起動を待つ → API が確実に接続 OK
* **バインドマウント** でファイル保存 ⇒ コンテナ即反映

---

## 開発者側構築ステップ

| ステップ           | コマンド                                                                               | 解説                      |
| -------------- | ---------------------------------------------------------------------------------- | ----------------------- |
| 1. リポジトリ clone | `git clone git@github.com:yaya16888/docker.git`                                    |                         |
| 2. ENV 準備      | `cp .env.sample .env`                                                              | `DB_USER=lcart` など任意修正可 |
| 3. 起動          | `docker compose up -d`                                                             | 初回のみイメージビルド ⏱️2〜3 分     |
| 4. 動作確認        | <br> `curl localhost:8080/healthz` → `{"status":"ok"}`<br> `http://localhost:3000` | Go & Next.js 両方起動       |

---

## トラブルシューティング

| 症状                              | 原因                  | 解決                                 |
| ------------------------------- | ------------------- | ---------------------------------- |
| `db` が `unhealthy` で API が起動しない | HealthCheck ユーザー不一致 | `pg_isready -U postgres` に変更       |
| `bind: address already in use`  | ポート競合               | 3000/8080/5432 を他プロセス確認            |
| Next.js で “Invalid host header” | dev サーバのホスト設定漏れ     | Dockerfile で `pnpm dev -H 0.0.0.0` |
| ファイル保存しても Go が再起動しない            | volume 未マウント        | `volumes: - ./go:/app` を確認         |

---

## 参考リンク

* Gin + Air Hotreload: [https://github.com/cosmtrek/air](https://github.com/cosmtrek/air)
* Next.js 公式: [https://nextjs.org/docs](https://nextjs.org/docs)
* Postgres HealthCheck Tips: [https://docs.docker.com/engine/reference/builder/#healthcheck](https://docs.docker.com/engine/reference/builder/#healthcheck)
* 完全版リポジトリ: [https://github.com/yaya16888/docker](https://github.com/yaya16888/docker)

---