🐳

私的GolangのDocker環境

2022/07/26に公開

最近「そういえばアレあんまりわかってないな」みたいなトピックをGoでダラダラ書くのにハマってます
そんな中で私が常用しているGo向けのDockerfiledocker-compose.yamlを公開して人類に貢献したいと思います

早速Dockerfiledocker-compose.yamlです

Dockerfile
# ============
# Dev
# ============
FROM golang:1.18.3 as Dev
ENV TZ=Asia/Tokyo

ENV CGO_ENABLED=0
ENV GOOS=linux
ENV GOARCH=amd64
ENV ROOTPATH=/go/app

WORKDIR ${ROOTPATH}

RUN go install github.com/cosmtrek/air@v1.40.0
COPY go.mod go.sum .air.toml ./
RUN go mod download

COPY src/ ${ROOTPATH}/src/

CMD ["air", "-c", ".air.toml"]


# ============
# Builder
# ============
FROM golang:1.18.3 as Builder
ENV TZ=Asia/Tokyo

ENV CGO_ENABLED=0
ENV GOOS=linux
ENV GOARCH=amd64
ENV ROOTPATH=/go/app

WORKDIR ${ROOTPATH}

COPY go.mod go.sum ./
RUN go mod download

COPY src/ ${ROOTPATH}/src/

RUN go build \
    -o ${ROOTPATH}/bin/main \
    -ldflags '-s -w' \
    ./src/main.go


# ============
# Deploy
# ============
FROM gcr.io/distroless/static-debian11
ENV TZ=Asia/Tokyo

COPY --from=Builder /go/app/bin/main /app/main

EXPOSE 8080
USER nonroot:nonroot
CMD ["/app/main"]
docker-compose.yaml
version: "3.8"

services:
  server:
    build:
      context: .
      dockerfile: Dockerfile
      target: Dev
    stdin_open: true
    tty: true
    ports:
      - 80:80
    volumes:
      - type: bind
        source: src
        target: /go/app/src

以下にちょっとした解説を羅列します

  • ベースイメージは普通のgolang:x.x.xを利用してます、今のところ困ってないので無理してダイエットさせなくていいと思ってます
  • 基本的にローカルからはDockerfileDevステージをdocker-compose.yamlから利用して開発してます
  • Devステージではホットリロードのためにairを利用してます。2022/7/28時点の最新versionは1.40.0で、つい二週間前ほどに公開されたばかりです
    非常にオススメです。
airの設定ファイルはこちら(ほぼデフォルト)
.air.toml
# Config file for [Air](https://github.com/cosmtrek/air) in TOML format

# Working directory
# . or absolute path, please note that the directories following must be under root.
root = "."
tmp_dir = "tmp"

[build]
# Just plain old shell command. You could use `make` as well.
cmd = "go build -o ./tmp/main ./src/main.go"
# Binary file yields from `cmd`.
bin = "tmp/main"
# Customize binary, can setup environment variables when run your app.
full_bin = "APP_ENV=dev APP_USER=air ./tmp/main"
# Watch these filename extensions.
include_ext = ["go", "tpl", "tmpl", "html"]
# Ignore these filename extensions or directories.
exclude_dir = ["assets", "tmp", "vendor", "frontend/node_modules"]
# Watch these directories if you specified.
include_dir = []
# Exclude files.
exclude_file = []
# Exclude specific regular expressions.
exclude_regex = ["_test.go"]
# Exclude unchanged files.
exclude_unchanged = true
# Follow symlink for directories
follow_symlink = true
# This log file places in your tmp_dir.
log = "air.log"
# It's not necessary to trigger build each time file changes if it's too frequent.
delay = 1000 # ms
# Stop running old binary when build errors occur.
stop_on_error = true
# Send Interrupt signal before killing process (windows does not support this feature)
send_interrupt = false
# Delay after sending Interrupt signal
kill_delay = 500 # ms

[log]
# Show log time
time = false

[color]
# Customize each part's color. If no color found, use the raw app log.
main = "magenta"
watcher = "cyan"
build = "yellow"
runner = "green"

[misc]
# Delete tmp directory on exit
clean_on_exit = true
  • 個人的にdocker-compose.yamlvolumelong-syntax(参考)で書く方が読みやすいと思うので、意識して利用するようにしています
  • BuilderDeployステージはよくある形で、BuilderステージでバイナリをbuildしてDeployステージの軽量なdistrolessdebianで実行させています

特に目新しい部分はなかったかもしれないです
Github Gistに上げてあるのでよかったら試してみてください
https://gist.github.com/TadayoshiOtsuka/37ca54579c956dfa7c0da704c359da5a
これを機にみなさんの私的詩的Go環境もシェアしてもらえると嬉しいです🎉

参考にさせていただいた記事など

https://github.com/cosmtrek/air
https://docs.docker.com/compose/compose-file/compose-file-v3/

Discussion