😎

dockerでgo開発環境構築

2021/04/13に公開

今後goと合わせてDBやNext.jsを使っていくので、dockerのコンテナ上で開発をしていこうと思います。本記事ではgoの開発環境をdockerで作成からバイナリ実行までを行います。
本内容のソースはgitの01_go_dockerにあげてあります。

docker環境作成

Standard Go Project Layoutに合わせたディレクトリ構成で構築する。

$ tree
.
├── build
│   └── Dockerfile
└── cmd
   └── hello
       └── main.go
├── docker-compose.yml

dockerfile

今回、golangにはalpineを使います。alpineを使う理由は容量が他と比べて小さいからです。
go getコマンドは裏でgitコマンドを使用しますが、alpineにはgitが入っていないのでインストールする必要があります。

# goバージョン
FROM golang:1.16.3-alpine
# アップデートとgitのインストール!!
RUN apk add --update &&  apk add git
# appディレクトリの作成
RUN mkdir /go/src/app
# ワーキングディレクトリの設定
WORKDIR /go/src/app
# ホストのファイルをコンテナの作業ディレクトリに移行
ADD . /go/src/app

docker-compose.yml

今後DBやNext.jsなどのフロントアプリなど複数のコンテナを立てることを想定するため、docker-composeファイルを作成しておきます。

version: "3"
services: 
  goapp: # サービス名
    build: # ビルドに使うDockerファイルのパス
      context: .
      dockerfile: ./build/Dockerfile
    tty: true # コンテナの永続化
    volumes:
      - ./cmd:/go/src/app # マウントディレクトリ

コンテナの作成

コマンドを実行し、コンテナを作成する。

$ docker-compose build

以下のようにメッセージが出力されていればビルド成功です。

Successfully built af9a3cec1965
Successfully tagged 01_go_docker_goapp:latest

次にイメージができているか確認する。

$ docker images
REPOSITORY                                                        TAG                  IMAGE ID       CREATED             SIZE
01_go_docker_goapp                                                latest               af9a3cec1965   29 minutes ago      318MB

goファイル作成

マウントするためのディレクトリ/goファイルを作成します。
main.goには以下を記述し、コンテナから実行できたことを確認するため簡単なメッセージを出力するようにします。

package main

import "fmt"

func main() {
	fmt.Println("Hello world")
}

コンテナを立ち上げます。

$ docker-compose up -d
Creating network "01_go_docker_default" with the default driver
Creating 01_go_docker_goapp_1 ... done

作成したファイルん実行を確認します。
「Hello world」と出力が確認できました。

$ docker-compose exec goapp go run hello/main.go
Hello world

最後はコンテナを閉じることを忘れないでください。

$ docker-compose down
Stopping 01_go_docker_goapp_1 ... done
Removing 01_go_docker_goapp_1 ... done
Removing network 01_go_docker_default

goの初期化やビルド

コンテナ上での初期化やパッケージのインストール、そしてビルドをを行います。

初期化

go.modファイルを作成します。

$ docker-compose exec goapp go mod init github.com/akakuro43/go-app
$ docker-compose exec goapp go mod tidy

パッケージのインストールと実行確認

パッケージをインストールします。成功するとgo.sumファイルが作成される。

$ docker-compose exec goapp go get golang.org/x/tools/cmd/goimports
go: downloading golang.org/x/tools v0.1.0
go: downloading golang.org/x/mod v0.3.0
go: downloading golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4
go: downloading golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1
go get: added golang.org/x/tools v0.1.0

続いて、実行してみます。
インストールしたパッケージの動作も確認できました。

$ docker-compose exec goapp goimports ./hello/main.go 
package main

import "fmt"

func main() {
        fmt.Println("Hello world")
}

ビルドして実行

ビルドするとapp_helloという実行ファイルが生成されますので、続いて実行すると「Hello world」が表示されます。バイナリファイルとしての実行が確認できました。

// ビルド
$ docker-compose exec goapp go build -o app_hello hello/main.go
// 実行
$ docker-compose exec goapp ./app_hello
Hello world

ホットリロードも行いたいので、実装できたら追記しようと思います。
goのホットリロードはAirがアツいのかな??

Discussion