Home Explore Blog CI



docker

2nd chunk of `content/manuals/build/building/export.md`
3f5ccae345dabb75c11dacfdd937bc1a7511079871851bc80000000100000ca8
The neat thing about this is that you can use Docker's powerful isolation and
build features to create standalone binaries. This
works well for Go, Rust, and other languages that can compile to a single
binary.

The following example creates a simple Rust program that prints "Hello,
World!", and exports the binary to the host filesystem.

1. Create a new directory for this example, and navigate to it:

   ```console
   $ mkdir hello-world-bin
   $ cd hello-world-bin
   ```

2. Create a Dockerfile with the following contents:

   ```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"]
   ```

   > [!TIP]
   > The `COPY <<EOT` syntax is a [here-document](/reference/dockerfile.md#here-documents).
   > It lets you write multi-line strings in a Dockerfile. Here it's used to
   > create a simple Rust program inline in the Dockerfile.

   This Dockerfile uses a multi-stage build to compile the program in the first
   stage, and then copies the binary to a scratch image in the second. The
   final image is a minimal image that only contains the binary. This use case
   for the `scratch` image is common for creating minimal build artifacts for
   programs that don't require a full operating system to run.

3. Build the Dockerfile and export the binary to the current working directory:

   ```console
   $ docker build --output=. .
   ```

   This command builds the Dockerfile and exports the binary to the current
   working directory. The binary is named `hello`, and it's created in the
   current working directory.

## Exporting multi-platform builds

You use the `local` exporter to export binaries in combination with
[multi-platform builds](/manuals/build/building/multi-platform.md). This lets you
compile multiple binaries at once, that can be run on any machine of any
architecture, provided that the target platform is supported by the compiler
you use.

Continuing on the example Dockerfile in the
[Export binaries from a build](#export-binaries-from-a-build) section:

```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"]
```

You can build this Rust program for multiple platforms using the `--platform`
flag with the `docker build` command. In combination with the `--output` flag,
the build exports the binaries for each target to the specified directory.

For example, to build the program for both `linux/amd64` and `linux/arm64`:

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

3 directories, 2 files
```

## Additional information

In addition to the `local` exporter, there are other exporters available. To
learn more about the available exporters and how to use them, see the
[exporters](/manuals/build/exporters/_index.md) documentation.

Title: Building and Exporting Multi-Platform Binaries with Docker
Summary
This section details how to build a simple Rust "Hello, World!" program, package it in a Dockerfile using multi-stage builds and a scratch image, and then export the resulting binary to the host filesystem. It also demonstrates how to build the same program for multiple platforms (e.g., linux/amd64, linux/arm64) using the `--platform` flag and the `--output` flag, resulting in separate binaries for each target architecture in a specified output directory. It concludes by pointing to the documentation for other available exporters.