导出二进制文件

你知道吗,你可以使用Docker将你的应用程序构建为独立的二进制文件?有时候,你可能不想将你的应用程序打包并分发为Docker镜像。使用Docker来构建你的应用程序,并使用导出器将输出保存到磁盘。

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

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

从构建中导出二进制文件

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

这其中的巧妙之处在于,你可以利用Docker强大的隔离和构建功能来创建独立的二进制文件。这对于Go、Rust以及其他可以编译成单一二进制文件的语言来说非常有效。

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

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

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

  3. 构建Dockerfile并将二进制文件导出到当前工作目录:

    $ docker build --output=. .
    

    此命令构建Dockerfile并将二进制文件导出到当前工作目录。二进制文件名为hello,它是在当前工作目录中创建的。

导出多平台构建

您使用local导出器与多平台构建结合来导出二进制文件。这使您能够一次编译多个二进制文件,这些文件可以在任何架构的机器上运行,只要您使用的编译器支持目标平台。

继续在从构建中导出二进制文件部分的示例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"]

你可以使用docker build命令的--platform标志为多个平台构建这个Rust程序。结合--output标志,构建会将每个目标的二进制文件导出到指定的目录。

例如,要为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导出器外,还有其他可用的导出器。要了解更多关于可用导出器及其使用方法的信息,请参阅导出器文档。