How to Deploy Rust to Docker Without Writing a Dockerfile

M
Miget Team
Writer
January 18, 2026
5 min read

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.lock for reproducible builds
  • Release builds with --release flag
  • 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:

  1. Detect Rust from your Cargo.toml
  2. Read version from rust-toolchain.toml or rust-toolchain
  3. Use the dummy crate technique for dependency caching
  4. Build with cargo build --release
  5. Copy CA certificates and static assets
  6. Output a minimal production image

How Does migetpacks Detect My Rust Version?

Version is resolved in this order:

PrioritySourceExample
1RUSTUP_TOOLCHAIN env varRUSTUP_TOOLCHAIN=1.80.0
2rust-toolchain file1.92.0
3channel in rust-toolchain.tomlchannel = "1.92.0"
4DefaultLatest 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:

  1. [[bin]] section name field
  2. [package] section name field
  3. 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

Stay UpdatedWith Latest Posts

Subscribe to our newsletter and never miss a new blog post, update, or special offer from the Miget team.