はじめに
前回の【モダンWeb開発 シリーズ 第1回】では、Docker DesktopとVS Code Dev Containersを利用して、Windows 11上にGoの開発環境を構築しました。
今回はその構成をさらに発展させ、ショッピングサイトをはじめとしたWebアプリケーション開発に利用できる、React + TypeScript + Go + PostgreSQLによるフルスタック開発環境を構築します。
Frontend
├─ React
├─ TypeScript
├─ Node.js
├─ npm
└─ Vite
Backend
└─ Go
Database
└─ PostgreSQL
開発環境にはVS Code Dev Containersを利用します。
Windows側へGoやNode.jsを直接インストールして開発するのではなく、アプリケーション開発に必要なGoとNode.jsをDevelopment Containerへ用意します。
また、本連載でショッピングサイトの実装やテストに利用するCodex CLIもDevelopment Container内へ導入します。CodexをWindows側ではなくDocker上のDevelopment Container内で動作させることで、CodexからGo、Node.js、プロジェクトファイルへ直接アクセスできる構成にします。
PostgreSQLはアプリケーション開発コンテナとは分離し、Docker Composeで別コンテナとして起動します。
今回の全体像は次のようになります。
本記事では、環境を作成するだけではなく、
React + TypeScript
↓
ブラウザ表示確認
Go
↓
REST API起動確認
PostgreSQL
↓
DB起動・接続確認
まで実施します。
前回の記事では、Docker Desktop、VS Code Dev Containers、Go Development Containerの基本的な仕組みを詳しく解説しています。本記事では、それらが利用できることを前提に、フルスタック開発環境へ発展させます。
この記事で分かること
- React / TypeScript / Node.js / npm / Viteの関係
- GoとNode.jsを同じDevelopment Containerで利用する方法
- PostgreSQLを別コンテナとして起動する理由
- Docker Composeを使った複数コンテナ開発環境
- React + TypeScriptプロジェクトの作成方法
- Vite開発サーバーの起動方法
- Go REST APIの起動方法
- PostgreSQLの起動・接続確認方法
- Windows側へGoやNode.jsを直接インストールしない開発構成
- Codex CLIをDevelopment Container内へインストールする方法
- CodexをDocker上のDevelopment Container内で起動する方法
- VS Codeを終了した後に開発環境を再開する方法
今回利用する技術
今回利用する主なツール・技術を整理します。
| 分類 | Tool / 技術 | 役割 |
|---|---|---|
| OS | Windows 11 | ホストOS |
| Editor | Visual Studio Code | ソースコード編集 |
| Container | Docker Desktop | Dockerコンテナ実行環境 |
| Development | Dev Containers | DockerコンテナをVS Code開発環境として利用 |
| Frontend Runtime | Node.js | React / Viteなどを実行 |
| Package Manager | npm | JavaScript / TypeScriptのパッケージ管理 |
| Frontend | React | UI構築 |
| Language | TypeScript | 型を利用したフロントエンド開発 |
| Build Tool | Vite | React開発サーバー・ビルド |
| Backend | Go | REST API |
| Database | PostgreSQL | 商品・ユーザー・注文などのデータ管理 |
| Container Definition | Docker Compose | appとdbの複数コンテナ管理 |
| Version Control | Git | ソースコード管理 |
| AI Development | Codex CLI | Development Container内で実装・テスト・修正を実行 |
React・TypeScript・Node.js・npm・Viteの関係
Reactを初めて利用する場合、
React
TypeScript
Node.js
npm
Vite
の関係が分かりにくいかもしれません。
今回の構成では、おおまかに次の関係になります。
Node.js
│
└─ npm
│
└─ Vite
│
└─ React + TypeScript
Node.js
Node.jsはJavaScriptをブラウザ以外でも実行するための実行環境です。
Reactの開発では、開発サーバーやビルドツールなどを動かすためにNode.jsを利用します。
npm
npmはNode.jsのパッケージ管理ツールです。
ReactやViteなどのパッケージをインストール・管理するときに利用します。
npm install
などのコマンドを実行します。
React
ReactはWeb画面をコンポーネント単位で構築するために利用します。
今回のショッピングサイトでは、将来的に次のような画面を作成します。
React
│
├─ 商品一覧
├─ 商品詳細
├─ ログイン
├─ カート
└─ 注文画面
TypeScript
TypeScriptはJavaScriptへ型の仕組みを追加した言語です。
例えば商品の型を次のように定義できます。
type Product = {
id: number
name: string
price: number
}
Reactと組み合わせることで、データ構造を明確にしながら開発できます。
Vite
Viteはフロントエンド開発で利用するビルドツールです。
今回はViteを利用してReact + TypeScriptプロジェクトを作成し、開発サーバーを起動します。
構成を整理すると、
Node.js
↓
npm
↓
Vite
↓
React + TypeScript
↓
ブラウザ
となります。
なぜPostgreSQLは別コンテナにするのか
Go、Node.js、PostgreSQLを1つのコンテナへすべて入れることも技術的には可能ですが、今回は分離します。
Docker Compose
│
├─ app
│ ├─ Go
│ ├─ Node.js
│ └─ Codex CLI
│
└─ db
└─ PostgreSQL
アプリケーション開発環境とデータベースを分けることで、それぞれの役割が明確になります。
app
↓
ソースコードの編集・実行・ビルド・テスト
db
↓
データの保存
今後、Go APIからPostgreSQLへ接続する場合も、
Go API
│
│ PostgreSQL接続
▼
db:5432
のように、Docker Composeのサービス名 db を接続先として利用できます。
前提条件
今回は次の環境を前提とします。
- Windows 11
- Docker Desktopが起動している
- Visual Studio Codeがインストール済み
- VS Code Dev Containers拡張機能がインストール済み
- PowerShellが利用できる
Windows側へGo SDKやNode.jsを直接インストールしている必要はありません。
今回の構成では、Go、Node.js、Codex CLIをDevelopment Container内で利用します。
Docker Desktopの動作確認
PowerShellを開き、次を実行します。
docker --version
Docker Composeも確認します。
docker compose version
バージョンが表示されれば利用できます。
プロジェクトの作成
今回は次のフォルダにプロジェクトを作成します。
C:\work\shopping-site
PowerShellで実行します。
cd C:\work
mkdir shopping-site
cd shopping-site
VS Codeで開きます。
code .
最初は次の状態です。
shopping-site
プロジェクト全体の構成
最終的には次の構成を作成します。
shopping-site
│
├─ .devcontainer
│ └─ devcontainer.json
│
├─ .env
├─ .env.example
├─ .gitignore
│
├─ frontend
│ ├─ src
│ ├─ package.json
│ └─ ...
│
├─ backend
│ ├─ go.mod
│ └─ main.go
│
├─ compose.yml
└─ README.md
DB接続情報を.envで管理する
続いて、PostgreSQLの接続情報をプロジェクトルートの .env で管理します。
プロジェクトルートに、
.env
を作成します。
POSTGRES_DB=shop
POSTGRES_USER=appuser
POSTGRES_PASSWORD=apppass
DATABASE_URL=postgres://appuser:apppass@db:5432/shop?sslmode=disable
TEST_DATABASE_URL=postgres://appuser:apppass@db:5432/shop?sslmode=disable
POSTGRES_DB、POSTGRES_USER、POSTGRES_PASSWORD はPostgreSQLコンテナの初期設定に利用します。
DATABASE_URL は通常のGo BackendからPostgreSQLへ接続するための設定です。
TEST_DATABASE_URL は後続の記事でRepository TestやIntegration Testを実行するときに利用します。今回の学習用環境では通常の開発用Databaseと同じ shop を接続先としますが、後続のテストではテストごとに独立したSchemaや一時領域を利用してテストデータを分離します。
ここで使用している
appuser/apppassはローカル学習環境のサンプルです。本番環境では実際の認証情報を.envやソースコードへ固定せず、環境変数やSecretsなどの適切な仕組みで管理してください。
.envをGit管理対象から除外する
.env には認証情報を含むため、Gitへコミットしないようにします。
プロジェクトルートに .gitignore を作成し、次を追加します。
.env
既に .gitignore が存在する場合は、既存内容を残したまま .env を追加します。
.env.exampleを作成する
開発環境で必要な環境変数を確認できるように、プロジェクトルートに .env.example を作成します。
POSTGRES_DB=shop
POSTGRES_USER=appuser
POSTGRES_PASSWORD=
DATABASE_URL=
TEST_DATABASE_URL=
.env.example には実際のパスワードを記載せず、必要な環境変数だけを確認できるようにします。
構成は次のようになります。
shopping-site
│
├─ .env
├─ .env.example
├─ .gitignore
├─ compose.yml
└─ ...
compose.ymlの作成
プロジェクトルートに、
compose.yml
を作成します。
services:
app:
image: mcr.microsoft.com/devcontainers/go:2-1.26-trixie
volumes:
- .:/workspaces/shopping-site:cached
command: sleep infinity
ports:
- "5173:5173"
- "8080:8080"
environment:
DATABASE_URL: ${DATABASE_URL}
TEST_DATABASE_URL: ${TEST_DATABASE_URL}
depends_on:
- db
db:
image: postgres:17
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- postgres-data:/var/lib/postgresql/data
volumes:
postgres-data:
このDocker Composeでは2つのサービスを定義しています。
services
│
├─ app
│ └─ 開発コンテナ
│
└─ db
└─ PostgreSQL
appサービス
app はVS Codeから接続するDevelopment Containerです。
app:
image: mcr.microsoft.com/devcontainers/go:2-1.26-trixie
Go用Dev Containerイメージをベースにします。
また、
ports:
- "5173:5173"
- "8080:8080"
として、
5173
↓
Vite / React
8080
↓
Go REST API
をWindows側からアクセスできるようにします。
dbサービス
db はPostgreSQLです。
db:
image: postgres:17
開発用として .env で定義した次の設定を利用します。
Database
shop
User
appuser
Password
apppass
compose.yml では値を直接記述せず、次のように .env の環境変数を参照します。
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
ここで使用しているパスワードはローカル開発環境のサンプルです。本番環境の認証情報をソースコードやComposeファイルへ直接記述しないでください。
PostgreSQLのポートをWindowsへ公開しない理由
今回の構成では、PostgreSQLの 5432 ポートをWindows側へ公開しません。
app と db は同じDocker Composeネットワーク上で動作するため、Go APIからPostgreSQLへはサービス名 db を使って直接接続できます。
app Container
│
│ db:5432
▼
db Container
│
└─ PostgreSQL
そのため、db サービスには次のような ports 設定は記述しません。
# 今回は設定しない
ports:
- "5432:5432"
これにより、Windows側ですでに別のPostgreSQLが 5432 ポートを使用している場合でも、ホスト側のポート競合を避けられます。
また、PostgreSQLをWindows側へ公開しないため、データベースへ直接アクセスできる範囲もDocker Compose内部に限定できます。
Windows上のpgAdmin、DBeaver、psqlなどからPostgreSQLへ直接接続したい場合は、必要に応じて
5433:5432など別のホストポートを公開します。本記事ではWindowsからDBへ直接接続しないため設定しません。
PostgreSQLのデータ保存
次のVolumeを利用します。
volumes:
postgres-data:
これにより、PostgreSQLのデータをコンテナ本体とは分離して保持できます。
.devcontainerフォルダの作成
プロジェクト直下に、
.devcontainer
フォルダを作成します。
その中に、
devcontainer.json
を作成します。
shopping-site
│
├─ .devcontainer
│ └─ devcontainer.json
│
└─ compose.yml
devcontainer.jsonの作成
.devcontainer/devcontainer.json に次を記述します。
{
"name": "Shopping Site Development",
"dockerComposeFile": "../compose.yml",
"service": "app",
"workspaceFolder": "/workspaces/shopping-site",
"features": {
"ghcr.io/devcontainers/features/node:2": {
"version": "lts"
}
},
"customizations": {
"vscode": {
"extensions": [
"golang.go",
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode"
]
}
},
"forwardPorts": [
5173,
8080
],
"postCreateCommand": "npm install -g @openai/codex@latest",
"remoteUser": "vscode"
}
今回の重要なポイントは、
"dockerComposeFile": "../compose.yml"
です。
Dev ContainersからDocker Composeを利用します。
さらに、
"service": "app"
として、VS Codeが app コンテナへ接続するように指定します。
さらに、Codex CLIをDevelopment Container内へインストールするため、次の設定を追加しています。
"postCreateCommand": "npm install -g @openai/codex@latest"
postCreateCommand はDevelopment Containerの作成後に実行されるコマンドです。
今回はNode.js FeatureによってDevelopment Container内でnpmを利用できるため、npmを使ってCodex CLIをインストールします。
この設定により、Dev Containerを作成したときにCodex CLIも同じ app コンテナへ導入されます。
全体の流れは次のようになります。
VS Code
↓
Dev Containers
↓
devcontainer.json
↓
compose.yml
↓
Docker Desktop
│
├─ app
│ ↑
│ └─ VS Codeが接続
│
└─ db
└─ PostgreSQL
Node.jsをDev Containerへ追加する
今回の app コンテナはGo用イメージをベースにしています。
そこへDev Container Featureを利用してNode.jsを追加します。
"features": {
"ghcr.io/devcontainers/features/node:2": {
"version": "lts"
}
}
これにより、
Go Development Container
│
└─ Node.js Feature追加
↓
Development Container
├─ Go
├─ Node.js
├─ npm
└─ Codex CLI
という環境になります。
ReactやTypeScriptそのものをWindowsへインストールするのではなく、Node.js/npmを利用して frontend プロジェクト内へ導入します。
Codex CLIをDev Containerへ追加する
今回の開発では、Codex CLIもDevelopment Container内で利用します。
CodexをWindows側ではなくDevelopment Container内で動作させることで、Codexから同じコンテナ内のGo、Node.js、npm、プロジェクトファイルへ直接アクセスできます。
Codex CLIはnpmを利用してインストールします。
今回はDev Container作成時に自動的にインストールされるよう、.devcontainer/devcontainer.json に次の設定を追加しています。
"postCreateCommand": "npm install -g @openai/codex@latest"
これにより、Dev Containerの作成後に次のコマンドが自動実行されます。
npm install -g @openai/codex@latest
したがって、人間がDev Container作成後に毎回Codexを手動インストールする必要はありません。
構成は次のようになります。
Development Container
│
├─ Go
├─ Node.js
├─ npm
└─ Codex CLI
このあとDev Containerを起動すると、Node.js Featureの追加後に postCreateCommand が実行され、Codex CLIがDevelopment Container内へインストールされます。
Dev Containerを起動する
compose.yml と devcontainer.json を保存します。
VS Codeで、
Ctrl + Shift + P
を押します。
次を検索します。
Dev Containers: Reopen in Container
を選択します。
VS Codeが設定を読み込み、
devcontainer.json
↓
compose.yml
↓
Docker Desktop
↓
appコンテナ作成
+
dbコンテナ作成
↓
Node.js Feature追加
↓
Codex CLIインストール
↓
VS Codeがappへ接続
という流れで開発環境を構築します。
初回はDockerイメージやFeatureの取得が行われるため、時間がかかる場合があります。
コンテナの状態を確認する
Dev Containerが起動したら、VS Codeのターミナルを開きます。
まず現在のディレクトリを確認します。
pwd
次のように表示されます。
/workspaces/shopping-site
別のPowerShellからDockerコンテナを確認する場合は、
docker compose ps
を実行します。
概念的には次の2つが起動します。
shopping-site-app
shopping-site-db
実際のコンテナ名はComposeのプロジェクト名などによって異なる場合があります。
Goの動作確認
Dev Container内のターミナルで実行します。
go version
Node.jsの動作確認
次を実行します。
node --version
続いてnpmを確認します。
npm --version
両方のバージョンが表示されれば、Node.jsとnpmが利用できています。

