如何使用 docker init 命令对 Go 应用程序进行容器化

DockerDockerBeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

在这个实验中,你将学习如何使用 docker init 命令将一个 Go 应用程序容器化。实验首先会验证 Docker Desktop 是否在 LabEx 虚拟机 (VM) 上正确安装,包括检查 Docker 版本并运行 hello-world 容器,以确保 Docker 按预期运行。

后续步骤包括使用 docker init 初始化一个 Go 项目,针对 Go 应用程序定制生成的 Dockerfile 和 Compose 文件,最后使用 Docker Compose 构建并运行该 Go 应用程序。通过这个实践经验,你将掌握使用现代 Docker 工具对 Go 应用程序进行有效容器化的技能。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL docker(("Docker")) -.-> docker/SystemManagementGroup(["System Management"]) docker(("Docker")) -.-> docker/DockerfileGroup(["Dockerfile"]) docker(("Docker")) -.-> docker/ContainerOperationsGroup(["Container Operations"]) docker(("Docker")) -.-> docker/ImageOperationsGroup(["Image Operations"]) docker/ContainerOperationsGroup -.-> docker/run("Run a Container") docker/ContainerOperationsGroup -.-> docker/logs("View Container Logs") docker/ContainerOperationsGroup -.-> docker/create("Create Container") docker/ImageOperationsGroup -.-> docker/pull("Pull Image from Repository") docker/SystemManagementGroup -.-> docker/version("Show Docker Version") docker/DockerfileGroup -.-> docker/build("Build Image from Dockerfile") subgraph Lab Skills docker/run -.-> lab-555164{{"如何使用 docker init 命令对 Go 应用程序进行容器化"}} docker/logs -.-> lab-555164{{"如何使用 docker init 命令对 Go 应用程序进行容器化"}} docker/create -.-> lab-555164{{"如何使用 docker init 命令对 Go 应用程序进行容器化"}} docker/pull -.-> lab-555164{{"如何使用 docker init 命令对 Go 应用程序进行容器化"}} docker/version -.-> lab-555164{{"如何使用 docker init 命令对 Go 应用程序进行容器化"}} docker/build -.-> lab-555164{{"如何使用 docker init 命令对 Go 应用程序进行容器化"}} end

安装 Docker Desktop 并验证 Docker Init

在这一步中,我们将验证 Docker 是否已在 LabEx 虚拟机 (VM) 上正确安装。LabEx 虚拟机已预先安装了 Docker 引擎,因此我们将检查 Docker 版本并运行一个简单的“hello-world”容器,以确保一切按预期运行。

首先,让我们检查 Docker 版本。在 LabEx 虚拟机中打开一个终端。你可以在桌面或应用程序菜单中找到终端图标。

在终端中执行以下命令:

docker --version

此命令将显示系统上安装的 Docker 版本。你应该会看到类似于以下的输出:

Docker version 20.10.21, build xxxxxxx

如果你看到了 Docker 版本,这意味着 Docker 已正确安装。如果你遇到错误,请联系技术支持。

接下来,让我们运行“hello-world”容器。这是一个简单的容器,它会在控制台打印一条消息,然后退出。

在终端中执行以下命令:

docker run hello-world

在运行此命令之前,你需要从 Docker Hub 拉取 hello-world 镜像。Docker Hub 是一个用于 Docker 镜像的公共注册表。

执行以下命令来拉取镜像:

docker pull hello-world

此命令会将 hello-world 镜像从 Docker Hub 下载到你的本地机器。你应该会看到类似于以下的输出:

Using default tag: latest
latest: Pulling from library/hello-world
...
Digest: sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Status: Downloaded newer image for hello-world:latest
docker.io/library/hello-world:latest

现在,再次执行 docker run hello-world 命令:

docker run hello-world

此命令将运行 hello-world 容器。你应该会看到类似于以下的输出:

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

此消息表明 Docker 运行正常,并且你已成功运行了第一个容器!

使用 Docker Init 初始化一个 Go 项目

在这一步中,我们将初始化一个新的 Go 项目,并使用 docker init 生成必要的 Dockerfile 和 docker-compose.yml 文件。这将为我们将 Go 应用程序容器化提供一个起点。

首先,让我们为我们的 Go 项目创建一个新目录。在 LabEx 虚拟机中打开一个终端,并执行以下命令:

