0
Help us understand the problem. What are the problem?

posted at

updated at

Docker-composeを使ってGoの実行環境の作成

はじめに

Goを使ったプログラムを書きたかったのでコンテナを使い簡単に環境構築を行おうとしました。今回はホットリロード機能も付けた状態となります。備忘録としてまとめます。

構成

go
├ app
│ ├── go.mod
| ├── main.go
│ └── .air.toml
├ Dockerfile
└ docker-compose.yaml

ファイルの作成

Dockerfile

Dockerfile
# goバージョン
FROM golang:1.17.9-alpine
# アップデートとgitのインストール
RUN apk add --update &&  apk add git
# appディレクトリの作成
RUN mkdir /go/src/app
# ワーキングディレクトリの設定
WORKDIR /go/src/app
# ホストのファイルをコンテナの作業ディレクトリに移行
ADD . /go/src/app
# ホットリロード用
RUN go install github.com/cosmtrek/air@v1.27.3
CMD ["air","-c",".air.toml"]

docker-compose.yaml

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

app/go.modの配置

mkdir app && cd app
go.mod
module go_docker

go 1.14

app/.air.tomlの配置

app/.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 ."
# 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
# Add additional arguments when running binary (bin/full_bin). Will run './tmp/main hello world'.
args_bin = ["hello", "world"]

[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

ただし、この例ではapp/tmp/mainが勝手に作成されてホットリロード機能が動作するが、仕組みがよくわかっていないので、このままにしてある。

app/main.goの配置

app/main.go
package main

import "fmt"

func main() {
        fmt.Println("Hello golang from docker!")
}

コンテナの立ち上げとmain.goの実行

sudo docker-compose build
sudo docker-compose up
vpn@vpn:~/go$ docker-compose up
Creating network "go_default" with the default driver
Creating bot_go ... done
Attaching to bot_go
bot_go   |
bot_go   |   __    _   ___
bot_go   |  / /\  | | | |_)
bot_go   | /_/--\ |_| |_| \_ , built with Go
bot_go   |
bot_go   | mkdir /go/src/app/tmp
bot_go   | watching .
bot_go   | !exclude tmp
bot_go   | building...
bot_go   | running...
bot_go   | Hello golang from docker!

ここで別ターミナルを開きapp/main.goの内容を書き換える。

app/main.go
package main

import "fmt"

func main() {
        fmt.Println("Hello golang from docker air!")
}

そして先ほどのターミナルを見てみると

bot_go   | main.go has changed
bot_go   | building...
bot_go   | running...
bot_go   | Hello golang from docker air!

が追記されて正しくホットリロードが行われていることがわかる。

特定のgoファイル指定して動作させたい場合

sudo docker-compose up -d
sudo docker-compose exec goapp go run main.go

内部で入ってコマンドを実行する場合

sudo docker-compose exec goapp sh
#任意のコマンド

参考サイト

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
0
Help us understand the problem. What are the problem?