Edited at
Go3Day 9

Goの開発環境でDockerを利用する

Go3 Advent Calendar 2018の9日目を担当するtheoden9014です。よろしくお願いします。

Makefileについて書こうと思ったのですが、内容が同じような記事が先に出てしまったようなので、少し趣向を変えたタイトルにしました。

この記事では、MakefileDockerfileを上手く利用することによって、Docker内でのビルドやデバッグを簡単にする方法についてご紹介します。

この手法であれば、開発者は手元にはDockerをインストールするだけでGoを使った開発を行えるようになります。

今回は以下のリポジトリをベースとしてご紹介していきます。

https://github.com/theoden9014/go-startkit/tree/qiita


背景

Goで開発する際には$GOPATHの知識は必要不可欠です。

vgoの普及によって$GOPATHの重要性は下がってくるでしょうが、現段階では全く考慮しないわけには行きません。

初心者でも簡単にHello Worldができるような環境を作りたいな、と思い今回の記事を書きました。


Dockerfile

以下のDockerfileはdockerのマルチステージビルドを用い、以下のステージに分けています


  • development


    • 開発を行うための周辺環境が整っているステージ



  • builder


    • ビルドを行うための周辺環境が整っているステージ



ステージを指定しない場合は、builderステージでビルド後、成果物をalpineへコピーし、バイナリを実行するだけのコンテナイメージをビルドすることができます。

#

# Use multi stage build so require docker version higher 17.05.
#
FROM golang:1.11 AS development
ARG name=
ARG repository=
RUN apt-get update -y
RUN apt-get install -y doxygen doxygen-gui graphviz
WORKDIR /go/src/${repository}
COPY Makefile ./
RUN make setup
CMD ["/bin/true"]

FROM development AS builder
COPY Gopkg.toml Gopkg.lock ./
RUN make vendor
COPY . .
RUN make build
CMD ["/bin/true"]

FROM alpine
ARG name=
ARG repository=
ENV PORT 8080
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /go/src/${repository}/${name} ./app
ENTRYPOINT ["./app"]


Makefile

https://github.com/theoden9014/go-makefile/blob/qiita/Makefile

上記のMakefileのDockerに関する部分について軽く説明していきます。

REPOSITORY              ?= github.com/theoden9014/go-startkit

NAME ?= go-startkit

...

#
# Docker
#
DOCKER ?= docker
DOCKER_IMAGE_NAME := $(NAME)
DEVELOP_DOCKER_IMAGE_NAME := $(NAME)-dev
BUILD_DOCKER_IMAGE_NAME := $(NAME)-build
DOCKERFILE := Dockerfile
DEVELOP_STAGE := development
BUILD_STAGE := builder
DEFAULT_DOCKER_BUILD_OPTS := -f $(DOCKERFILE) --build-arg name=$(NAME) --build-arg repository=$(REPOSITORY)
DOCKER_BUILD_DEVELOP_STAGE_OPTS := $(DEFAULT_DOCKER_BUILD_OPTS) -t $(DEVELOP_DOCKER_IMAGE_NAME) --target $(DEVELOP_STAGE)
DOCKER_BUILD_BUILD_STAGE_OPTS := $(DEFAULT_DOCKER_BUILD_OPTS) -t $(BUILD_DOCKER_IMAGE_NAME) --target $(BUILD_STAGE)
DOCKER_BUILD_OPTS := $(DEFAULT_DOCKER_BUILD_OPTS) -t $(DOCKER_IMAGE_NAME)

...

# Docker targets from here
docker: ## Build server image
docker build $(DOCKER_BUILD_OPTS) .
login: build-develop-stage ## Login to development environment with container
docker run --rm -it \
-v $(PWD):/go/src/$(REPOSITORY) \
-p 8080:8080 \
$(DEVELOP_DOCKER_IMAGE_NAME) \
/bin/bash
docker-check: build-develop-stage ## Run 'make check' inside container
docker run --rm -it \
$(DEVELOP_DOCKER_IMAGE_NAME) \
make check
docker-coverview: build-develop-stage ## Run 'make coverview' inside container
docker run --rm -it \
-v $(PWD):/go/src/$(REPOSITORY) \
$(DEVELOP_DOCKER_IMAGE_NAME) \
make coverview
docker-graph: build-develop-stage ## Run 'make graph' inside container
docker run --rm -it \
-v $(PWD):/go/src/$(REPOSITORY) \
$(DEVELOP_DOCKER_IMAGE_NAME) \
make graph
build-develop-stage:
docker build $(DOCKER_BUILD_DEVELOP_STAGE_OPTS) .
build-build-stage:
docker build $(DOCKER_BUILD_BUILD_STAGE_OPTS) .

.PHONY: docker login docker-check docker-coverview docker-graph build-develop-stage build-build-stage

上記のMakefileを利用することで以下のようなことが行えるようになります。



  • make login


    • プロジェクトルートディレクトリをコンテナ内の$GOPATH配下へマウントし、コーディングはローカルのIDEで、ビルドやデバッグはコンテナ内で行えます




  • make docker-*


    • コンテナ内でテストやパッケージ依存関係のグラフ作成等を行えるようにしています




最後に

以上、簡単ではありましたがGo言語をDockerで開発する方法の紹介でした。

ここまでご覧いただきありがとうございました。

明日は@pankonaさんです!