Golang開発環境構築
コンセプト
- ローカル環境に処理系をインストールしない(全てコンテナに集約)
- 開発時はVS Codeのリモートコンテナでコンテナ内で開発
- ホットリロードツールで自動的にビルド
前提条件
- OSSとして公開しないプロジェクト(自社サービスとか)
環境
- Ubuntu 20.04
- Docker
- VS Code
- Remote Containers
ディレクトリ構成
$tree -a -I .git
.
├── .air.toml
├── .devcontainer
│ └── devcontainer.json
├── .env.example
├── .gitignore
├── Dockerfile
├── README.md
├── docker-compose.yaml
├── go.mod
├── go.sum
└── main.go
- ルートディレクトリに
main.go
を配置するスタイル
Dockerfile
- 開発時に使用するコンテナとリリース用のコンテナをマルチステージビルドで分けている
FROM golang:1.18 AS dev
WORKDIR /app
# -- Set ENV
ENV CGO_ENABLED=1 \
GOOS=linux \
GOARCH=amd64
# -- Install Dev Tool
RUN go install github.com/cosmtrek/air@latest && \
go install golang.org/x/tools/gopls@latest && \
go install github.com/ramya-rao-a/go-outline@latest && \
go install honnef.co/go/tools/cmd/staticcheck@latest && \
go install golang.org/x/tools/cmd/goimports@latest && \
go install github.com/josharian/impl@latest && \
go install github.com/go-delve/delve/cmd/dlv@latest && \
go install github.com/cweill/gotests/...@latest && \
go install github.com/haya14busa/goplay/cmd/goplay@latest && \
go install github.com/fatih/gomodifytags@latest && \
go install github.com/golang/mock/mockgen@latest && \
go install github.com/fzipp/gocyclo/cmd/gocyclo@latest && \
go install github.com/onsi/ginkgo/v2/ginkgo@latest && \
go install github.com/onsi/gomega/...@latest
# -- COPY Source
COPY . /app
# -- Build
RUN cd /app && \
go mod download && \
go build -o ${GOPATH}/bin/main /app/main.go
# -- Hot reload
CMD ["air", "-c", ".air.toml"]
FROM ubuntu:20.04 as prod
WORKDIR /app
# -- Set Envs
ENV DEBIAN_FRONTEND=noninteractive \
TZ=Asia/Tokyo \
LC_ALL=C.UTF-8 \
LANG=C.UTF-8
#
RUN apt update && apt install -y tzdata
COPY --from=dev /go/bin/main /app
CMD ["/app/main"]
- 処理系のバージョンは明示的に決めたいのでバージョンタグが付いたものを使用(
latest
は使わない)
- 開発用のコンテナにはユーティリティツールもインストールしている(VS Codeのリモートコンテナ起動時に毎回サジェストされるのが鬱陶しいので)
- 開発時はホットリロードツールとして
air
を利用している
docker-compose.yaml
version: '3.8'
services:
app:
environment:
PORT: ${PORT}
build: .
volumes:
- .:/app
tty: true
ports:
- ${PORT}:${PORT}
devcontainer.json
{
"name": "dev container",
"dockerComposeFile": [
"../docker-compose.yaml"
],
"service": "app",
"remoteUser": "root",
"workspaceFolder": "/app",
"settings": {},
"extensions": [
"golang.go",
"ms-azuretools.vscode-docker"
]
}
モジュールの追加
- ソースコードにimportを追加 && コンテナ内で
go mod tidy
- VS Codeのリモートコンテナで開発している場合、コンテナのターミナルが使えるようになるのでそこで実行する
参考資料