GoDocker教程展示了如何将Docker用于Golang应用程序。
应用程序容器化是一种操作系统级别的虚拟化方法,用于部署和运行分布式应用程序,而无需为每个应用程序创建一个完整的虚拟机。使用容器,可以在单个主机上运行多个隔离的应用程序或服务并访问相同的操作系统内核。容器可在裸机系统、云实例或虚拟机上运行。
泊坞窗
Docker是一个供开发人员和系统管理员使用容器构建、运行和共享应用程序的平台。Docker促进了应用程序的可移植性和可扩展性。Docker提供了应用程序隔离,从而消除了由库和环境差异引起的许多问题。它有助于自动化开发和部署。借助预定义的社区图像,开发人员可以节省时间并改善他们的整体体验。
Docker镜像是一个只读模板,其中包含创建Docker容器的说明。Docker容器是图像的可运行实例。
Docker图像存储在存储库中。DockerHub是官方的Docker存储库。Docker引擎是使用Docker的组件和服务构建和运行容器的底层客户端-服务器技术。
Dockerfile是一个特殊文件,其中包含构建Docker映像所需的指令。
$ docker --version Docker version 20.10.17, build 100c701
这是我们使用的Docker版本。
$ go version go version go1.18.1 linux/amd64
我们使用Go版本1.18。
GoDockerhello示例
在下面的例子中,我们创建并运行了一个非常简单的Docker镜像。当我们运行图像时,将执行一个简单的Go应用程序。
package main import ( "fmt" "runtime" ) func main() { fmt.Println("Hello there!") osv := runtime.GOOS fmt.Printf("The OS is: %s\n", osv) }
这是一个简单的控制台应用程序,它会打印一条消息和底层操作系统的版本。
# syntax=docker/dockerfile:1 FROM golang:1.18 WORKDIR /app COPY go.mod . RUN go mod download COPY *.go . RUN go build -o /hello CMD [ "/hello" ]
Dockerfile
是构建镜像的一系列命令。
# syntax=docker/dockerfile:1
第一行是一个可选的语法分析器指令。该指令指示Docker构建器在解析Dockerfile时使用什么语法。
FROM golang:1.18
我们的形象基于社区golang:1.18
。
WORKDIR /app
我们需要设置一个构建目录。WORKDIR
命令指示Docker使用指定目录作为所有后续命令的默认目标。
COPY go.mod .
我们使用COPY
将go.mod
文件复制到我们的项目目录(/app)。
RUN go mod download
使用RUN
指令,我们运行gomoddownload
命令下载我们的Go模块。
COPY *.go .
使用COPY
命令,我们将Go源代码复制到构建目录中。
RUN go build -o /hello
我们构建Go程序。我们将可执行文件放在文件系统的根目录下。
CMD [ "/hello" ]
通过CMD
命令,我们告诉Docker在使用我们的映像启动容器时执行什么命令。
$ docker build -t hello .
我们构建图像并将其命名为hello
。
$ docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE hello latest 1525ae981450 52 seconds ago 966MB docker/getting-started latest cb90f98fd791 8 weeks ago 28.8MB
我们使用dockerimagels
命令列出可用的图像。
$ docker run hello Hello there! The OS is: linux
我们运行hello图像。
多阶段构建
多阶段构建允许使用多个图像来构建最终产品。在多阶段构建中,我们在单个Dockerfile中有多个图像。
$ docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE hello latest 1525ae981450 52 seconds ago 966MB docker/getting-started latest cb90f98fd791 8 weeks ago 28.8MB
当我们查看hello图像的大小时,我们注意到它相当大。这是因为该图像包含构建应用程序所需的所有Go工具和库。然而,一旦构建了一个应用程序,这些可能就不再需要了。为了解决这个问题,我们使用多阶段构建。
package main import ( "fmt" "runtime" ) func main() { fmt.Println("multi-stage build") osv := runtime.GOOS fmt.Printf("The OS is: %s\n", osv) }
我们有相同的控制台应用程序。
# syntax=docker/dockerfile:1 # Build FROM golang:1.18 AS build WORKDIR /app COPY go.mod . RUN go mod download COPY *.go . RUN go build -o /hello # Deploy FROM scratch WORKDIR / COPY --from=build /hello /hello CMD [ "/hello" ]
现在,我们有两个FROM
命令形成两个阶段。
FROM golang:1.18 AS build
通过AS
指令,我们创建了一个名为build
的阶段。
FROM scratch
我们为下一阶段使用最小的scratch
图像。
COPY --from=build /hello /hello
我们从构建阶段复制构建程序。
CMD [ "/hello" ]
最后,我们设置要运行的程序。
$ docker build -t hello:multistage .
我们构建图像并为其赋予multistage
标签。
$ docker run hello:multistage multi-stage build The OS is: linux
我们运行新图像。
$ docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE hello multistage 28c2d0b534eb 6 minutes ago 1.77MB hello latest 1525ae981450 23 minutes ago 966MB docker/getting-started latest cb90f98fd791 8 weeks ago 28.8MB
大小差别很大。
GoDocker回显示例
在下一个示例中,我们将使用echo框架创建一个简单的Web应用程序。
package main import ( "net/http" "github.com/labstack/echo/v4" ) func main() { e := echo.New() e.GET("/", func(c echo.Context) error { return c.String(http.StatusOK, "Hello there!") }) e.Logger.Fatal(e.Start(":8080")) }
应用程序有一个文本端点。它在端口8080上侦听。
# syntax=docker/dockerfile:1 # Build FROM golang:1.18 AS build WORKDIR /app COPY go.mod . COPY go.sum . RUN go mod download COPY *.go . RUN go build -o /hello # Deploy FROM debian:latest WORKDIR / COPY --from=build /hello /usr/local/bin/hello EXPOSE 8080 ENTRYPOINT [ "/usr/local/bin/hello" ]
EXPOSE
指令通知Docker容器在运行时监听指定的网络端口。
FROM debian:latest
我们的镜像基于Debian镜像。
$ docker build -t web .
Web构建图像。
$ docker run -p 8080:8080 web ____ __ / __/___/ / ___ / _// __/ _ \/ _ \ /___/\__/_//_/\___/ v4.7.2 High performance, minimalist Go web framework https://echo.labstack.com ____________________________________O/_______ O\ ⨠http server started on [::]:8080
我们运行图像。容器的8080端口映射到我们电脑的8080端口。
$ curl localhost:8080 Hello there!
我们使用curl创建一个GET请求。
在本教程中,我们使用了Go和Docker。
列出所有Go教程。