专栏首页Golang语言社区使用Docker和热加载运行Go API

使用Docker和热加载运行Go API

原文作者:Sun

This is a quick discussion of how to set up a local development environment for a Go API running inside of a Docker container with hot reloading. I’ve found this to be an effective way to develop locally. The full source code can be found on GitHub.

API

We’ll first set up a dummy API in cmd/api/main.go:

 1package main
 2
 3import (
 4    "fmt"
 5    "log"
 6    "net/http"
 7)
 8
 9func handler(w http.ResponseWriter, r *http.Request) {
10    fmt.Fprint(w, "Hello from the api!")
11}
12
13func main() {
14    http.HandleFunc("/", handler)
15    log.Println("listening on 5000")
16    log.Fatal(http.ListenAndServe(":5000", nil))
17}

This API simply listens on the root path and returns a hello world back out.

Good enough for this example!

Dockerfile

The next thing we need is a Dockerfile to define how we want to build our container for this Go API:

FROM golang:1.10

WORKDIR /go/src/github.com/Zach-Johnson/go-docker-hot-reload-example

COPY . .

RUN ["go", "get", "github.com/githubnemo/CompileDaemon"]

ENTRYPOINT CompileDaemon -log-prefix=false -build="go build ./cmd/api/" -command="./api"

  • First we set the base image for the Dockerfile to Go 1.10.
  • WORKDIR sets the current working directory within the container to the path for this example repository.
  • Then the COPY command copies everything in the current context directory to the container. We’re going to use a docker-compose file for this, so the context directory will be whatever we define it to be in the docker-compose file or the directory we run the docker-compose command from by default.
  • I’m using a hot reloader called CompileDaemon. There are a variety of hot reloaders for Go apps - I chose to use CompileDaemon because of the simplicity and it played nice with Docker out of the box.
  • The ENTRYPOINT defines the command that will be ran when the container starts up. Here we run the CompileDaemon command - it has a variety of optional flags, but runs a go build by default. I explicitly specify a go build command here to build from the directory I want and then execute the binary so that the server starts up. CompileDaemon handles the rest - anytime any .go file changes in the directory, it will terminate the server and re-run the build steps. The file types that it watches for can also be modified as needed with the -pattern flag. Sweet!

docker-compose

A docker-compose file can simplify orchestration between Docker containers. For this example it’s a bit contrived since we’re only running one service, but often times it makes things much nicer when running multiple microservices and perhaps a database locally.

1version: '3.6'
2
3services:
4    api:
5        image: api:latest
6        ports:
7            - 5000:5000
8        volumes:
9            - ./:/go/src/github.com/Zach-Johnson/go-docker-hot-reload-example

We first specify the image to use; the latest image of the API that will be created when we build the Docker image from our Dockerfile. We expose port

5000 and map it to port 5000 on the Docker container so that we can reach our API from outside of the Docker container. The last line is a volume mount. This is what makes the hot reloading work inside of a Docker container! This links our current working directory to the directory inside of the Docker container so that any file changes that happen on our local machine also happen inside of the Docker container. Since CompileDaemon is running inside of the Docker container, when it sees a file change inside the container, it can then re-build and re-run the server.

Makefile

Lastly we write a little Makefile to simplify server start up and shutdown:

 1default:
 2    @echo "=============building Local API============="
 3    docker build -f cmd/api/Dockerfile -t api .
 4
 5up: default
 6    @echo "=============starting api locally============="
 7    docker-compose up -d
 8
 9logs:
10    docker-compose logs -f
11
12down:
13    docker-compose down
14
15test:
16    go test -v -cover ./...
17
18clean: down
19    @echo "=============cleaning up============="
20    rm -f api
21    docker system prune -f
22    docker volume prune -f

Our default command simply builds the Dockerfile for the API. The up command starts up the API and runs it in the background. logs tails the logs on the Docker container. down shuts down the server. test runs any tests in the current directory tree. clean shuts down the API and then clears out saved Docker images from your computer. This can be useful when running another image like MySQL which writes information to your local machine and doesn’t clean it up when the container shuts down.

Closing Thoughts

I’ve found this to be an effective way to develop locally when running multiple APIs that are interacting with a DB of some sort. It can be a simple way to run integration tests as well: by keeping your infrastructure running locally inside of containers, you can run make test and execute all of your integration tests against your local infrastructure. Then any code changes you make get hot reloaded, but the Docker images don’t have to rebuild, so it is much quicker than having a separate test suite that has to build and run all of your infrastructure each time you want to change something.


版权申明:内容来源网络,版权归原创者所有。除非无法确认,我们都会标明作者及出处,如有侵权烦请告知,我们会立即删除并表示歉意。谢谢。

本文分享自微信公众号 - Golang语言社区(Golangweb)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-08-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Golang memory model

    Introduction The Go memory model specifies the conditions under which reads of a...

    李海彬
  • go http 服务器编程(2)

    match 会遍历路由信息字典,找到所有匹配该路径最长的那个。路由部分的代码解释就到这里了,最后回答上面的一个问题:http.HandleFunc 和 Serv...

    李海彬
  • 阅读源代码的姿势:以 go-restful 为例

    一般初学者确定一个方向,比如web 后端、前端等,会选择一门编程语言深入下去,比如后端java、python、go等。通过项目不断练习编程语言和编程思维,知道如...

    李海彬
  • 上传到App Store 含第三方支付被3.1.1被拒解决方案

    最近在做项目时,涉及用户付费。于是就找来了支付宝和微信支付的集成教程,按照要求分别开通各自开发平台的开发者账号和商户号。在后台加入了支付的支持,一步步的集成和测...

    jiang chen
  • CNCF大使档案:TiKV的Queeny Jin

    Our first ambassador spotlight goes to Queeny Jin, who has been spreading the wo...

    CNCF
  • 并行处理器调度:采用基于感知推理的多目标语言优化求解方法(CS AI)

    在工业4.0时代,几乎所有的工业和制造企业都把重心放在了将人的因素最小化,自动化过程最大化智商。这些企业包含许多处理系统,这些处理系统可以使用最少数量的人并行地...

    奥斯特洛夫斯萌
  • Configuring Spring Boot's Server, GZip compression, HTTP/2

    Spring Boot is powerful yet flexible. It tries to auto-configure most of the stu...

    heidsoft
  • Codeforces 706B Interesting drink

    B. Interesting drink time limit per test:2 seconds memory limit per test:256 meg...

    Angel_Kitty
  • Building a Middle Tier Component using NHibernate and Spring.NET

    http://www.codeproject.com/csharp/SpringPlusHibernate.asp Download demo project ...

    张善友
  • 仅用四行代码实现RNN文本生成模型

    文本生成(generating text)对机器学习和NLP初学者来说似乎很有趣的项目之一,但也是一个非常困难的项目。值得庆幸的是,网络上有各种各样的优秀资源,...

    用户3578099

扫码关注云+社区

领取腾讯云代金券