How to Deploy Rust to Docker Without Writing a Dockerfile
You can containerize any Rust application without writing a Dockerfile using migetpacks. It reads your Rust version from rust-toolchain.toml, uses a smart dependency caching strategy, builds optimized release binaries, and outputs a minimal production image. One command, zero configuration.
Why Is Writing a Dockerfile for Rust So Complicated?
A production-ready Rust Dockerfile requires:
- Multi-stage builds to separate compilation from runtime
- The "dummy crate" trick for dependency caching
- Proper handling of
Cargo.lockfor reproducible builds - Release builds with
--releaseflag - CA certificates in the runtime image
- Choosing between debian, alpine, or distroless base images
- Copying static assets alongside the binary
Rust's compile times make proper caching critical. Get it wrong and every code change triggers a full dependency rebuild.
How Do I Containerize a Rust App Without a Dockerfile?
Open your terminal, navigate to your Rust project, and run:
cd ~/projects/my-rust-api
docker run --rm \
-v "$PWD":/workspace/source \
-v /var/run/docker.sock:/var/run/docker.sock \
-e OUTPUT_IMAGE=my-rust-api:latest \
miget/migetpacks:latest
That's it. migetpacks will:
- Detect Rust from your
Cargo.toml - Read version from
rust-toolchain.tomlorrust-toolchain - Use the dummy crate technique for dependency caching
- Build with
cargo build --release - Copy CA certificates and static assets
- Output a minimal production image
How Does migetpacks Detect My Rust Version?
Version is resolved in this order:
| Priority | Source | Example |
|---|---|---|
| 1 | RUSTUP_TOOLCHAIN env var | RUSTUP_TOOLCHAIN=1.80.0 |
| 2 | rust-toolchain file | 1.92.0 |
| 3 | channel in rust-toolchain.toml | channel = "1.92.0" |
| 4 | Default | Latest stable |
What Is the Dummy Crate Caching Technique?
Rust dependency caching is tricky because cargo build compiles everything together. migetpacks uses a smart technique:
# Copy dependency manifests
COPY Cargo.toml Cargo.lock* ./
# Create dummy source and build deps (CACHED)
RUN mkdir -p src && echo 'fn main() {}' > src/main.rs
RUN cargo build --release && rm -rf src
# Copy real source code
COPY . .
# Touch main.rs and rebuild (only app code recompiles)
RUN touch src/main.rs
RUN cargo build --release
This ensures dependency compilation is cached across builds when only source code changes.
What Does the Full Generated Dockerfile Look Like?
# Builder stage
FROM rust:1.92 AS builder
WORKDIR /build
COPY Cargo.toml Cargo.lock* ./
RUN mkdir -p src && echo 'fn main() {}' > src/main.rs
RUN cargo build --release && rm -rf src
COPY . .
RUN touch src/main.rs
RUN cargo build --release \
&& cp target/release/myapp /build/app \
&& rm -rf src target Cargo.toml Cargo.lock .git
# Runtime stage
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y ca-certificates
WORKDIR /app
COPY --from=builder /build /app
ENV RUST_BACKTRACE=1
ENV RUST_LOG=info
You never write or maintain this file - migetpacks handles it automatically.
How Does migetpacks Detect the Binary Name?
The binary name is automatically detected from Cargo.toml:
[[bin]]sectionnamefield[package]sectionnamefield- Falls back to
app
Does migetpacks Support Cargo Workspaces?
Yes. For workspace projects (when [workspace] is present in Cargo.toml), all workspace member Cargo.toml files are copied for proper dependency resolution.
cd ~/projects/my-rust-workspace
docker run --rm \
-v "$PWD":/workspace/source \
-v /var/run/docker.sock:/var/run/docker.sock \
-e OUTPUT_IMAGE=my-api:latest \
-e RUN_COMMAND="./app" \
miget/migetpacks:latest
What About Static Assets?
If your project contains static/, public/, assets/, templates/, dist/, or build/ directories, they are automatically copied alongside the binary to the runtime image.
How Do I Build Secure Distroless Images?
Enable Docker Hardened Images for minimal containers:
docker run --rm \
-v "$PWD":/workspace/source \
-v /var/run/docker.sock:/var/run/docker.sock \
-e OUTPUT_IMAGE=my-app:latest \
-e USE_DHI=true \
miget/migetpacks:latest
Since Rust produces static binaries, the distroless runtime works perfectly - no shell, no package manager, minimal attack surface.
How Do I Use Custom Cargo Features?
Override the build command to include features:
docker run --rm \
-v "$PWD":/workspace/source \
-v /var/run/docker.sock:/var/run/docker.sock \
-e OUTPUT_IMAGE=my-app:latest \
-e BUILD_COMMAND="cargo build --release --features production" \
miget/migetpacks:latest
Next Steps
- Full Rust documentation - version detection, caching, workspaces
- Deploy on Miget - unlimited apps, one price
- Star on GitHub - migetpacks is open source
- Related guides: Go, Python