挺早之前在我写过一篇用 Docker
搭建LNMP开发环境的文章:用Docker搭建Laravel开发环境,里面详细介绍了将 nginx
、 mysql
和 php
三个容器用 docker-compose
编排成 LNMP
开发环境的步骤,今天来讲说怎么用 Docker
快速搭建 Go
语言项目的开发环境。php
由于靠Go
自己自带的标准库就能实现高性能的 HTTP
服务器,不熟悉的同窗买它,呃说错了,看它:深刻学习用Go编写HTTP服务器。因此用 Docker
构建 Go
的开发环境比构建 LNMP 开发环境要简单不少,若是没有太多定制化要求甚至都不用写 Dockerfile
本身构建镜像,直接使用官方的 golang
镜像便可。mysql
咱们使用官方最新稳定版的镜像 golang:latest
, 获取镜像前先得确保你电脑上运行了 Docker
客户端,没有的去官网下载一下吧这里就很少说了。linux
下载dockerHub
上的镜像直接使用命令:nginx
docker pull golang
复制代码
下载完镜像后用镜像运行一个容器:golang
docker run --rm -it --name go-http-demo golang bash
复制代码
上面这个命令用镜像 golang
建立了一个名为 go-http-demo
的容器,在容器中建立了一个 Bash
会话。--rm
选项指定容器退出后自动移除容器。sql
运行完上面的命令后咱们就进入了运行的容器中,运行 go version
查看如下 go
的版本:docker
root@965425c5bdcf:/go# go version
go version go1.13.6 linux/amd64
root@965425c5bdcf:/go#
复制代码
你能够根据本身的须要在https://hub.docker.com/_/golang
中查找本身须要的版本的 golang
镜像运行容器。shell
咱们使用《深刻学习用Go编写HTTP服务器》中最后写的支持优雅关停服务的 HTTPServer
的源码,将它放到 Docker
容器里伺服宿主机的请求。HTTP Server
的源码以下,想探究代码具体怎么实现的看连接里的文章就行了。浏览器
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
中,文件目录大家作的时候根据本身的状况写路径。bash
接下来就要把这个代码放到容器里去运行了,切到代码目录里执行以下命令:
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
看到下图中的页面就证实服务器在容器里已经正常运行起来了。
经过上面的内容咱们已经用 Docker
构建好了一个 Go
的开发环境,不过每次打那堆命令,还要进容器执行 go
命令启动程序太费事了,咱们用 docker-compose
把上面那些流程自动化一下。
在项目代码根目录建立docker-compose.yml
:
version: '3'
services:
app:
image: golang:latest
volumes:
- $PWD:/go/src/examplecom/http_demo
ports:
- "8000:8080"
command: go run /go/src/examplecom/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
讲的都比较深刻,例子也多,感兴趣的能够看看。
若是本身搭建环境的时候遇到什么问题了,能够在这里留言反馈,也能够在个人公众号里留言反馈。