根据Stack Overflow的2022开发者调查,Go(或Golang)是最受欢迎和最受欢迎的编程语言之一。由于与许多其他语言相比,Go的二进制大小更小,开发人员经常使用Go进行容器化应用程序开发。
Mohammad Quanit在他的社区全能课程中探索了Docker和围棋之间的联系。Mohammad分享了如何Dockerize一个基本的围棋应用程序,同时探索了过程中涉及的每个核心组件:
随着我们深入这些集装箱化步骤。我们将探索使用Go应用程序和HTTP web服务器,以及关键的最佳实践、优化技巧和增强安全性的方法。
Go应用程序组件
创建一个成熟的围棋应用程序需要您创建一些特定于围棋的组件。这些对许多围棋项目至关重要,集装箱化过程同样严重依赖于它们。现在让我们仔细看看这些。
使用main。去吧,去吧
穆罕默德主要强调主要内容。go文件,因为没有可执行代码就无法运行应用程序。在Mohammad的案例中,他创建了一个简单的web服务器,有两条独特的路径:一条具有打印功能的I/O格式,另一条返回当前时间。
穆罕默德的例子的好处是它不太长也不太复杂。您可以在创建自己的web服务器时模拟这一点,或者将其用作更多定制的垫脚石。
注意:您也可以使用包main来代替main。go文件。你不需要明确的main。为web服务器指定,因为您可以随意命名文件,但您确实需要在代码中定义一个func-main()。这存在于我们上面的示例中。
我们始终建议确认您的代码是否按预期工作。输入命令go run main。去启动你的应用程序。您也可以替换main。使用文件的特定名称。然后,打开浏览器并访问http://localhost:8081查看您的“Hello World”消息或等效消息。因为我们有两条路线,导航到http://localhost:8081/time由于Mohammad的第二个功能,显示当前时间。
接下来,我们开始了。mod文件。您将使用它作为Go包的根文件、导入的模块路径(如上所示)以及依赖性要求。Go模块还可以帮助您为项目代码选择目录。
有了这两个部分,就可以创建Dockerfile了!
创建Dockerfile
构建和部署Dockerized Go应用程序意味着从软件映像开始。虽然您可以直接从Docker Hub(使用CLI)获取此信息,但从Dockerfile开始可以为您提供更多的配置灵活性。
你可以在你喜欢的编辑器中创建这个文件,比如VS代码。我们推荐VS代码,因为它支持官方Docker扩展。此扩展支持调试、自动完成和轻松的项目文件导航。
选择一个基本映像并包含应用程序代码非常简单。由于Mohammad正在使用Go,他通过指定golang Docker官方图像作为父图像来启动Dockerfile。Docker将以此构建最终的容器映像。
你可以选择你想要的任何版本,但像golang:1.19.2牛眼这样的固定版本既稳定又苗条。像这样的新图像版本也可以安全地抵御2022年10月的Text4Shell漏洞。
您还需要在Dockerfile中执行以下操作:
包含源代码的应用程序目录
将所有内容从根目录复制到应用程序目录
将Go文件复制到应用程序目录并安装依赖项
使用配置构建应用程序
告诉Docker容器在运行时侦听某个端口
定义容器启动后运行的可执行命令
考虑到这几点,穆罕默德是如何构建他的基本Dockerfile的:
# Specifies a parent image
FROM golang:1.19.2-bullseye
# Creates an app directory to hold your app’s source code
WORKDIR /app
# Copies everything from your root directory into /app
COPY . .
# Installs Go dependencies
RUN go mod download
# Builds your app with optional configuration
RUN go build -o /godocker
# Tells Docker which network port your container listens on
EXPOSE 8080
# Specifies the executable command that runs when the container starts
CMD [ “/godocker” ]
从这里,您可以运行一个快速CLI命令从该文件构建映像:
docker build--rm-t[您的图像名称]:alpha。
这将创建一个图像,同时在整个构建过程中移除使用每个图像层(或步骤)创建的任何中间容器。您还可以用名称标记您的图像,以便以后参考。
通过运行Docker image ls命令,确认Docker成功构建了您的映像:
如果您已经在过去提取或构建了图像并保存了它们,它们也会出现在CLI输出中。然而,你可以看到穆罕默德的码头工人形象被列在最前面,因为这是最新的。
更改生产工作负载
如果您想考虑在生产Go应用程序中不可避免地发生的代码或依赖项更改,该怎么办?根据Mohammad的说法,您需要调整原始Dockerfile并添加一些说明,以便更改可见,构建过程成功:
FROM golang:1.19.2-bullseye
WORKDIR /app
# Effectively tracks changes within your go.mod file
COPY go.mod .
RUN go mod download
# Copies your source code into the app directory
COPY main.go .
RUN go mod -o /godocker
EXPOSE 8080
CMD [ “/godocker” ]
进行这些更改后,您将希望运行相同的docker build和docker image ls命令。现在,是时候运行您的新图像了!输入以下命令以从图像启动容器:
docker run -d -p 8080:8081 --name go-docker-app [YOUR IMAGE NAME]:alpha
通过输入docker-ps命令来确认这是否有效,该命令将生成容器列表。如果您安装了Docker Desktop,您也可以从Docker Dashboard访问Containers选项卡,并在列表中找到您的新容器。这也适用于您的图像构建,而不是使用“图像”选项卡。
祝贺通过跟踪Mohammad的步骤,您成功地将一个正常运行的围棋应用程序封装起来。
最佳实践和优化
当我们的围棋应用程序完成任务时,Mohammad的最终图像相当大,达到913MB。客户端(或最终用户)不必下载如此庞大的文件。
Mohammad建议使用多阶段构建,只在图像层之间向前复制所需的组件。尽管我们以golang:version作为构建者图像开始,但定义第二个构建阶段并选择像alpine这样的苗条替代方案有助于减小图像大小。你可以看到他一步步解决这个问题的方法。
这在许多用例中都是有益的和常见的。然而,通过在多阶段构建中使用FROM,您可以更进一步。这个空文件是我们提供的最小的文件,并接受静态二进制文件作为可执行文件-这使它非常适合Go应用程序开发。
您可以在Docker Hub上了解更多关于我们的scratch图像的信息。尽管在Hub上,您只能直接将scratch添加到Dockerfile中,而不是将其拉出。