All docs

Rust

A Cargo.toml is enough. The two things to plan for are build time and which binary runs.

A Cargo.toml at the root is enough.

marina vessels create api --repo acme/api

Your crate is compiled and the resulting binary is what runs, named after the package. Nothing is interpreted at start, so the running app is small and boots fast; starter is usually plenty.

The port

Marina sets PORT and routes to it. Read it, and bind all interfaces:

let port: u16 = std::env::var("PORT")
    .ok()
    .and_then(|p| p.parse().ok())
    .unwrap_or(3000);
let listener = tokio::net::TcpListener::bind(("0.0.0.0", port)).await?;

0.0.0.0, not 127.0.0.1. The second one builds, starts, logs nothing unusual, and answers no requests.

The Rust version

From rust-toolchain.toml, then the rust-version field in Cargo.toml. Pin it if your code uses something recent; without one you get a version that will move under you.

[toolchain]
channel = "1.89"

Build time

A cold Rust build is minutes, not seconds, and it is the slowest first deploy of any stack here. Nothing is wrong; it is the compiler.

Two things make it bearable. Keep the dependency tree honest, because most of that time is dependencies rather than your code. And remember a failed or slow build never takes the running app down: the previous version serves throughout.

The thing that usually breaks

A workspace with more than one binary. The binary is chosen from the package, so a workspace that builds several gets one of them, and it may not be the server.

A Dockerfile at the root is used automatically and says exactly what to build:

FROM rust:1.89 AS build
WORKDIR /src
COPY . .
RUN cargo build --release --bin server

FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/*
COPY --from=build /src/target/release/server /server
CMD ["/server"]

PORT is still injected, and ca-certificates is there because a binary that makes outbound HTTPS calls fails without it in a slim image, which is a confusing way to lose an afternoon.