Codex CLIの動作確認
今回の構成では、Codex CLIもDevelopment Container内で動作します。
Dev Container内のターミナルで次を実行します。
codex --version
Codexを起動する
プロジェクトルートへ移動します。
cd /workspaces/shopping-site
Codexを起動します。
codex
初回起動時は、画面に表示される案内に従って認証を行います。
認証が完了すると、CodexをDevelopment Container内から利用できます。
構成は次のようになります。
Windows 11
↓
VS Code
↓
Dev Containers
↓
Docker Compose
│
├─ app
│ ├─ Codex CLI
│ ├─ Go
│ └─ Node.js
│
└─ db
└─ PostgreSQL
Codexは app コンテナ内で動作するため、同じコンテナにあるGoやNode.jsを利用できます。
また、プロジェクトは /workspaces/shopping-site にマウントされているため、CodexからFrontendとBackendのソースコードを確認・修正できます。
後続の記事では、この構成を利用してCodexから実装、ユニットテスト、結合テストを実行します。
Gitの動作確認
Gitも確認します。
git --version
PostgreSQLの動作確認
PostgreSQLは db コンテナで動作しています。
Windows側のPowerShellで、
docker compose ps
続いて、PostgreSQLコンテナ内の psql を利用して接続します。
docker compose exec db psql -U appuser -d shop
接続できると、PostgreSQLのプロンプトが表示されます。
shop=#
データベースを確認します。
SELECT current_database();
終了する場合は、
\q
を入力します。
これで、
Docker Desktop
↓
db Container
↓
PostgreSQL
↓
shop Database
まで確認できました。
DB接続用の環境変数を確認する
Dev Container内のターミナルで、DATABASE_URL が app コンテナへ渡されていることを確認します。
printenv DATABASE_URL
次のように表示されれば設定できています。
postgres://appuser:apppass@db:5432/shop?sslmode=disable
続いて、テスト用の TEST_DATABASE_URL も確認します。
printenv TEST_DATABASE_URL
次のように表示されれば設定できています。
postgres://appuser:apppass@db:5432/shop?sslmode=disable
これにより、後続の記事でGo Backendからは DATABASE_URL、Repository TestやIntegration Testからは TEST_DATABASE_URL を利用できます。
React + TypeScriptプロジェクトの作成
続いてフロントエンドを作成します。
Dev Container内のVS Codeターミナルで、プロジェクトルートにいることを確認します。
pwd
/workspaces/shopping-site
Viteを利用してReact + TypeScriptプロジェクトを作成します。
npm create vite@latest frontend -- --template react-ts
Linterを選択する
Viteのバージョンによっては、続いて使用するLinterの選択画面が表示されます。
今回は Oxlint を選択し、Enterを押します。
Linterは、ソースコードを解析して問題のある記述などを検出するためのツールです。
npmによるインストール
続いて、次の確認が表示されます。
Install with npm and start now?
○ Yes / ● No
今回のDev Container環境では、Windows側のブラウザからViteへアクセスできるように --host 0.0.0.0 を指定して起動するため、ここでは No を選択してEnterを押します。
Viteのプロジェクト作成が完了したら、frontend へ移動します。
cd frontend
依存パッケージをインストールします。
npm install
ここまでで、
frontend
│
├─ src
├─ public
├─ package.json
├─ tsconfig.json
└─ ...
などが作成されます。
Viteやテンプレートのバージョンによって、生成されるファイル構成や表示される選択肢は変わる場合があります。
React + TypeScript開発サーバーを起動する
Dev Container内の frontend ディレクトリで、次を実行します。
npm run dev -- --host 0.0.0.0
--host 0.0.0.0 を指定することで、Viteをコンテナ内部だけではなく、Windows側のブラウザからアクセスできる状態で起動します。
正常に起動したら、Windows側のブラウザから、
http://localhost:5173
へアクセスします。
Vite + Reactの初期画面が表示されれば成功です。
構成は次のようになります。
Windows Browser
│
│ localhost:5173
▼
Docker Desktop
│
▼
app Container
│
├─ Node.js
├─ npm
├─ Vite
├─ React
└─ TypeScript
Yes を選択してViteを起動した場合
Install with npm and start now? で Yes を選択すると、npmによるインストール後、そのままViteの開発サーバーが起動します。
その際、次のように表示される場合があります。
VITE v8.x.x ready
Local: http://localhost:5173/
Network: use --host to expose
この状態では、Dev Container内部ではViteが起動していますが、Windows側のブラウザから http://localhost:5173 へアクセスすると、
ERR_EMPTY_RESPONSE
となる場合があります。
その場合は、Dev Container内のターミナルで、
Ctrl + C
を押してViteを停止します。
続いて、frontend ディレクトリで、
npm run dev -- --host 0.0.0.0
を実行して起動し直します。
その後、Windows側のブラウザから、
http://localhost:5173
へアクセスします。
React + TypeScriptのビルド確認
開発サーバーを停止する場合は、
Ctrl + C
を押します。
続いてビルドを確認します。
npm run build
正常に終了すれば、React + TypeScriptのビルド環境も利用できています。
Backendフォルダの作成
プロジェクトルートへ戻ります。
cd /workspaces/shopping-site
backend を作成します。
mkdir backend
cd backend
Goモジュールを初期化します。
go mod init example.com/shopping-site/backend
go.mod が作成されます。
backend
│
└─ go.mod
Go REST APIを作成する
backend/main.go を作成します。
package main
import (
"encoding/json"
"log"
"net/http"
)
type Message struct {
Message string `json:"message"`
}
func main() {
http.HandleFunc("/api/health", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
response := Message{
Message: "Go API is running",
}
if err := json.NewEncoder(w).Encode(response); err != nil {
http.Error(w, "failed to encode response", http.StatusInternalServerError)
}
})
log.Println("server started at :8080")
if err := http.ListenAndServe(":8080", nil); err != nil {
log.Fatal(err)
}
}
今回は環境確認が目的なので、Go標準ライブラリだけで簡単なAPIを作成します。
Go APIを起動する
backend ディレクトリで実行します。
go run .
次のようなログが表示されます。
server started at :8080
ブラウザから、
http://localhost:8080/api/health
へアクセスします。
次のJSONが表示されれば成功です。
{
"message": "Go API is running"
}
構成は次のようになります。
Windows Browser
│
│ localhost:8080
▼
app Container
│
└─ Go
│
└─ REST API
Goのテスト・ビルド環境を確認する
APIを停止します。
Ctrl + C
フォーマットします。
gofmt -w main.go
テスト対象が追加された場合は、次のコマンドでテストできます。
go test ./...
ビルドも確認します。
go build ./...
これでGo側も、
Go
├─ go run
├─ gofmt
├─ go test
└─ go build
を利用できる状態です。
FrontendとBackendの構成を確認する
ここまででプロジェクトは次のようになります。
shopping-site
│
├─ .devcontainer
│ └─ devcontainer.json
│
├─ .env
├─ .env.example
├─ .gitignore
│
├─ frontend
│ ├─ src
│ ├─ package.json
│ ├─ tsconfig.json
│ └─ ...
│
├─ backend
│ ├─ go.mod
│ └─ main.go
│
└─ compose.yml
Docker側では、
Docker Compose
│
├─ app
│ │
│ ├─ Codex CLI
│ │
│ ├─ /workspaces/shopping-site/frontend
│ │ └─ React + TypeScript
│ │
│ └─ /workspaces/shopping-site/backend
│ └─ Go
│
└─ db
└─ PostgreSQL
となっています。
appからPostgreSQLへ接続するときの接続先
今後、Go APIからPostgreSQLへ接続します。
ここで重要なのが接続先です。
Go APIもPostgreSQLもDocker Compose内で動作するため、GoからDBへ接続するときは、
localhost
ではなく、
db
を利用します。
概念的な接続情報は次のようになります。
Host db
Port 5432
Database shop
User appuser
Password apppass
実際のGo Backendでは接続情報をソースコードへ直接記述せず、.env から app コンテナへ渡した DATABASE_URL を利用します。
DATABASE_URL
↓
postgres://appuser:apppass@db:5432/shop?sslmode=disable
後続のRepository TestやIntegration Testでは TEST_DATABASE_URL を利用します。
つまり、
app Container
│
│ db:5432
▼
db Container
│
└─ PostgreSQL
となります。
localhost は「そのコンテナ自身」を表すため、app コンテナから別コンテナのPostgreSQLへ接続するときには使用しません。
Windowsからアクセスするときのlocalhostとの違い
Windows側からアクセスするのは、ブラウザで確認するReact / ViteとGo APIです。これらの公開ポートへアクセスするときは localhost を利用します。
PostgreSQLはWindows側へ公開していないため、localhost:5432 では接続しません。
Windows Browser
│
├─ localhost:5173
│ ↓
│ React / Vite
│
└─ localhost:8080
↓
Go API
整理すると、
コンテナ → コンテナ
db:5432
Windows → コンテナ
localhost:5173
localhost:8080
PostgreSQL
Windows側へは公開しない
という違いがあります。
開発時の起動方法
フロントエンドとバックエンドを同時に開発する場合は、VS Codeでターミナルを2つ開くと分かりやすくなります。
Terminal 1:Frontend
cd /workspaces/shopping-site/frontend
npm run dev -- --host 0.0.0.0
Terminal 2:Backend
cd /workspaces/shopping-site/backend
go run .
PostgreSQLはDocker Composeによってすでに db コンテナとして起動しています。
VS Code
│
├─ Terminal 1
│ └─ React / Vite :5173
│
├─ Terminal 2
│ └─ Go API :8080
│
└─ Docker Compose
└─ PostgreSQL :5432(Docker内部のみ)
VS Codeを終了した後の再開方法
VS Codeを終了しても、Windows側のプロジェクトファイルは残っています。
再開するときはPowerShellで、
cd C:\work\shopping-site
code .
を実行します。
VS CodeがWindows側で開いた場合は、
Ctrl + Shift + P
から、
Dev Containers: Reopen in Container
を実行します。
再び、
Windows VS Code
↓
Dev Containers
↓
Docker Compose
│
├─ app
└─ db
↓
VS Codeがappへ接続
という開発環境へ戻れます。
開発環境を停止する
Dev ContainerからWindows側へ戻した後、Docker Composeのコンテナも停止する場合は、プロジェクトルートで次を実行します。
docker compose down
PostgreSQLのデータはNamed Volumeへ保存しているため、通常の docker compose down ではVolumeは削除されません。
Volumeも含めて削除する場合は、
docker compose down -v
を利用できます。
-vを指定するとPostgreSQLの開発データも削除されるため、必要なデータがある場合は注意してください。
Windows側にNode.jsやGoをインストールする必要はあるのか
今回の構成では、Windows側へNode.jsやGo SDKを直接インストールする必要はありません。
Windows側は、
Windows 11
│
├─ Docker Desktop
└─ VS Code
└─ Dev Containers
を中心にします。
開発ツールとCodex CLIはコンテナ側へ配置します。
app Container
│
├─ Codex CLI
├─ Go
├─ Node.js
├─ npm
├─ React
├─ TypeScript
└─ Vite
データベースも別コンテナです。
db Container
└─ PostgreSQL
このように環境を分離することで、Windows側の開発言語のバージョン差異を減らしやすくなります。
前回のGo単体環境との違い
前回は、
Windows 11
↓
VS Code
↓
Dev Containers
↓
Go Development Container
↓
Go
というGo単体の開発環境でした。
今回は、
Windows 11
↓
VS Code
↓
Dev Containers
↓
Docker Compose
│
├─ app
│ ├─ Codex CLI
│ ├─ Go
│ └─ Node.js
│ └─ React + TypeScript + Vite
│
└─ db
└─ PostgreSQL
まで発展させています。
これにより、フロントエンド、バックエンド、データベースを同じプロジェクトで開発できるようになります。
完成した開発環境
最終的な構成は次のとおりです。
[Windows 11]
│
├─ Visual Studio Code
│ │
│ └─ Dev Containers
│
└─ Docker Desktop
│
└─ Docker Compose
│
├─ app
│ │
│ ├─ Codex CLI
│ │
│ ├─ Go
│ │ └─ REST API :8080
│ │
│ └─ Node.js
│ ├─ npm
│ ├─ Vite
│ ├─ React
│ └─ TypeScript
│ └─ Frontend :5173
│
└─ db
└─ PostgreSQL :5432(Docker内部のみ)
開発対象は、
shopping-site
│
├─ frontend
│ └─ React + TypeScript
│
├─ backend
│ └─ Go
│
└─ database
└─ PostgreSQL
という役割になります。
動作確認チェックリスト
最後に、今回の環境が利用できるか確認します。
| 確認項目 | コマンド / URL |
|---|---|
| Docker | docker --version |
| Docker Compose | docker compose version |
| Go | go version |
| Node.js | node --version |
| npm | npm --version |
| Git | git --version |
| Codex CLI | codex --version |
| Codex起動 | codex |
| PostgreSQL | docker compose exec db psql -U appuser -d shop |
| Backend DB接続環境変数 | printenv DATABASE_URL |
| Test DB接続環境変数 | printenv TEST_DATABASE_URL |
| React | npm run dev -- --host 0.0.0.0 |
| React画面 | http://localhost:5173 |
| React Build | npm run build |
| Go API | go run . |
| Go API確認 | http://localhost:8080/api/health |
| Go Test | go test ./... |
| Go Build | go build ./... |
すべて確認できれば、webアプリケーションを開発するための基本的なフルスタック開発環境は完成です。
まとめ
- React + TypeScriptの開発にはNode.jsとnpmを利用できる
- Viteを利用してReact + TypeScriptプロジェクトを作成できる
- GoとNode.jsは同じDevelopment Containerで利用できる
- Codex CLIをDevelopment Container内へインストールしてDocker上で利用できる
- Codexから同じDevelopment Container内のGo、Node.js、プロジェクトファイルへアクセスできる
- PostgreSQLはDocker Composeの別コンテナとして分離できる
- PostgreSQLの接続情報を
.envで管理し、Docker Composeからappとdbへ渡せる - 通常のBackendでは
DATABASE_URL、Repository TestやIntegration TestではTEST_DATABASE_URLを利用できる -
.envをGit管理対象から除外し、.env.exampleで必要な環境変数を共有できる - PostgreSQLの5432番ポートはWindows側へ公開せず、Docker Compose内部だけで利用できる
- Windows側ですでに別のPostgreSQLが5432番ポートを利用していても、ホスト側へ公開しなければポート競合を避けられる
- VS Code Dev ContainersからDocker Composeの
appコンテナへ接続できる - React / Viteは5173番ポート、Go APIは8080番ポートで動作確認できる
-
appコンテナからPostgreSQLへ接続するときはlocalhostではなくサービス名dbを利用する - Windows側へGoやNode.jsを直接インストールしなくても開発環境を構築できる
-
compose.ymlとdevcontainer.jsonをプロジェクトで管理することで、開発環境を再現しやすくなる
本連載について
| 回 | タイトル | 対応範囲 | 主な内容 |
|---|---|---|---|
| 第1回 | Docker × VS Code Dev ContainersでGo開発環境を構築する | 🐳 Go開発環境 | Docker Desktop・VS Code・Dev Containersを使ったGo開発環境の構築 |
| 第2回 | React + TypeScript + Go + PostgreSQLのフルスタック開発環境を構築する | 🛠️ フルスタック開発環境 | Docker Desktop・Dev Containers・React・TypeScript・Go・PostgreSQL・Node.js・Vite |
| 第3回 | ChatGPT Workでショッピングサイトを設計してみる | 📐 システム設計 | Project instructions・要件定義・ユースケース・画面設計・ER図・DB設計・REST API設計・テストケース仕様書 |
| 第4回 | Codex × AGENTS.md × Skillsで実装準備を整える | 🤖 AI開発ルール | AGENTS.md・プロジェクトルール・階層化・Skills・実装準備 |
| 第5回 | Codexで設計書からショッピングサイトを実装する | 🛒 ショッピングサイト実装 | 設計書・AGENTS.md・Skillsを活用した段階的なAI開発・実装・検証 |
| 第6回 | Codexで実装したショッピングサイトをテスト・動作確認する | 🧪 テスト・動作確認 | test-cases.md・ユニットテスト・結合テスト・API・ブラウザ・DBによる動作確認 |
| 発展編① | Codexのエージェントハーネスでテスト・デバッグ・再テストを自律化する | 🤖 エージェントハーネス | AGENTS.md・確定仕様・テストケース・停止条件を利用したテスト・デバッグ・修正・再テスト・Regression Testの自律化 |
| 発展編② | Playwrightでブラウザテストを自動化する | 🎭 E2Eテスト自動化 | Playwright・E2Eテスト・ブラウザ操作・Auto-waiting・Trace Viewer・Seleniumとの違い・Codexとの連携 |








