こんにちは!GxP の肥後です。
この記事はGxP Advent Calendar 2025 の 3日目の記事です。
はじめに
いざGoの開発環境を整えようとすると、特に Windows 環境ではいくつかの壁にぶつかります。
- 環境構築が面倒: Linter や Formatter、DB のセットアップだけで日が暮れる。
-
Docker が遅い:
go mod downloadやビルドに時間がかかる。 - チーム開発の壁: 「私の環境では動くんですけど…」が起きる。
「開発・学習を始めたいだけなのに、環境構築で消耗したくない!」
そう思った私は、VS Code と Docker(DevContainer)を使って、コマンド一発で立ち上がる「最強の Go 開発環境」を構築しました。
今回は、Windows 特有の「Docker 遅延問題」も解決した、こだわりの設定ファイルを全公開します。
目指した「モダンな環境」の要件
学習用とはいえ、実務でも通用するレベルを目指しました。
- 全部入り: Go 1.24, PostgreSQL, Air(ホットリロード), sqlc, golangci-lint を完備。
- 爆速: Windows でもネイティブ並みの I/O 速度を出す。
- 堅牢: DB の起動待ち(Healthcheck)やバージョン固定を行い、エラーで止まらない。
なぜ Windows の Docker は遅いのか?(高速化の理論)
コードを紹介する前に、Windows ユーザーにとって最も重要な「速度」の話をします。
Windows 上のフォルダ(例: C:\Users\Project)を Docker にマウントすると、ファイルシステムの変換処理が発生し、ディスクアクセスが劇的に遅くなります。これが「Windows の Docker は重い」と言われる主な原因です。
これを解決するには、以下の構成にするのが正解です。
- ソースコード: WSL 2(Linux 領域) の中に置く。
- キャッシュ類: Named Volumes(Docker 管理領域) に逃がす。
こうすることで、すべての処理が Linux の中で完結し、「爆速」 になります。 今回の設定ファイルは、この仕組みをフル活用しています。
なぜ Docker Compose ではなく DevContainer なのか?
「Docker Compose だけでいいのでは?」と思うかもしれません。 しかし、DevContainer には VS Code の設定まで配布できるという強力なメリットがあります。
- 拡張機能の自動インストール: Go, Docker, DB クライアントなどが勝手に入る。
-
設定の共有:
formatOnSaveやlintToolの設定も共有される。 - チーム全員同じ環境: 新しいメンバーはリポジトリを開くだけで、あなたと全く同じエディタ環境が手に入る。
環境構築の手順書を作る必要はもうありません。「このリポジトリを VS Code で開いて」の一言で済みます。
構築手順と設定ファイル
1. ディレクトリ構成
プロジェクトフォルダは必ず WSL 2 の領域内(例: \\wsl$\Ubuntu\home\user\go-project) に作成してください。
my-go-project/
├── .devcontainer/
│ ├── devcontainer.json
│ └── Dockerfile
├── docker-compose.yml
├── .env <-- 環境変数(gitignore推奨)
├── go.mod
└── main.go
2. Dockerfile:ツール群をバージョン固定で導入
ベースは Microsoft 公式イメージ。各ツールは latest ではなくタグ指定でインストールし、突然の仕様変更で環境が壊れるのを防ぎます。
FROM mcr.microsoft.com/devcontainers/go:1-1.24.5-bookworm
# 開発効率を上げるモダンなツール群をインストール(バージョン固定)
# air: ホットリロード
# migrate: DBマイグレーション
# sqlc: 型安全なクエリ生成
# mockgen: テスト用モック
# goimports: フォーマッター
RUN go install github.com/air-verse/air@v1.52.3 && \
go install -tags 'postgres' github.com/golang-migrate/migrate/v4/cmd/migrate@v4.18.1 && \
go install github.com/sqlc-dev/sqlc/cmd/sqlc@v1.27.0 && \
go install go.uber.org/mock/mockgen@v0.5.0 && \
go install golang.org/x/tools/cmd/goimports@v0.28.0
# DB接続確認用にPostgreSQLクライアントも入れておく
RUN apt-get update && apt-get install -y \
postgresql-client \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
3. docker-compose.yml:DB 連携と高速化の要
App(Go)と DB(Postgres)を定義します。 ここでのポイントは volumes 設定によるキャッシュの永続化 と、healthcheck による起動順序の制御 です。
services:
# PostgreSQL Database
db:
image: postgres:15-alpine
container_name: my-go-project-db
env_file:
- .env
volumes:
- db-data:/var/lib/postgresql/data
# DBが接続可能になるまで監視する設定
healthcheck:
test: ['CMD-SHELL', 'pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}']
interval: 10s
timeout: 5s
retries: 5
start_period: 10s
networks:
- app-network
restart: unless-stopped
# Go Application (Dev Container用)
app:
build:
context: .
dockerfile: .devcontainer/Dockerfile
container_name: my-go-project-app
env_file:
- .env
# DBのHealthcheckがOKになるまで起動を待つ(エラー回避)
depends_on:
db:
condition: service_healthy
volumes:
# ソースコードはCachedマウントで同期
- .:/workspace:cached
# ★ここが爆速ポイント!ビルドキャッシュをNamed Volumeに逃がす
- go-build-cache:/home/vscode/.cache/go-build
- go-pkg-cache:/go/pkg
working_dir: /workspace
networks:
- app-network
# DB接続文字列を環境変数から自動構築してGoに渡す
environment:
DATABASE_URL: 'postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}?sslmode=disable'
command: sleep infinity
volumes:
db-data:
go-build-cache:
go-pkg-cache:
networks:
app-network:
driver: bridge
4. devcontainer.json:VS Code の完全制御
最後に、VS Code がどう振る舞うかを定義します。拡張機能の自動インストールや、ポート通知設定を行います。
※ customizations に GitHub.copilot を含めていますが、チームメンバーが契約していない場合は自動で無効になるか、エラーになる可能性があります。不要な場合はこの行を削除してください。
{
"name": "Go Development with PostgreSQL",
"dockerComposeFile": "../docker-compose.yml",
"service": "app",
"workspaceFolder": "/workspace",
"runServices": ["db"],
"features": {
"ghcr.io/devcontainers/features/github-cli:1": {},
"ghcr.io/devcontainers/features/docker-outside-of-docker:1": {},
// golangci-lintはfeatureで入れるのが手軽で確実
"ghcr.io/devcontainers-contrib/features/golangci-lint:1": {}
},
// デバッグ実行(dlv)に必要な権限
// ※セキュリティ制限を緩和していますが、ローカル開発環境(コンテナ内)なので安全です
"capAdd": ["SYS_PTRACE"],
"securityOpt": ["seccomp=unconfined"],
"customizations": {
"vscode": {
// コンテナ内だけで有効になる拡張機能
"extensions": [
"golang.Go",
"ms-azuretools.vscode-docker",
"cweijan.vscode-postgresql-client2",
// Copilotを契約していない場合は削除してください
"GitHub.copilot"
],
// チーム全員で共有したいVS Code設定
"settings": {
"go.useLanguageServer": true,
"go.formatTool": "goimports",
"go.lintTool": "golangci-lint",
"editor.formatOnSave": true,
"go.toolsManagement.autoUpdate": true
}
}
},
"postCreateCommand": "go version && go mod download",
"portsAttributes": {
"5432": { "label": "PostgreSQL", "onAutoForward": "notify" },
"8080": { "label": "Application", "onAutoForward": "openBrowser" }
}
}
5. 環境変数 (.env)
プロジェクトルートに作成します。Git には含めないように注意してください。
POSTGRES_USER=myuser
POSTGRES_PASSWORD=mypassword
POSTGRES_DB=mydb
6. アプリケーションコード (go.mod, main.go)
これがないと起動時にエラーになるので、とりあえず動くものを用意します。
go.mod:
module my-go-project
go 1.24.5
main.go:
package main
import "fmt"
func main() {
fmt.Println("Hello, DevContainer!")
}
前提条件
- Docker Desktop がインストールされていること
- VS Code に拡張機能「Dev Containers」がインストールされていること
- WSL 2 が有効化されていること
使い方(起動手順)
- WSL 2 を起動: ターミナルで Ubuntu を開きます。
-
フォルダ作成:
mkdir my-go-projectなどでフォルダを作り、上記のファイルを配置します。 -
VS Code 起動: そのフォルダ内で
code .を実行します。 - コンテナ起動: VS Code 左下の「><」アイコン(または通知)から "Dev Containers: Reopen in Container" をクリック。
初回はビルドが走りますが、しばらく待つと開発環境が立ち上がります。 ターミナルを開いて air -v や psql --version が表示されれば成功です!
Tips & トラブルシューティング
最後に、初心者がハマりやすいポイントをまとめておきます。
- Docker Desktop の設定: Settings > Resources > WSL Integration で、使用している Ubuntu ディストリビューションのスイッチが ON になっているか確認してください。
- 初回起動が遅い: 初回は Go の Docker イメージやツール群をダウンロードするため、数分かかることがあります。2 回目以降は爆速です。
-
権限エラー: もし
permission deniedが出る場合は、docker-compose.ymlのvolumes設定でキャッシュのパスが正しく設定されているか確認してください(今回の設定ファイルでは対策済みです)。
まとめ
これで、Windows 環境でも「遅い」と嘆くことなく、Go の学習や開発に集中できる環境が整いました。 ローカル PC を一切汚さず、設定ファイルだけでいつでも同じ環境を再現できるのが DevContainer の最大の強みです。
これから Go を始める方も、環境構築で悩んでいる方も、ぜひこの構成を試してみてください!