为你的 Go 后端创建 Dockerfile
由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!
这是一份面向零基础初学者的分步指南,教你如何为 Go 后端创建 Docker 镜像。本文将指导你从头开始构建 Docker 镜像,并部署和运行你的 Go 应用。GitHub 仓库的完整源代码在此。
先决条件
- 安装 Go 版本
1.21.0或更高版本。访问Go 下载页面安装工具链。 - 对 Golang 基础知识有基本的了解。
- Docker 正在本地运行,请从这里安装 Docker 。
- 一个集成开发环境/文本编辑器和一个命令行终端应用程序。
创建 Go 后端
在本教程中,我将使用该Echo框架构建后端。您可以Echo 在这里了解更多信息。
您可以自由地使用或不使用框架来创建自己的后端。
以下是一个示例main.go文件:
package main
import (
"net/http"
"os"
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
)
func main() {
e := echo.New()
// Middleware
e.Use(middleware.Logger())
e.Use(middleware.Recover())
e.GET("/", func(c echo.Context) error {
return c.String(http.StatusOK, "Hello, World!")
})
e.GET("/health", func(c echo.Context) error {
return c.String(http.StatusOK, "Health is OK!!")
})
httpPort := os.Getenv("PORT")
if httpPort == "" {
httpPort = "8080"
}
e.Logger.Fatal(e.Start(":" + httpPort))
}
如您所见,我们有两个端点,
/返回Hello, World!/health返回Health is OK!!
别忘了在文件
PORT中添加.env:
PORT=8000
您还应该使用以下命令在当前目录中初始化新模块:
go mod init <your-module-package>
要添加文件中提到的依赖项main.go,请使用以下命令。
go mod tidy
测试您的应用程序
让我们启动应用程序,并确保它运行正常。
go run main.go
让我们来试用一下我们的应用程序:
$ curl http://localhost:8080/
$ curl http://localhost:8080/health
你应该得到以下输出:
Hello, World!
Health is OK!!
创建 Dockerfile
以下是完整的 Dockerfile 文件及其说明。
# syntax=docker/dockerfile:1
FROM golang:1.21.0
# Set destination for COPY
WORKDIR /app
# Download Go modules
COPY go.mod go.sum ./
RUN go mod download
# Copy the source code. Note the slash at the end, as explained in
# https://docs.docker.com/engine/reference/builder/#copy
COPY *.go ./
# Build
RUN CGO_ENABLED=0 GOOS=linux go build -o /docker-gs-ping
# Optional:
# To bind to a TCP port, runtime parameters must be supplied to the docker command.
# But we can document in the Dockerfile what ports
# the application is going to listen on by default.
# https://docs.docker.com/engine/reference/builder/#expose
EXPOSE 8080
# Run
CMD ["/docker-gs-ping"]
构建 Docker 镜像
创建 Dockerfile 之后,现在就可以使用命令从中构建 Docker 镜像了build。
构建命令可以选择性地接受一个--tag标志。该标志用于为镜像添加一个易于人类阅读和识别的字符串标签。如果不传递该标志--tag,Docker 将使用latest默认值。
让我们构建 Docker 镜像!
请在根目录下运行以下命令。
docker build --tag echo .
瞧!我们为后端构建了一个 Docker 镜像。
要列出镜像,请使用docker image ls命令或docker images命令。
运行 Docker 镜像
要运行 Docker 镜像,我们可以使用以下docker run命令:
docker run <image-name>
就我而言,命令大概是这样的:
docker run echo
瞧!我们的服务器已经启动并运行了;但是等等,如果您现在尝试访问您的某个端点,将会收到以下错误:
无法连接到本地主机端口 8080:连接被拒绝
所以,我们需要将主机上的 8080 端口暴露给其他服务器。为此,您只需执行以下操作:
docker run -p 8080:8080 echo
现在让我们重新运行 curl 命令
$ curl http://localhost:8080/
Hello, World!
成功!我们已成功连接到运行在容器内 8080 端口的应用程序。按Ctrl + C停止容器。
要列出所有图像,您可以尝试该命令docker image ls,您会发现我们的图像非常大。
正如@sibprogrammer在评论中提到的,减少文件大小的一种常见方法是使用多阶段构建。
感谢@sibprogrammer提供详细信息:
常用的方法是使用多阶段构建。Go 是一种编译型语言,运行服务不需要 Go 工具链。因此,其基本思路是:在一个阶段构建二进制文件,然后使用另一个最小化的镜像来启动它。这带来了巨大的差异。最新的“golang”镜像大约有 800 MB(基于 Debian),而最终的服务镜像可能只有 5-10 MB。
以下是一个示例:
FROM golang:1.15 as builder
ARG CGO_ENABLED=0
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN go build
FROM scratch
COPY --from=builder /app/server /server
ENTRYPOINT ["/server"]