PreviewDrop for Rust

Deploy previews for Rust apps

Push a branch, get a live preview URL. PreviewDrop compiles your Rust server in a multi-stage build, runs the binary as a long-lived process, and posts the link to the pull request in under 60 seconds.

TL;DR
Add a multi-stage Dockerfile, connect your repo, push. PreviewDrop builds your release binary and runs it behind a TLS-terminated subdomain. Your Axum / Actix / Rocket server keeps its shared application state, Tokio background tasks and database connection pool — it’s a real process, not a WASM edge function with tight limits.

Dockerfile

Drop this at the root of your repo. PreviewDrop picks it up on the next push and builds it into a container behind a TLS-terminated subdomain.

Dockerfile
FROM rust:1.82 AS build WORKDIR /app COPY Cargo.toml Cargo.lock ./ # Pre-build dependencies in their own layer for fast rebuilds RUN mkdir src && echo "fn main() {}" > src/main.rs && cargo build --release && rm -rf src COPY . . RUN cargo build --release FROM debian:bookworm-slim RUN apt-get update && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/* # Replace "yourapp" with your crate's binary name COPY --from=build /app/target/release/yourapp /usr/local/bin/app EXPOSE 8080 ENV PORT=8080 CMD ["app"]

Environment variables

Set these in the Variables tab of your PreviewDrop project. They're encrypted at rest and injected into every preview container at start.

VariableExample valueNote
PORT8080PreviewDrop injects this. Read it in main() and bind your listener to it.
DATABASE_URLpostgres://user:pass@host:5432/dbFor sqlx / SeaORM / Diesel. Omit for stateless previews.
RUST_LOGinfoControls tracing / env_logger verbosity inside the preview container.

Common gotchas

Bind to 0.0.0.0 and read PORT

In Axum: TcpListener::bind(("0.0.0.0", port)).await where port comes from std::env::var("PORT"). Binding to 127.0.0.1 makes the container unreachable and the preview will 502.

Replace "yourapp" with your binary name

The COPY pulls target/release/yourapp. That name is your crate’s [[bin]] name (or the package.name in Cargo.toml) — match it exactly or the COPY fails.

Install ca-certificates in the runtime image

A slim Debian runtime ships no root certificates, so any outbound HTTPS — reqwest calls, sqlx TLS to a managed Postgres — fails with a certificate error. The Dockerfile installs ca-certificates to fix it.

Cache dependencies so rebuilds stay fast

Rust release builds are slow. The dummy-main.rs trick compiles your dependency tree in its own layer, so a change to application code doesn’t recompile every crate — which keeps the build inside the ~60-second window. For larger projects, cargo-chef does this more robustly.

Why not Vercel or Netlify?

Vercel and Netlify run Rust only as WASM/edge functions — no persistent process, tight CPU and memory limits, and no shared state between requests. A real Axum, Actix or Rocket server with a connection pool, Tokio background tasks and in-memory caches needs a long-lived process. PreviewDrop runs your compiled binary directly — the same way it runs in production.

Preview your Rust app in 5 minutes

Connect a repo, push a branch, get a URL. No credit card, no trial clock.

Start free