mkdir my-go-app
cd my-go-app

这些命令会在 ~/project 目录下创建一个名为 my-go-app 的新目录,然后将当前目录更改为 my-go-app

接下来,我们需要初始化一个 Go 模块。这将创建一个 go.mod 文件,用于跟踪我们项目的依赖项。

在终端中执行以下命令:

go mod init my-go-app

此命令将初始化一个名为 my-go-app 的新 Go 模块。你应该会看到类似于以下的输出:

go: creating new go.mod: module my-go-app
go: to add module requirements and sums:
        go mod tidy

现在,让我们创建一个简单的 Go 应用程序。使用 nano 编辑器在 my-go-app 目录下创建一个名为 main.go 的新文件:

nano main.go

将以下代码添加到 main.go 文件中:

package main

import "fmt"

func main() {
	fmt.Println("Hello, Docker!")
}

这是一个简单的 Go 程序,它会在控制台打印“Hello, Docker!”。

Ctrl+X,然后按 Y,再按 Enter 保存文件并退出 nano 编辑器。

现在,我们将使用 docker init 来生成 Dockerfile 和 docker-compose.yml 文件。不过,LabEx 虚拟机默认没有安装 Docker Compose。我们需要先安装它。

使用 curl 下载最新版本的 Docker Compose:

sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

使 Docker Compose 二进制文件可执行:

sudo chmod +x /usr/local/bin/docker-compose

通过检查 Docker Compose 版本来验证安装情况:

docker-compose --version

你应该会看到类似于以下的输出:

docker-compose version 1.29.2, build xxxxxxx

现在 Docker Compose 已安装,我们可以继续使用 docker init

在终端中执行以下命令:

docker init

docker init 会询问一系列问题,以配置 Dockerfile 和 docker-compose.yml 文件。以下是本实验的推荐答案:

  • 你想给这个应用程序取什么名字? my-go-app
  • 这个应用程序监听哪个端口? 3000(这是一个占位符,在这个简单的示例中我们实际上不会使用端口)
  • 要执行的主文件是什么? main.go
  • 你想包含 Docker Compose 配置吗? Yes
  • 请选择一个 Docker Compose 版本: 2.0

回答完这些问题后,docker init 会在 my-go-app 目录下生成一个 Dockerfile 和一个 docker-compose.yml 文件。

你可以使用 cat 命令查看生成文件的内容:

cat Dockerfile
cat docker-compose.yml

这些文件为在 Docker 容器中构建和运行我们的 Go 应用程序提供了基本配置。在下一步中,我们将定制这些文件以更好地满足我们的需求。

为 Go 项目定制生成的 Dockerfile 和 Compose 文件

在这一步中,我们将定制上一步生成的 Dockerfiledocker-compose.yml 文件。我们会优化 Dockerfile 以构建我们的 Go 应用程序,并配置 docker-compose.yml 文件来运行我们的应用程序。

首先,让我们查看生成的 Dockerfile。使用 nano 编辑器打开 my-go-app 目录下的 Dockerfile

nano Dockerfile

生成的 Dockerfile 可能如下所示:

## syntax=docker/dockerfile:1

FROM golang:latest AS builder

WORKDIR /app

COPY go.mod go.sum ./
RUN go mod download && go mod verify

COPY . .

RUN go build -o my-go-app

FROM alpine:latest

WORKDIR /app

COPY --from=builder /app/my-go-app .

EXPOSE 3000

CMD ["./my-go-app"]

这个 Dockerfile 使用了多阶段构建。第一阶段(builder)使用 golang:latest 镜像来构建 Go 应用程序。第二阶段使用 alpine:latest 镜像来运行应用程序。

让我们修改 Dockerfile,使用特定的 Go 版本并优化构建过程。将 Dockerfile 的内容替换为以下内容:

## syntax=docker/dockerfile:1

FROM golang:1.17 AS builder

WORKDIR /app

COPY go.mod go.sum ./
RUN go mod download && go mod verify

COPY . .

RUN go build -o my-go-app

FROM alpine:latest

WORKDIR /app

COPY --from=builder /app/my-go-app .

CMD ["./my-go-app"]

我们已将构建阶段的基础镜像更改为 golang:1.17。这确保了我们使用特定的 Go 版本来构建应用程序。

