Rust on Miren
Miren auto-detects Rust apps from Cargo.toml, builds them with Cargo, and ships a
single release binary at /bin/app on a minimal runtime image — no Dockerfile required.
Ask your AI coding agent to "set up this Rust app on Miren" after installing the
Miren agent skills. It confirms your binary, checks the server binds
0.0.0.0:$PORT, wires up environment variables, and deploys — using this page as its
reference.
Do you need a Dockerfile?
No. Miren detects Rust from Cargo.toml and runs cargo build --release for you. The
default Rust version is 1.83. Provide a Dockerfile.miren only for custom build
steps — see Using Dockerfile.miren.
Set up the app
From your project root:
miren init
miren deploy
Preview what Miren detects — binary name, version, entrypoint — without building:
miren deploy --analyze
Binary name
Miren reads Cargo.toml to find the binary, then copies it to /bin/app:
- Uses the
[[bin]]name if specified. - Otherwise uses the package name from
[package].
Start command
Your server must bind to 0.0.0.0 on $PORT — Miren injects PORT and routes traffic
to it. Read it with std::env::var("PORT"). Here's a minimal axum
server:
use axum::{routing::get, Router};
use std::env;
use tokio::net::TcpListener;
#[tokio::main]
async fn main() {
let app = Router::new().route("/", get(|| async { "Hello from Rust on Miren!\n" }));
let port = env::var("PORT").unwrap_or_else(|_| "8080".to_string());
let listener = TcpListener::bind(format!("0.0.0.0:{port}")).await.unwrap();
axum::serve(listener, app).await.unwrap();
}
The compiled binary lands at /bin/app, which is the default start command. Use a
Procfile only to pass flags or define extra processes:
# Default — run the compiled binary
web: /bin/app
# Background worker
worker: /bin/app --mode worker
Example Cargo.toml
[package]
name = "myapp"
version = "0.1.0"
edition = "2021"
[dependencies]
axum = "0.7"
tokio = { version = "1", features = ["full"] }
Environment variables
Set variables with miren env set — -e for plain values, -s for secrets (masked
in output and logs):
miren env set -e RUST_LOG=info
miren env set -s DATABASE_URL
miren env set -s API_TOKEN
miren env set -s API_TOKEN (no value) prompts with masked input. You can also declare
variables in .miren/app.toml:
[[env]]
key = "DATABASE_URL"
value = ""
required = true
sensitive = true
description = "Postgres connection string"
See App Configuration — Environment Variables.
Agent quick reference
- Detection:
Cargo.tomlin the project - Default version: Rust 1.83 (override via
[build] versionin.miren/app.toml) - Build:
cargo build --release; binary copied to/bin/app - Binary name:
[[bin]]name if set, else the[package]name - Start command:
web: /bin/app(default); bind0.0.0.0:$PORTviastd::env::var("PORT") - Env vars:
miren env set -e KEY=VALUE,-sfor secrets, or[[env]]inapp.toml - Dockerfile: not needed; add
Dockerfile.mirenonly for custom builds
Next steps
- Supported Languages — Rust — full build detail
- App Configuration — customize
.miren/app.toml - Services — web + workers
- Deployment — how deploys build and activate