原文连接:在 Go 语言项目中使用 Dockergit
容器(Container) 将程序及其所需的任何内容捆绑在一块儿,包括依赖项、工具和配置文件等等。这样使得程序不受环境的干扰,真正意义上作到开发环境和生成环境彻底一致。github
而 Docker 在容器的基础上,进行了进一步的封装,从文件系统、网络互联到进程隔离等等,极大的简化了容器的建立和维护。与传统虚拟机相比,Docker 也有许多优势,如:更高效的系统资源利用和更快速的启动时间。golang
在本文中,经过一个简单的 Go 语言项目,您将学习如何在 Go 语言项目中使用 Docker。docker
让咱们来建立一个做为示例的 Go 语言项目。在命令行下输入如下命令以建立文件夹:shell
mkdir gdp
咱们将使用 Go Module 进行依赖性管理。转到项目的根目录,而后初始化 Go Module:服务器
cd gdp go mod init github.com/linehk/gdp
咱们将建立一个简单的 hello 服务器。在项目根目录中建立一个名为 hello_server.go 的新文件:网络
touch hello_server.go
文件内容以下:app
package main import ( "fmt" "log" "net/http" "time" "github.com/gorilla/mux" ) func handler(w http.ResponseWriter, r *http.Request) { query := r.URL.Query() name := query.Get("name") if name == "" { name = "Guest" } log.Printf("Received request for %s.\n", name) w.Write([]byte(fmt.Sprintf("Hello, %s!\n", name))) } func main() { r := mux.NewRouter() r.HandleFunc("/", handler) server := &http.Server{ Handler: r, Addr: ":8080", ReadTimeout: 10 * time.Second, WriteTimeout: 10 * time.Second, } log.Println("Starting Server.") if err := server.ListenAndServe(); err != nil { log.Fatal(err) } }
该项目使用 gorilla/mux 包来建立 HTTP 路由(导入包是为了展现 Docker 容器捆绑依赖项的做用),地址是 localhost:8080。curl
让咱们先尝试在本地编译和运行项目。能够在项目根目录输入如下命令来编译项目:工具
go build
go build 命令将会生成一个名为 gdp 的可执行文件。能够像这样运行该文件:
./gdp 2020/08/19 21:33:49 Starting Server.
咱们的 hello 服务器如今正在运行,能够尝试使用 curl 或其它工具与其交互:
curl http://localhost:8080 Hello, Guest!
curl http://localhost:8080?name=sulinehk Hello, sulinehk!
让咱们来为这个项目编写 Dockerfile,在根目录建立文件名为 Dockerfile 的文件,内容以下:
# 拉取 Go 语言最新的基础镜像 FROM golang:latest # 在容器内设置 /app 为当前工做目录 WORKDIR /app # 把文件复制到当前工做目录 COPY . . # 设置 GOPROXY 环境变量 ENV GOPROXY="https://goproxy.cn" # 下载所有依赖项 RUN go mod download # 编译项目 RUN go build -o gdp . # 暴露 8080 端口 EXPOSE 8080 # 执行可执行文件 CMD ["./gdp"]
镜像(Image) 是实际的软件分发包,其中包含运行应用程序所需的全部内容。
而容器根据镜像构建,是镜像的运行示例,相似 Go 语言中结构体定义和结构体变量之间的关系。
docker build -t gdp .
docker run -d -p 8080:8080 gdp aa6a1afbe1b13ad0b0d1d656e157f762c5fe2229a8e0d95a025df26396ffc08f
curl http://localhost:8080 Hello, Guest!
curl http://localhost:8080?name=sulinehk Hello, sulinehk!
下面是一些其它的 Docker 命令:
能够看出,一个定义良好的 Dockfile 文件在整个流程中起到承上启下的做用。