Axum is a Rust web framework built on Tokio and Tower. Vercel provides a native Rust runtime in public beta, but a container is useful when you want to run an existing Axum HTTP server, control its Linux dependencies, or preserve an existing Docker build.
Cargo produces a native binary; a multi-stage build can compile the application once and omit the compiler and toolchain from the final image. Add a Dockerfile.vercel and set the service runtime to container. Vercel builds the image, stores it in the Vercel Container Registry, and serves it from a Function that autoscales with traffic and scales to zero when idle.
This guide deploys a minimal Axum API, binds it to Vercel's PORT, and explains how to use durable external storage instead of the container file system.
Copy link to headingPrerequisites
- A Vercel account
- Docker Desktop or a running Docker daemon
- Vercel CLI (
npm install -g vercel)
Copy link to headingHow it works
The project is one Axum application with the following parts:
src/main.rsdefines/and/health, binds to0.0.0.0on$PORT, and drains onSIGTERM.Cargo.tomldeclares Axum, Tokio, and Serde, andCargo.lockpins their resolved versions.Dockerfile.vercelcompiles a release binary in one stage and copies it into a minimal final stage.vercel.jsondeclares a container service and rewrites incoming requests to it.- On deployment, Vercel builds the image and runs it as a Vercel Function.
Copy link to headingSteps
Copy link to heading1. Initialize the project
Create the project and add the dependencies with the features this guide uses:
The resulting Cargo.toml should look like this. The release profile is optional, but keeps the shipped binary small:
Now, for the HTTP server, update the src/main.rs:
The server must bind to 0.0.0.0, not 127.0.0.1, and read PORT. The fallback to port 80 matches Vercel's default container port.
Copy link to heading2. Add Dockerfile.vercel
Create the Dockerfile.vercel file in the project root:
Compiling dependencies from the Cargo Chef recipe before copying the application code lets Docker reuse the dependency layer. The final stage contains the binary and the C libraries it links against, excludes Cargo and the compiler, and runs as the image's non-root user. The path in the COPY line must match the package name in Cargo.toml, and pinning an exact toolchain tag instead of latest-rust-1 makes builds reproducible.
Copy link to heading3. Add vercel.json
Create a vercel.json file to configure your project:
The service selects the container runtime and points to the Dockerfile. The catch-all rewrite sends every public path to the Axum service.
Copy link to heading4. Run locally
Run the project through Vercel's local container environment:
Use the URL printed by the CLI, usually http://localhost:3000:
Copy link to heading5. Deploy to Vercel
Authenticate and create a production deployment:
For Git-based deployments, push the directory to a repository, import it in Vercel, and keep both configuration files at the configured project root.
Copy link to headingExtend your application
You have deployed an Axum API as a native Rust binary. You can now add routes, middleware, authentication, and external data services.
Copy link to headingEnvironment variables
Add configuration in the project settings or with vercel env add NAME. Pull development values locally with vercel env pull. Read secrets at runtime with std::env rather than baking them in at compile time with env!, and do not commit them or include them in the image.
Copy link to headingDatabase and storage
The container runs on Vercel Functions, where the file system is not persistent. Here are some recommendations for persistent workloads:
| Use case | Recommended service |
|---|---|
| Files and uploads | Vercel Blob |
| Relational data | Marketplace Postgres integration |
| Sessions and caching | Marketplace Redis integration |
| Frequently read configuration | Vercel Global Config |
Keep database pools small, build them once during startup, and share them through Axum state so a warm instance can reuse connections.
Copy link to headingIterate with preview deployments
A connected Git repository receives a unique Preview Deployment for each branch push or pull request. Run vercel deploy without --prod to create the same disposable environment from the CLI.
Copy link to headingScale automatically with Fluid compute
Vercel Services use Fluid compute by default. Instances can process concurrent requests and scale to zero when idle. Active CPU billing stops while code waits on I/O and when no requests are running; memory and invocation charges still apply.
Copy link to headingTroubleshooting
Copy link to headingThe binary starts locally but requests return 502
Cause: The listener is bound to 127.0.0.1 or a hardcoded port instead of the container interface and the port Vercel routes to.
Fix: Bind to [0, 0, 0, 0] and parse PORT, with 80 as the fallback. EXPOSE does not configure routing.
Copy link to headingThe final image reports a missing loader or library
Cause: The binary was linked against libraries that the runtime image does not provide, which commonly happens when build and runtime stages mix Alpine and Debian.
Fix: Keep the build and runtime images in the same family, or build a static MUSL binary and pair it with a matching static image. Run the exact final image locally before deploying.
Copy link to headingBuilds remain slow after small source changes
Cause: Copying the whole source tree before compiling dependencies invalidates the Cargo layer cache on every edit.
Fix: Keep the Cargo Chef planner and cargo chef cook stages ahead of the source build, and commit Cargo.lock so dependency resolution is reproducible.
Copy link to headingSpawned Tokio tasks stop before completion
Cause: Tasks detached with tokio::spawn assume the process outlives the response. Scale-in can send SIGTERM at any point after a request finishes.
Fix: Finish request work before responding, use Vercel Cron for schedules, and use Workflow for durable multi-step work. Keep request handlers idempotent.
Copy link to headingNext steps
- Learn how Vercel Services routes traffic between backends and frontends
- Learn how to run Docker on Vercel
- Review the vercel.json reference
- Read the container images documentation for execution limits
- Explore the Vercel Frameworks documentation