Quickstart: run an app with StageX¶
Build and run a tiny Rust program with the StageX Rust pallet and Docker.
How it works¶
StageX is designed as a drop-in replacement for distribution images such as Alpine or Debian, so this workflow should feel familiar if you already build container images.
StageX supports common application languages and toolchain ecosystems, including C/C++, Cython, Go, Lua, Node.js, PHP, Python, Ruby, Rust, and Solidity. This guide uses the StageX Rust pallet to build a tiny Rust program as a static binary, then copies it into a minimal scratch image.
What you need¶
Before you begin, install Docker to build and run the application image.
Create the app¶
Create a small Rust project that Cargo can build inside the StageX Rust environment.
Start by creating a new Rust project directory:
Add Cargo.toml with the package metadata:
Next, add src/main.rs with a small program:
With the application files in place, the next step is to define the container build.
Add a Containerfile¶
Create Containerfile to build the Rust binary with StageX and package it in a minimal runtime image:
FROM docker.io/stagex/pallet-rust@sha256:2fbe7b164dd92edb9c1096152f6d27592d8a69b1b8eb2fc907b5fadea7d11668 AS build
WORKDIR /app
COPY Cargo.toml ./
COPY src/ ./src/
RUN --network=none <<EOF
ARCH="$(uname -m)"
RUSTFLAGS="-C target-feature=+crt-static" \
cargo build \
--release \
--target "${ARCH}-unknown-linux-musl" \
--bin hello-stagex
cp "target/${ARCH}-unknown-linux-musl/release/hello-stagex" /hello-stagex
EOF
FROM scratch AS runtime
COPY --from=build /hello-stagex /hello-stagex
ENTRYPOINT ["/hello-stagex"]
The important choices are:
- The build stage uses the StageX Rust pallet as the compiler environment.
- The binary is statically linked, to minimize required dependencies during runtime.
- The final image used as a runtime is made from
scratch, so it contains only the app binary. Alternatively the binary can be exported from the image to be used elsewhere.
This example pulls the pallet from Docker Hub. StageX images are also available from Quay; keep the image pinned by digest if you use a different registry.
Build and run¶
Build the runtime image from Containerfile, load it into Docker, and run it locally:
docker buildx build -f Containerfile --target runtime --load -t hello-stagex:latest .
docker run --rm hello-stagex:latest
The container should print:
Add dependencies later¶
For projects with external crates, keep Cargo.lock committed and split dependency download from compilation:
The fetch step may use the network. The compile step should not.
Make your application image reproducible¶
StageX pallets are reproducible and full-source bootstrapped. That gives your application a verifiable toolchain and base image, but it does not automatically make your application image reproducible.
Follow this section if you want to check byte-for-byte reproducibility for the application image. To get matching rebuilds, your application build also needs stable inputs and stable image output.
Before running the reproducibility commands, check your build environment:
- Build on an x86_64 system for this workflow.
- Enable Docker's containerd image store.
- Use a Buildx builder with OCI exporter support; for Docker, use the
docker-containerdriver.
Then keep the application build deterministic:
- Pin the StageX pallet by digest.
- Lock application dependencies, such as
Cargo.lock. - Keep compilation hermetic with
RUN --network=none. - Disable Buildx provenance attestations for byte-for-byte archive comparison.
- Export an OCI archive with fixed timestamps and forced compression.
Then run these commands in order:
-
Build a reproducible Open Container Initiative (OCI) archive.
-
Load and run the archive.
-
Rebuild without cache and compare.
SOURCE_DATE_EPOCH=1 docker buildx build -f Containerfile . \ --no-cache \ --platform linux/amd64 \ --build-arg BUILDKIT_MULTI_PLATFORM=1 \ --target runtime \ --provenance=false \ --output type=oci,rewrite-timestamp=true,force-compression=true,dest=out/hello-stagex-rebuild.tar,name=hello-stagex:latest sha256sum out/hello-stagex.tar out/hello-stagex-rebuild.tar
The two archive hashes should match. If they do not, check for unlocked dependencies, generated files, timestamps, host-specific paths, or build steps that still use the network.
Next steps¶
You have built and run an application with StageX. Here's what to explore next:
-
Verify images and signatures
Configure lookaside signature verification for StageX images.
-
Reproduce StageX
Rebuild StageX and compare the resulting artifacts.