Docker上でGolang(Echo)+realizeの起動まで

概要

Goでの開発用環境構築をやっていました。Echoの起動とrealizeによるホットリロードの確認まで行っています。
結構苦労したので書き残しておきます。

github.com

github.com

内容

ディレクトリ構成

動作確認しか行っていないので、必要最低限のもののみ入っています。

.
├── Dockerfile
├── docker-compose.yml
├── go.mod
├── go.sum
├── main
└── main.go

Docker

Dockerfile及びdocker-compose.ymlを以下のように設定します。

FROM golang:alpine

ENV SRC_DIR=/go/src/github.com/ryu022304/test-echo
ENV  GO111MODULE=on

WORKDIR $SRC_DIR

RUN apk update && apk add git

RUN go mod init test-echo
RUN go get github.com/labstack/echo/v4
RUN GO111MODULE=off go get github.com/oxequa/realize
version: '3'
services:
  app:
    build: .
    ports:
      - 1323:1323
    volumes:
      - .:/go/src/github.com/ryu022304/test-echo
    tty: true
    command: realize start

Dockerfile内の RUN GO111MODULE=off go get github.com/oxequa/realize については、先頭の RUN GO111MODULE=off をつけないと下記のようなエラーが出てしまうので追加しています。docker-compose.yml内の realize start に関しましては、後述するrealizeの実行を行っています。

go: github.com/oxequa/realize imports
    gopkg.in/urfave/cli.v2: gopkg.in/urfave/cli.v2@v2.3.0: parsing go.mod:
    module declares its path as: github.com/urfave/cli/v2
            but was required as: gopkg.in/urfave/cli.v2

github.com

realize

.realize.yamlを以下のように設定します。.realize.ymlだとだめなようなので注意が必要です。
この設定とdocker-compose.ymlに記述した内容により、 docker-compose up しただけで.goのソースを更新するたびにbuildと実行を自動で行ってくれるようにします。

settings:
  legacy:
    force: false
    interval: 0s
schema:
- name: realize
  path: .
  commands:
    install:
      status: true
      method: go build -o ./main ./
    run:
      status: true
      method: ./main
  watcher:
    extensions:
    - go
    paths:
    - /
    ignored_paths:
    - .git
    - .realize
    - vendor

main.go

基本的にechoのgithub上にあるサンプルをそのまま使っています。

package main

import (
  "net/http"
  "github.com/labstack/echo/v4"
  "github.com/labstack/echo/v4/middleware"
)

func main() {
  // Echo instance
  e := echo.New()

  // Middleware
  e.Use(middleware.Logger())
  e.Use(middleware.Recover())

  // Routes
  e.GET("/", hello)

  // Start server
  e.Logger.Fatal(e.Start(":1323"))
}

// Handler
func hello(c echo.Context) error {
  return c.String(http.StatusOK, "Hello, World!\n")
}

確認

docker-composeでコンテナを立ち上げます。

$ docker-compose up
Creating network "test-echo_default" with the default driver
Creating test-echo_app_1 ... done
Attaching to test-echo_app_1
app_1  | [08:43:33][REALIZE] : Watching 1 file/s 1 folder/s
app_1  | [08:43:33][REALIZE] : Install started
app_1  | [08:43:34][REALIZE] : Install completed in 1.209 s
app_1  | [08:43:34][REALIZE] : Running..
app_1  | [08:43:34][REALIZE] :    ____    __
app_1  | [08:43:34][REALIZE] :   / __/___/ /  ___
app_1  | [08:43:34][REALIZE] :  / _// __/ _ \/ _ \
app_1  | [08:43:34][REALIZE] : /___/\__/_//_/\___/ v4.1.17
app_1  | [08:43:34][REALIZE] : High performance, minimalist Go web framework
app_1  | [08:43:34][REALIZE] : https://echo.labstack.com
app_1  | [08:43:34][REALIZE] : ____________________________________O/_______
app_1  | [08:43:34][REALIZE] :                                     O\
app_1  | [08:43:34][REALIZE] : ⇨ http server started on [::]:1323

リクエストを送ってみるとレスポンスが返ってくることが確認できます。

$ curl localhost:1323
Hello, World!

ソースを更新するとホットリロードされています。

app_1  | [08:48:05][REALIZE] : GO changed /go/src/github.com/ryu022304/test-echo/main.go
app_1  | [08:48:05][REALIZE] : Install started
app_1  | [08:48:07][REALIZE] : Install completed in 2.489 s
app_1  | [08:48:07][REALIZE] : Running..
app_1  | [08:48:07][REALIZE] :    ____    __
app_1  | [08:48:07][REALIZE] :   / __/___/ /  ___
app_1  | [08:48:07][REALIZE] :  / _// __/ _ \/ _ \
app_1  | [08:48:07][REALIZE] : /___/\__/_//_/\___/ v4.1.17
app_1  | [08:48:07][REALIZE] : High performance, minimalist Go web framework
app_1  | [08:48:07][REALIZE] : https://echo.labstack.com
app_1  | [08:48:07][REALIZE] : ____________________________________O/_______
app_1  | [08:48:07][REALIZE] :                                     O\
app_1  | [08:48:07][REALIZE] : ⇨ http server started on [::]:1323

雑感

Go Modulesをちゃんと理解出来ていないので時間がかかってしまいました。精進しようと思います。