挺早以前在我写过一篇用 `Docker`搭建LNMP开发环境的文章:[用Docker搭建Laravel开发环境](http://mp.weixin.qq.com/s?__biz=MzUzNTY5MzU2MA==&mid=2247483807&idx=1&sn=061f9a4f6711d7c4550c4f9012d9ad4e&chksm=fa80d008cdf7591edd2373aae91c76b4b13ec8a30a6f55d4f851556a288ca4c25f428910ddd3&scene=21#wechat_redirect),里面详细介绍了将 `nginx`、 `mysql`和 `php`三个容器用 `docker-compose`编排成 `LNMP`开发环境的步骤,今天来说说怎么用 `Docker`快速搭建 `Go`语言项目的开发环境。

因为靠`Go`本身自带的标准库就能实现高性能的 `HTTP`服务器,不熟悉的同学买它,呃说错了,看它:[深入学习用Go编写HTTP服务器](http://mp.weixin.qq.com/s?__biz=MzUzNTY5MzU2MA==&mid=2247484112&idx=1&sn=79d0d3167d0d962fe41ec00cdafffbb0&chksm=fa80d347cdf75a51183182f14622af766538ca0c5335012e5e1cc50b100e78f2954fa3943770&scene=21#wechat_redirect)。所以用 `Docker` 构建 `Go`的开发环境比构建 LNMP 开发环境要简单很多,如果没有太多定制化要求甚至都不用写 `Dockerfile`自己构建镜像,直接使用官方的 `golang`镜像即可。

### 获取Docker镜像

我们使用官方最新稳定版的镜像 `golang:latest`, 获取镜像前先得确保你电脑上运行了 `Docker` 客户端,没有的去官网下载一下吧这里就不多说了。

下载`dockerHub`上的镜像直接使用命令:

```shell
docker pull golang
```

下载完镜像后用镜像运行一个容器:

```shell
docker run --rm -it --name go-http-demo golang bash
```

上面这个命令用镜像 `golang`创建了一个名为 `go-http-demo`的容器,在容器中创建了一个 `Bash`会话。`--rm`选项指定容器退出后自动移除容器。

运行完上面的命令后我们就进入了运行的容器中,运行 `go version` 查看以下 `go`的版本:

```
root@965425c5bdcf:/go# go version
go version go1.13.6 linux/amd64
root@965425c5bdcf:/go#
```

你可以根据自己的需要在`https://hub.docker.com/_/golang` 中查找自己需要的版本的 `golang`镜像运行容器。

### 在容器中运行Go项目

我们使用《[深入学习用Go编写HTTP服务器](http://mp.weixin.qq.com/s?__biz=MzUzNTY5MzU2MA==&mid=2247484112&idx=1&sn=79d0d3167d0d962fe41ec00cdafffbb0&chksm=fa80d347cdf75a51183182f14622af766538ca0c5335012e5e1cc50b100e78f2954fa3943770&scene=21#wechat_redirect)》中最后写的支持优雅关停服务的 `HTTPServer`的源码,将它放到 `Docker`容器里伺服宿主机的请求。`HTTP Server`的源码如下,想探究代码具体怎么实现的看链接里的文章就好了。

```go
package main

import (
"context"
"fmt"
"log"
"net/http"
"os"
"os/signal"
"syscall"
)

func main() {
mux := http.NewServeMux()
mux.Handle("/", &helloHandler{})

server := &http.Server{
Addr: ":8080",
Handler: mux,
}

// 创建系统信号接收器
done := make(chan os.Signal)
signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
go func() {
<-done

if err := server.Shutdown(context.Background()); err != nil {
log.Fatal("Shutdown server:", err)
}
}()

log.Println("Starting HTTP server...")
err := server.ListenAndServe()
if err != nil {
if err == http.ErrServerClosed {
log.Print("Server closed under request")
} else {
log.Fatal("Server closed unexpected")
}
}
}

type helloHandler struct{}

func (*helloHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello World")
}
```

把源码放在本地电脑的 `/Code/go/src/example.com/http-demo/main.go`中,文件目录你们做的时候根据自己的情况写路径。

接下来就要把这个代码放到容器里去运行了,切到代码目录里执行如下命令:

```
docker run --rm -it --name go-http-demo \
-v $PWD:/go/src/example.com/go-http-demo \
-p 8000:8080
golang
```

`-v`选项允许我们挂载多个本地目录或者数据卷到容器中,更改会在容器内外相互同步,上面的命令将 `/Code/go/src/example.com/go-http-demo/`挂载到了容器的 `/go/src/example.com/go-http-demo`。

`-p`指定主机和容器的端口映射,因为代码里 `HTTP`服务是监听 `8080`端口的,所以我们将主机的 `8000`端口和容器的 `8080`端口做了映射。

执行完上面的命令,我们切换到到容器里的 `Bash`会话,切到代码目录运行 `go run main.go`后,在自己的电脑上打开浏览器访问 `http:localhost:8080`看到下图中的页面就证明服务器在容器里已经正常运行起来了。

![](https://user-gold-cdn.xitu.io/2020/1/30/16ff47b8a056fb09?w=1000&h=750&f=png&s=13544)

### 用 docker-compose 管理容器

通过上面的内容我们已经用 `Docker`构建好了一个 `Go`的开发环境,不过每次打那堆命令,还要进容器执行 `go`命令启动程序太费事了,我们用 `docker-compose`把上面那些流程自动化一下。

在项目代码根目录创建`docker-compose.yml`:

```
version: '3'
services:
app:
image: golang:latest
working_dir: /go/src/example.com/http_demo
volumes:
- /$GOPATH/src/example.com/http_demo:/go/src/example.com/http_demo
- /$GOPATH/src:/go/src
ports:
- "8000:8080"
environment:
WORKING_DIR: /go/src/example.com/http_demo
command: go run /go/src/example.com/http_demo/main.go
```

如果你们项目里不允许就找个目录放这个文件,我自己就是单独有个目录里面放了好几个项目的 `Docker`配置文件,有 `PHP`项目的也有 `Go`项目的。

上面的编排文件里只定义了一个叫 `app`的服务,其他的也很容易理解我就不说了,唯一要注意的一点就是如果 `yml`文件在项目外 `volumes`里的配置就换成绝对路径不要用 `$PWD`了

接下来启动 `docker-compose`:

```
docker-compose up -d
```

如果启动不成功先不要在 `daemon`模式下运行把 `-d`去掉,就能看到具体什么错误,等调试正常了再后台启动。

代码有修改后,需要重新编译项目,针对我们的容器执行下面的命令即可

```
docker-compose restart
```

想要进入运行的容器中执行操作使用命令:

```
docker exec -it <container name> bash
```

给我们创建的 `app`发送 `go test`命令让它在容器内执行:

```
docker-compose exec app go test
```

最近想尝试把老项目换成用 `go mod`管理,项目还是在用 `go1.12`所以我就先用 `Docker`搭环境,容器隔离的环境怎么瞎折腾也没事。今天做的这个开发环境还是很简单的,没有用 `Dockerfile`自己创建镜像, `docker-compose`配置文件里的设置也很简单,后面用着不顺手有更新了我再推送。下面的两篇老文章对 `Docker`镜像和 `docker-compose`讲的都比较深入,例子也多,感兴趣的可以看看。

[教你如何做出想要的PHPDocker镜像](http://mp.weixin.qq.com/s?__biz=MzUzNTY5MzU2MA==&mid=2247483850&idx=1&sn=fa469ad6b5688452f0dc46aee7ec042a&chksm=fa80d05dcdf7594ba178189a7f61b0c134fc1274a2012d0fa40512d998bf2b6d5e375cfc9f36#rd)

[用Docker搭建Laravel开发环境](http://mp.weixin.qq.com/s?__biz=MzUzNTY5MzU2MA==&mid=2247483807&idx=1&sn=061f9a4f6711d7c4550c4f9012d9ad4e&chksm=fa80d008cdf7591edd2373aae91c76b4b13ec8a30a6f55d4f851556a288ca4c25f428910ddd3#rd)

如果自己搭建环境的时候遇到什么问题了,可以在这里留言反馈,也可以在我的公众号里留言反馈。

![](https://user-gold-cdn.xitu.io/2020/1/28/16fea461218705c6?w=450&h=518&f=png&s=35436)

五分钟用Docker快速搭建Go开发环境的更多相关文章

  1. 使用Docker快速搭建PHP开发环境

    最近有个同事找过来,希望我对在很早之前写的一个PHP网站上增加一些功能,当时开发使用xampp构建的本地开发环境,但是现在我的笔记本电脑已经更新,没有当时的开发环境.本着尽量不往电脑上装无用软件的原则 ...

  2. Docker 快速搭建 MySQL8 开发环境

    使用 Docker 快速搭建一个 MySQL8 开发环境 步骤 获取镜像 docker pull mysql:8 启动容器,密码 123456,映射 3306 端口 docker run --name ...

  3. 在win10下使用docker快速搭建ruby开发环境

    docker在windows下发力的时候必将取代各种虚拟机,并改变程序员的开发习惯,或许还会改变infra的工作. 概要: 在Windows下搭建开发环境一直是infra(我)头疼的事情.为了解决这个 ...

  4. 使用Docker快速搭建Tensorflow开发环境

    当我刚开始学习使用scikit-learn时,总是会出现各种各样的包依赖问题,兜兜转转了一遍才全部安装好,现在的机器学习算法开发者大都使用tensorflow.pytorch来实现自己的想法,但依然会 ...

  5. 一文教您如何通过 Docker 快速搭建各种测试环境(Mysql, Redis, Elasticsearch, MongoDB) | 建议收藏

    欢迎关注个人微信公众号: 小哈学Java, 文末分享阿里 P8 高级架构师吐血总结的 <Java 核心知识整理&面试.pdf>资源链接!! 个人网站: https://www.ex ...

  6. Docker-教你如何通过 Docker 快速搭建各种测试环境

    今天给大家分享的主题是,如何通过 Docker 快速搭建各种测试环境,本文列举的,也是作者在工作中经常用到的,其中包括 MySQL.Redis.Elasticsearch.MongoDB 安装步骤,通 ...

  7. CentOS 7快速搭建Nodejs开发环境

    Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的速度非常快,性能非常好.学习Nodejs首先需要会安装环境.这里我介绍如 ...

  8. Linux下快速搭建php开发环境

    php开发环境快速搭建 一.Linux下快速搭建php开发环境 1.安装XAMPP for Linux XAMPP(Apache+MySQL+PHP+PERL)是一个功能强大的建站集成软件包,使用XA ...

  9. Windows下快速搭建安卓开发环境android-studio

    Windows下快速搭建安卓开发环境android-studio 发布时间:2018-01-18 来源:网络 上传者:用户 关键字: 安卓 搭建 Android Windows 快速 环境 Studi ...

随机推荐

  1. elasticsearch用法

    基本原理 搜索引擎的索引 倒排序 由value查找key 数据库的索引 由key查找value 用于解决分库分表后的排序分页 like查找 性能问题 日志库的全文搜索 spring集成时使用的不是re ...

  2. 转:ZABBIX监控H3C设备的CPU和内存使用率

      由于最近监控的H3C路由器经常出现死机现象,SNMP获取不到数据,后面检查发现是CPU使用率过高,直接导致无法处理SNMP请求,所以需求来了,怎样通过SNMP监控H3C路由器的CPU和内存使用率? ...

  3. 多线程的lock功能

    import threading def job1(): global A, lock lock.acquire() for i in range(10): A += 1 print('job1', ...

  4. Android Studio NDK编程初探

    继上一篇学习了如何使用NDK编译FFMPEG后,接下来就是要学习如何在Android Studio中使用了. 经过参考和一系列的摸索,记录下具体步骤. 创建C++ Support的Android St ...

  5. 杂记:OSX 安装openssl

    因为工作中要用到openssl中提供的MD5.SHA等摘要算法,通过brew install openssl安装的openssl在C文件中找不到相应的头文件.按照网上的教程各种修改之后还是找不到相应的 ...

  6. AIDLservice

    有三种情况:如果直接使用服务,则没有必要进行绑定,但是如果要使用服务里面的方法,则要进行绑定.具体的启动情况有下: 其中很重要一点:bindService和unbindService是成对出现的. 1 ...

  7. 使用mysql创建自己的物化视图

    物化视图,它是用于预先计算并保存表连接或聚集等耗时较多的操作的结果,这样,在执行查询时,就可以避免进行这些耗时的操作,从而快速的得到结果.物化视图有很多方面和索引很相似:使用物化视图的目的是为了提高查 ...

  8. 在使用vue+webpack模版创建的项目中使用font-awesome

    前言:最近使用vue+webpack进行一个小项目的开发,按照官方模版文档完成项目初始化后打算引入ont-awesome字体图标库进行使用,引入过程中遇到一些问题并解决,现记录如下. 一开始进展很顺利 ...

  9. qt creator源码全方面分析(3-1)

    目录 qtcreator.pro 包含qtcreator.pri include(filename) Qt版本判断 message(string) $$运算符 error(string) 包含doc. ...

  10. 常见WAF绕过思路

    WAF分类 0x01 云waf 在配置云waf时(通常是CDN包含的waf),DNS需要解析到CDN的ip上去,在请求uri时,数据包就会先经过云waf进行检测,如果通过再将数据包流给主机. 0x02 ...