导出Binaries

你是否知道可以使用 Docker 将应用程序构建为独立的Binaries?有时候,你不想将应用程序打包并以 Docker 镜像的形式分发。使用 Docker 构建应用程序,并使用导出器将输出保存到磁盘。

docker build 的默认输出格式是容器镜像。该镜像会自动加载到您的本地镜像存储中,您可以从此镜像运行容器,或将其推送到注册表。在底层,这使用默认的导出器,称为 docker 导出器。

要将构建结果导出为文件,您可以使用--output标志, 或使用简短的-o--output标志允许您更改构建的输出格式。

从构建中导出Binaries

如果您为docker build --output标志指定文件路径,Docker会在构建结束时将构建容器的内容导出到主机文件系统上的指定位置。这使用了local 导出器

有趣的是,您可以使用 Docker 强大的隔离和构建功能来创建独立的Binaries。这 适用于 Go、Rust 以及可以编译为单个Binaries的其他语言。

以下示例创建了一个简单的 Rust 程序,打印“Hello, World!”,并将Binaries导出到主机文件系统。

  1. 为该示例创建一个新的目录,并导航到该目录:

    $ mkdir hello-world-bin
    $ cd hello-world-bin
    
  2. 创建一个包含以下内容的 Dockerfile:

    # syntax=docker/dockerfile:1
    FROM rust:alpine AS build
    WORKDIR /src
    COPY <<EOT hello.rs
    fn main() {
        println!("Hello World!");
    }
    EOT
    RUN rustc -o /bin/hello hello.rs
    
    FROM scratch
    COPY --from=build /bin/hello /
    ENTRYPOINT ["/hello"]

    提示

    COPY <<EOT 语法是一个 here-document。 它允许你在 Dockerfile 中编写多行字符串。在这里,它被用来在 Dockerfile 中内联创建一个简单的 Rust 程序。

    此 Dockerfile 使用多阶段构建,在第一阶段编译程序,然后在第二阶段将Binaries复制到 scratch 镜像中。最终镜像是一个仅包含Binaries的最小镜像。这种使用 scratch 镜像的方式常见于为不需要完整操作系统即可运行的程序创建最小构建工件。

  3. 构建 Dockerfile 并将Binaries导出到当前工作目录:

    $ docker build --output=. .
    

    此命令构建 Dockerfile,并将Binaries导出到当前工作目录。Binaries命名为 hello,并在当前工作目录中创建。

导出多平台构建

你使用 local 导出器配合 多平台构建 来导出Binaries。这使得你可以一次编译多个Binaries,可以在任何架构的任何机器上运行,前提是目标平台受你使用的编译器支持。

继续在 从构建中导出Binaries 部分中的示例 Dockerfile:

# syntax=docker/dockerfile:1
FROM rust:alpine AS build
WORKDIR /src
COPY <<EOT hello.rs
fn main() {
    println!("Hello World!");
}
EOT
RUN rustc -o /bin/hello hello.rs

FROM scratch
COPY --from=build /bin/hello /
ENTRYPOINT ["/hello"]

您可以使用 --platform 标志与 docker build 命令为多个平台构建此 Rust 程序。与 --output 标志结合使用时,构建会将每个目标的Binaries导出到指定目录。

例如,为linux/amd64linux/arm64构建程序:

$ docker build --platform=linux/amd64,linux/arm64 --output=out .
$ tree out/
out/
├── linux_amd64
│   └── hello
└── linux_arm64
    └── hello

3 directories, 2 files

附加信息

除了 local 导出器之外,还有其他可用的导出器。要了解有关可用导出器及其使用方法的更多信息,请参阅 导出器 文档。