Gin + Nginxで仕事でも使えるかな、と思いつつ開発環境を作成する
ソースはこちら
環境
Go 1.14
Gin 1.5.0
Docker 19.03.8
docker-compose 1.25.4
やること
- GinでREST APIを作成
- realizeでホットリロードできるようする
- docker-composeでNginxを立ててリバプロする
GinでREST APIを作成
GETでリクエストがきたら、 {"key":"value"}
を返すだけのコードを作成
package main
import "github.com/gin-gonic/gin"
func main() {
router := gin.Default()
router.GET("/api", func(context *gin.Context) {
context.JSON(200, gin.H{
"key": "value",
})
})
router.Run()
}
realizeでホットリロードできるようする
変更後にgo run main.go
をするのが面倒なので、ホットリロードをできるようにする
realizeをInstallする
go get github.com/oxequa/realize
main.goがあるディレクトリで
realize start
をすると、そのディレクトリに.realize.yaml
が作成される
settings:
legacy:
force: false
interval: 0s
schema:
- name: src
path: .
commands: {}
watcher:
extensions:
- go
paths:
- /
ignored_paths:
- .git
- .realize
- vendor
このままでは、watch状態にならないようなので、以下に変更する
settings:
legacy:
force: false
interval: 0s
schema:
- name: src
path: .
commands:
run:
status: true
watcher:
extensions:
- go
paths:
- /
ignored_paths:
- .git
- .realize
- vendor
そして再度実行すると、起動ログが出力される
realize start
[21:15:11][SRC] : Watching 1 file/s 1 folder/s
[21:15:11][SRC] : Install started
[21:15:12][SRC] : Install completed in 0.946 s
[21:15:12][SRC] : Running..
[21:15:12][SRC] : [GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
[21:15:12][SRC] : [GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
[21:15:12][SRC] : - using env: export GIN_MODE=release
[21:15:12][SRC] : - using code: gin.SetMode(gin.ReleaseMode)
[21:15:12][SRC] : [GIN-debug] GET /api --> main.main.func1 (3 handlers)
[21:15:12][SRC] : [GIN-debug] Environment variable PORT is undefined. Using port :8080 by default
[21:15:12][SRC] : [GIN-debug] Listening and serving HTTP on localhost:8080
この状態で、コードの変更をすると変更を検知してリロードが走る
Dockerリバプロの設定
localhost:80でリクエストがあると、Nginxが3000番ポートへ流す構成にする
Gin環境のDockerfileとコードを少し改変
FROM golang:latest
RUN go get -u github.com/gin-gonic/gin && \
go get -u github.com/oxequa/realize
WORKDIR /go/src/github.com/gin-nginx-sample/src
CMD [ "realize", "start"]
3000番ポートで起動するように変更
(一応ログファイルも出るようにして、リクエストIDを表示するだけのmiddlewareも書いてみた)
package main
import (
"github.com/gin-gonic/gin"
"github.com/labstack/gommon/log"
"io"
"os"
)
func main() {
file, _ := os.Create("gin.log")
gin.DefaultWriter = io.MultiWriter(file)
log.SetOutput(gin.DefaultWriter)
router := gin.Default()
router.GET("/api", myMiddleware(), func(context *gin.Context) {
context.JSON(200, gin.H{
"key": "value",
})
})
router.Run(":3000")
}
func myMiddleware() gin.HandlerFunc {
return func(context *gin.Context) {
header := context.GetHeader("X-REQUEST-ID")
log.Print("RequestId=" + header)
context.Next()
}
Nginx環境のDockerfile
自分で書いたnginx.conf
をnginx.confに上書きする
FROM nginx:latest
COPY ./nginx-docker/nginx.conf /etc/nginx/nginx.conf
worker_processes auto;
events {
worker_connections 1024;
}
http {
server {
listen 80;
location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_pass http://golang:3000;
}
}
}
docker-composeをかく
2つのDockerfile
を読み込んでdocker-composeを設定する
version: '3'
services:
golang:
container_name: "gin-nginx-sample"
tty: true
build:
context: .
dockerfile: ./go-docker/Dockerfile
volumes:
- ./src:/go/src/github.com/gin-nginx-sample/src
ports:
- "3000"
nginx:
container_name: "nginx"
build:
context: .
dockerfile: ./nginx-docker/Dockerfile
ports:
- "80:80"
depends_on:
- "golang"
確認
-
locahost:80/api
でアクセスしたら、{"key":"value"}
が返ってる -
main.go
を変更して、ホットリロードが動く
これらができたら、成功!
まとめ
普段意識して触ることのない技術スタックだったため、これだけの半日かかりました
もっと良い方法があったらぜひコメントください
参考