保存文件并退出 nano 编辑器。

现在,让我们查看生成的 docker-compose.yml 文件。使用 nano 编辑器打开 my-go-app 目录下的 docker-compose.yml 文件:

nano docker-compose.yml

生成的 docker-compose.yml 文件可能如下所示:

version: "3.9"
services:
  my-go-app:
    build: .
    ports:
      - "3000:3000"

这个 docker-compose.yml 文件定义了一个名为 my-go-app 的服务。它指定该服务应从当前目录(.)构建,并且应暴露端口 3000。

由于我们的应用程序实际上并不监听端口,我们可以移除 ports 部分。将 docker-compose.yml 文件修改为以下内容:

version: "3.9"
services:
  my-go-app:
    build: .

保存文件并退出 nano 编辑器。

在这一步中,我们定制了 Dockerfiledocker-compose.yml 文件以更好地满足我们的需求。在下一步中,我们将使用 Docker Compose 构建并运行我们的 Go 应用程序。

使用 Docker Compose 构建并运行 Go 应用程序

在这一步中,我们将使用 Docker Compose 来构建并运行我们的 Go 应用程序。Docker Compose 简化了构建和运行多容器应用程序的过程。在我们的例子中,虽然只有一个容器,但 Docker Compose 仍然为管理构建和运行过程提供了便捷的方式。

首先,在终端中导航到 my-go-app 目录:

cd ~/project/my-go-app

要为我们的应用程序构建 Docker 镜像,请执行以下命令:

docker-compose build

此命令将根据当前目录中的 Dockerfile 构建 Docker 镜像。你应该会看到类似于以下的输出:

Building my-go-app
Sending build context to Docker daemon  3.072kB
Step 1/6 : FROM golang:1.17 AS builder
 ---> xxxxxxxxxxxxxxxx
Step 2/6 : WORKDIR /app
 ---> Using cache
 ---> xxxxxxxxxxxxxxxx
Step 3/6 : COPY go.mod go.sum ./
 ---> Using cache
 ---> xxxxxxxxxxxxxxxx
Step 4/6 : RUN go mod download && go mod verify
 ---> Using cache
 ---> xxxxxxxxxxxxxxxx
Step 5/6 : COPY . .
 ---> xxxxxxxxxxxxxxxx
Step 6/6 : RUN go build -o my-go-app
 ---> Running in xxxxxxxxxx
Removing intermediate container xxxxxxxxxx
 ---> xxxxxxxxxxxxxxxx
Successfully built xxxxxxxxxxxxxxxx
Successfully tagged my-go-app_my-go-app:latest

此输出表明 Docker 镜像已成功构建。

现在,要运行应用程序,请执行以下命令:

docker-compose up

此命令将启动 docker-compose.yml 文件中定义的容器。你应该会看到类似于以下的输出:

Starting my-go-app_my-go-app_1 ... done
Attaching to my-go-app_my-go-app_1
my-go-app_1  | Hello, Docker!
my-go-app_my-go-app_1 exited with code 0

此输出显示我们的 Go 应用程序已执行,并在控制台打印了“Hello, Docker!”。然后容器以代码 0 退出,表明执行成功。

要停止容器,请在终端中按 Ctrl+C

你还可以通过在 docker-compose up 命令中添加 -d 标志以分离模式运行容器:

docker-compose up -d

这将在后台启动容器。要查看容器的日志,请执行以下命令:

docker logs my-go-app_my-go-app_1

要停止以分离模式运行的容器,请执行以下命令:

docker-compose down

此命令将停止并移除容器。

在这一步中,我们使用 Docker Compose 成功构建并运行了我们的 Go 应用程序。这展示了 Docker Compose 如何简化管理容器化应用程序的过程。

总结

在本次实验中,我们首先验证了 Docker Desktop 是否在 LabEx 虚拟机(VM)上成功安装。这包括使用 docker --version 命令检查 Docker 版本,并确认其已正确安装。接着,我们使用 docker pull hello-world 命令从 Docker Hub 拉取 hello-world 镜像,随后使用 docker run hello-world 命令运行该容器,以确保 Docker 按预期运行,并在控制台打印确认消息。

这第一步建立了一个可用的 Docker 环境,为后续使用 docker init 对 Go 应用程序进行容器化的步骤奠定了基础。