使用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)

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

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

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏杨建荣的学习笔记

使用shell定制awr脚本(r3笔记第32天)

大家在做性能问题诊断的时候,awr是不可或缺的工具,使用?/rdbms/admin/awrrpt.sql可能大家使用的多了,可能有时候感觉输入参数还是有些太繁琐...

2844
来自专栏程序员同行者

Docker部署Vue 工程包

这样前端工程镜像就build好了,可以执行docker run -d -p9528:9528 dist:v0.1启动

1282
来自专栏乐沙弥的世界

CRS-1006 , CRS-0215 故障一例

    安装好sles 10 sp3 + Oracle 10g RAC之后,在配置监听器时,总是提示主机bo2dbp上的监听服务已经在运行,忽略错误之后手动在b...

623
来自专栏散尽浮华

openstack虚拟机迁移的操作记录

需求说明: 计算节点linux-node1.openstack:192.168.1.8   计算节点linux-node2.openstack:192.168....

7539
来自专栏圣杰的专栏

.NET Core+MySql+Nginx 容器化部署

1. 引言 上两节我们通过简单的demo学习了docker的基本操作。这一节我们来一个进阶学习,完成ASP.NET Core + MySql + Nginx的容...

4348
来自专栏乐沙弥的世界

Oracle 11g RAC CRS-4535/ORA-15077

    新安装了Oracle 11g rac之后,不知道是什么原因导致第二个节点上的crsd无法启动?其错误消息是CRS-4535: Cannot commun...

903
来自专栏从零开始的linux

redis主从

主机名ipnode01(主)192.168.6.71node02(从)192.168.6.72 分别在两台机器上面安装redis wget https://c...

3708
来自专栏运维

linux下连接windows2003 ppoe 服务器

1,在CentOS6.3下用 /usr/sbin/pppd  pty "/usr/sbin/pptp publicip --nolaunchpppd" f...

1312
来自专栏康怀帅的专栏

Docker 相关概念总览

Docker 概念总览 Docker Engine Docker 引擎 Docker architecture Docker 架构 Docker daemon ...

4068
来自专栏木制robot技术杂谈

Ubuntu 使用 Docker 安装 Gitlab

最近帮公司重新搭建了 Gitlab,中间遇到了一些坑,折腾了不少时间,在此记录供大家参考。

3264

扫码关注云+社区

领取腾讯云代金券