Golang使用Docker

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 .

我们使用COPYgo.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教程。

赞(0) 打赏

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