Contents
ローカル環境の前提条件
| OS | 必要なソフトウェア | 推奨設定 |
|---|---|---|
| Windows 10/11 (WSL2 推奨) | Docker Desktop、WSL2、PowerShell (管理者) またはコマンドプロンプト | CPU 仮想化有効、メモリ ≥ 4 GB、スワップ ≥ 2 GB |
| macOS (Intel / Apple Silicon) | Docker Desktop for Mac | 4 GB 以上の RAM、Apple Silicon は公式の Docker Desktop for Mac (Apple Chip) を使用 |
| Linux (Debian/Ubuntu 系) | Docker Engine、BuildKit (オプション) | docker グループへのユーザー追加で非 root 実行 |
⚠️ 注意:各 OS のバージョンが古いと Docker Desktop がインストールできないことがあります。OS のアップデートも合わせて実施してください。
Windows (WSL2) の詳細手順
1. PowerShell と コマンドプロンプトの違い
| 実行環境 | 主な特徴 |
|---|---|
| PowerShell(管理者) | dism.exe や wsl.exe がデフォルトでパスに通っている。スクリプト実行ポリシーが影響することは少ない。 |
| コマンドプロンプト(管理者) | 同様のコマンドは使用できるが、PowerShell のエイリアスや変数展開が使えない点に注意。 |
実務上は PowerShell(管理者)で以下の手順を行うことを推奨します。
2. WSL と仮想マシンプラットフォーム機能の有効化
|
1 2 3 4 |
# PowerShell (Run as Administrator) dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart |
❗ 再起動が必要です。
/norestartオプションは有効化だけを行い、手動で再起動させるために付与しています。
3. 再起動後の確認手順
- PC を再起動する。
- 管理者権限 PowerShell で以下を実行し、WSL のバージョンが 2 になっていることを確認
|
1 2 |
wsl --list --verbose # 出力例: Ubuntu-20.04 Running 2 |
- デフォルト版がまだ
1の場合は再設定
|
1 2 |
wsl --set-default-version 2 |
- 正しく設定できたら、PowerShell とコマンドプロンプトの両方で同じ結果が得られるか を確認(
wsl -l -v)。
4. WSL2 Linux カーネル更新プログラム
- 公式ダウンロード URL: https://aka.ms/wsl2kernel
- リンク切れ対策: 将来的に URL が変更されるリスクを考慮し、Internet Archive の保存ページ も併せてブックマークしてください。
|
1 2 3 4 |
# ダウンロード & インストール(PowerShell) Invoke-WebRequest -Uri "https://aka.ms/wsl2kernel" -OutFile "$env:USERPROFILE\Downloads\wsl_update_x64.msi" Start-Process msiexec.exe -ArgumentList "/i `"$env:USERPROFILE\Downloads\wsl_update_x64.msi`" /quiet" -Wait |
⚠️ 重要:インストール後は必ず Docker Desktop を再起動し、設定 → Resources → WSL Integration が有効になっていることを確認してください。
macOS / Linux でのセットアップ補足
macOS
- Apple Silicon (M1/M2) の場合は「Docker Desktop for Mac (Apple Chip)」を公式サイトから取得。Intel と同様に
docker versionが動作すれば完了です。 - Rosetta 2 は不要です(Docker Desktop がネイティブ対応)。
Linux
- Debian/Ubuntu 系以外(Fedora、Alpine 等)でも基本は同様ですが、パッケージ名やリポジトリ URL が異なる点に注意。
- BuildKit の有効化(高速ビルド推奨)
|
1 2 3 4 5 6 |
# /etc/docker/daemon.json に追記 { "features": { "buildkit": true } } systemctl restart docker |
- Docker グループへユーザー追加後は、ターミナルを完全に再起動(または
newgrp docker)して権限が反映されることを確認してください。
Dockerfile とマルチステージビルドのベストプラクティス
1. ビルドステージと実行ステージの分離
|
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 |
# ---------- ビルドステージ ---------- FROM golang:1.22-slim AS builder # 必要なツールだけインストール(例:git, ca-certificates) RUN apt-get update && apt-get install -y --no-install-recommends \ git ca-certificates && rm -rf /var/lib/apt/lists/* WORKDIR /src # go.mod/go.sum のみ先にコピーし、依存関係だけをキャッシュ COPY go.mod go.sum ./ RUN --mount=type=ssh \ go mod download # SSH 認証が必要なプライベートリポジトリ対応(後述) # ソース全体をコピー COPY . . # ビルド(CGO 無効化で static バイナリ) ENV CGO_ENABLED=0 GOFLAGS="-trimpath" RUN go build -ldflags="-s -w -X main.version=$(git rev-parse --short HEAD)" \ -o /app/goapp001 ./cmd/goapp001 # ---------- 実行ステージ ---------- FROM alpine:3.20 AS runtime RUN apk add --no-cache ca-certificates tzdata # 必要に応じて tzdata WORKDIR /app COPY --from=builder /app/goapp001 . EXPOSE 8080 ENTRYPOINT ["./goapp001"] |
ポイント解説
| 項目 | 説明 |
|---|---|
--mount=type=ssh |
ビルド時に SSH エージェントをマウントし、プライベートリポジトリの go get を安全に実行できる(Docker BuildKit が必須)。 |
apt-get install --no-install-recommends |
不要な依存パッケージを削減し、最終イメージサイズの増大を防止。 |
CGO_ENABLED=0 + -ldflags="-s -w" |
静的バイナリ化+デバッグ情報除去で Alpine 上でも動作し、サイズが約 30 % 減少。 |
tzdata の追加はローカルタイムゾーンを扱う場合に便利(オプション)。 |
2. ビルドキャッシュの最大活用
- マルチステージ + レイヤー順序最適化 により、
go.mod/go.sumが変更されない限り依存関係ダウンロードは再実行されません。 - 大規模プロジェクトでは
go build -mod=readonlyを付与して、意図しないモジュール取得を防止できます。
devcontainer.json の安全な記述例
1. remoteUser が存在しないケースへの対策
remoteUser: "vscode" は devcontainers/features が自動で作成するユーザーです。ベースイメージにそのユーザーが無い場合は、Dockerfile 側で手動作成または公式 mcr.microsoft.com/vscode/devcontainers/base:ubuntu 等のイメージへ切り替える必要があります。
Dockerfile にユーザー追加例
|
1 2 3 4 5 6 7 8 9 |
# 既存の builder イメージに続けて記述 ARG USERNAME=vscode ARG USER_UID=1000 ARG USER_GID=$USER_UID RUN groupadd --gid $USER_GID $USERNAME \ && useradd --uid $USER_UID --gid $USER_GID -m $USERNAME \ && echo "$USERNAME ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/$USERNAME |
⚠️ 注意:
remoteUserを変更した場合は、.devcontainer/devcontainer.jsonと Dockerfile の両方を同期させてください。
2. 完全版 devcontainer.json
|
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 |
{ "name": "Go Development Container", "dockerFile": "Dockerfile", "context": "..", "remoteUser": "vscode", // 上記 Dockerfile に合わせて作成済みユーザー "features": { "ghcr.io/devcontainers/features/go:1": { "version": "1.22" } }, "customizations": { "vscode": { "extensions": [ "golang.Go", "ms-azuretools.vscode-docker", "github.copilot" ] } }, "forwardPorts": [8080], "postCreateCommand": "go mod tidy && go install github.com/cosmtrek/air@latest", "remoteEnv": { "GO111MODULE": "on" }, // ボリュームマウントで Go のキャッシュ永続化(CI 時間短縮) "mounts": [ "source=go-mod-cache,target=/home/vscode/go/pkg/mod,type=volume", "source=go-build-cache,target=/home/vscode/.cache/go-build,type=volume" ] } |
3. 外部リンクの安定化
備考:執筆時点でリンクが有効かどうかは必ず確認し、将来的に URL が変更された場合は上記アーカイブURLへ差し替えると読者の手間が減ります。
プライベートリポジトリの認証対策
go mod download でプライベート Git リポジトリを取得する際、ビルド環境に認証情報が無いと失敗します。代表的な対策は以下です。
1. SSH 鍵を利用したビルド(推奨)
|
1 2 3 4 5 6 |
# Docker BuildKit が必要 # ビルド実行時: DOCKER_BUILDKIT=1 docker build --ssh default . RUN --mount=type=ssh \ git config --global url."git@github.com:".insteadOf "https://github.com/" && \ go mod download |
- 手順
- ローカルに SSH キー (
~/.ssh/id_rsa) を作成し、GitHub に公開鍵を登録。 docker build --ssh defaultオプションでエージェント転送。
2. .netrc / 環境変数方式(トークンベース)
|
1 2 3 4 5 |
ARG GITHUB_TOKEN RUN echo "machine github.com login $GITHUB_TOKEN password x-oauth-basic" > /root/.netrc && \ chmod 600 /root/.netrc && \ go mod download |
- ビルドコマンド
|
1 2 |
DOCKER_BUILDKIT=1 docker build --build-arg GITHUB_TOKEN=$(gh auth token) . |
セキュリティ注意点:
ARGの値はイメージのレイヤーに残らないよう--squashかマルチステージで除去してください。
Docker‑Compose・air でホットリロード、Delve デバッグ
docker-compose.yml(開発モード)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
version: "3.9" services: app: build: context: . dockerfile: Dockerfile target: builder # ビルドステージを直接利用可能にする場合は指定 command: air -c .air.toml volumes: - .:/app:cached # ソースコード共有(macOS での I/O 最適化) ports: - "8080:8080" environment: - GO111MODULE=on # Delve 用ポートはデバッグ時だけ開放すること # ports: # - "40000:40000" |
.air.toml(最低構成)
|
1 2 3 4 5 6 7 8 9 10 11 12 |
[build] cmd = "go build -o ./tmp/goapp001 ./cmd/goapp001" bin = "./tmp/goapp001" include_ext = ["go", "tmpl"] exclude_dir = ["vendor", "tmp"] [log] time = true [color] main = "yellow" |
Delve デバッグ用の拡張(本番環境には不要)
|
1 2 3 |
# builder ステージの最後に追加 RUN go install github.com/go-delve/delve/cmd/dlv@latest |
docker-compose.yml のデバッグモード例
|
1 2 3 4 5 6 7 |
app: build: . command: dlv debug ./cmd/goapp001 --headless --listen=:40000 --api-version=2 --log ports: - "8080:8080" - "40000:40000" |
VS Code launch.json(Remote Attach)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
{ "version": "0.2.0", "configurations": [ { "name": "Attach to Go (Docker)", "type": "go", "request": "attach", "mode": "remote", "remotePath": "/app", "port": 40000, "host": "127.0.0.1", "showLog": true } ] } |
ポイント:
airとdlvは同時に起動できません。開発中はair、デバッグが必要なときだけdocker compose -f docker-compose.yml up app --detach && code .でlaunch.jsonを使って attach します。
本番イメージ最適化と CI/CD への応用
1. ビルド時のレイヤー削減
|
1 2 |
DOCKER_BUILDKIT=1 docker build --squash -t ghcr.io/yourorg/goapp:prod . |
--squashは全レイヤーを一つにまとめ、イメージサイズと脆弱性サーフェスを縮小します(Docker Engine 20.10 以降で利用可能)。
2. Multi‑platform ビルド(amd64 / arm64)
|
1 2 3 4 5 6 |
docker buildx create --use docker buildx build \ --platform linux/amd64,linux/arm64 \ -t ghcr.io/yourorg/goapp:prod \ --push . |
- GitHub Actions や GitLab CI の
setup-buildx-actionと組み合わせると、プッシュ時に自動でマニフェストが生成されます。
3. CI パイプライン例(GitHub Actions)
|
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 |
name: Docker Build & Release on: push: tags: - 'v*.*.*' jobs: build: runs-on: ubuntu-latest permissions: packages: write steps: - uses: actions/checkout@v4 - name: Set up QEMU uses: docker/setup-qemu-action@v2 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Login to GHCR uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Build & Push multi‑arch image run: | docker buildx build \ --platform linux/amd64,linux/arm64 \ -t ghcr.io/${{ github.repository }}:${{ github.ref_name }} \ --push . |
4. セキュリティベストプラクティス
| 項目 | 推奨設定 |
|---|---|
| ユーザー | USER vscode(または非 root ユーザー)で実行。Dockerfile 最終段階に USER 指定を忘れないこと。 |
| 最小権限パッケージ | apk add --no-cache ca-certificates のみインストールし、不要なツールは削除 (apk del .build-deps) 。 |
| イメージスキャン | docker scan ghcr.io/yourorg/goapp:prod で脆弱性を CI に組み込む。 |
トラブルシューティング集
| 症状 | 原因例 | 解決策 |
|---|---|---|
| Docker Desktop が WSL2 と接続できない | Windows の Hyper‑V が無効、もしくは WSL2 カーネルが古い | 1. wsl --update でカーネル更新2. BIOS で仮想化を再確認 |
go mod download がタイムアウト |
プライベートリポジトリの認証情報未設定 | 上記「プライベートリポジトリ」章の SSH/Token 方法を導入 |
devcontainer 起動時に vscode ユーザーが見つからない |
ベースイメージが公式 devcontainer ではなく plain golang イメージ | Dockerfile にユーザー作成ステップを追加、またはベースを mcr.microsoft.com/vscode/devcontainers/base:ubuntu に変更 |
| air がファイル変化を検知しない | ボリュームマウントが cached のみで書き込みキャッシュが有効になりすぎている |
consistency=delegated(macOS)や type=bind,consistency=cached を試す |
| Delve がポートバインドエラー | コンテナ内で既に 40000 番が使用中、またはファイアウォール設定 | docker compose down && docker compose up -d app でクリーンアップし、ホスト側のファイアウォールを確認 |
| Docker イメージサイズが期待より大きい | ビルドステージから不要なファイル(例: .git, node_modules) がコピーされている |
.dockerignore に以下を追加<br>.git<br**/node_modules/**<br**/*.md<brDockerfile.dev<br> |
まとめ
- バージョン情報は常に最新版を確認し、日付・バージョンの注意書きを記事冒頭に入れる。
- WSL2 の有効化手順は PowerShell とコマンドプロンプトの違い、再起動後の
wsl -l -v確認を必ず行う。 - devcontainer の
remoteUserがベースイメージに存在しない場合は Dockerfile でユーザー作成か、公式 devcontainer ベースへ変更する。 - 外部リンクはアーカイブ URL を併記し、リンク切れリスクを低減。
- プライベートリポジトリへの認証は SSH エージェント転送 (
--mount=type=ssh) かビルド時環境変数で安全に提供する。 - マルチステージビルド、BuildKit、squash, buildx を活用して本番イメージは 70 ~ 80 MB に抑えつつ、CI/CD パイプラインへ自動化を組み込む。
- docker‑compose + air + Delve の組み合わせでローカル開発・デバッグフローが高速かつ安全になる。
これらの手順とベストプラクティスに従えば、Docker 上の Go 開発環境を 軽量・安全・再現性の高い 状態で構築でき、チーム全体の生産性向上につながります。ぜひ本稿のリポジトリ(例: github.com/yourorg/go-devcontainer-demo)をクローンし、ハンズオンで確認してみてください。