> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sevalla.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> These are the docs for Sevalla, a platform for deploying applications, databases, static sites, object storage and load balancers. The dashboard is at https://app.sevalla.com.
> Bold text in steps is an exact dashboard label.
> To act on a Sevalla account, prefer the Sevalla MCP server (https://mcp.sevalla.com/mcp, see https://docs.sevalla.com/ai-agents/overview.md), then the Sevalla CLI (https://docs.sevalla.com/developer-tools/cli.md), then the REST API (https://api-docs.sevalla.com, OpenAPI spec at https://api.sevalla.com/v3/openapi.json).
> Every page index is at https://docs.sevalla.com/llms.txt.

# Deploy Rust applications

> How Rust applications build and run on Sevalla with Ingot: Cargo builds, rust-toolchain.toml and rust-version, native libraries, the PORT variable, processes and Dockerfiles.

A Rust web server runs on Sevalla as an [application](https://docs.sevalla.com/applications/overview.md): Sevalla builds an image from your Git repository, compiles your crate with Cargo in release mode, and runs the binary as processes. The web process runs the binary that serves HTTP, background workers and cron jobs can run other binaries of the same crate or workspace, and jobs run migrations before each deployment.

## Framework guides

> **[Axum](https://docs.sevalla.com/guides/rust/axum.md)**
>
> Deploy an Axum JSON API on Tokio, with a graceful shutdown on SIGTERM.

> **[Actix Web](https://docs.sevalla.com/guides/rust/actix-web.md)**
>
> Deploy Actix Web 4, with its request logger and built-in graceful shutdown.

> **[Rocket](https://docs.sevalla.com/guides/rust/rocket.md)**
>
> Deploy Rocket 0.5, with the address and `PORT` set from code.

## How Rust applications run on Sevalla

| Part | On Sevalla |
| - | - |
| Build | [Ingot](https://docs.sevalla.com/applications/builds/ingot.md), Sevalla's builder, by default. It recognizes a Rust project by `Cargo.toml`, builds every binary a plain `cargo build` would, with `cargo auditable build --release --locked`, and installs them in `/usr/local/bin`. `cargo-auditable` records the crates in each binary, so vulnerability scanners can list them. |
| Lock file | Commit `Cargo.lock`. Ingot builds with `--locked`, so the build uses its versions. Without it, the build log warns `There is no Cargo.lock, so dependency versions are chosen during the build`. |
| Rust version | Rust 1.99, Ingot's default line, unless the project sets another. Pin it in `rust-toolchain.toml`: see [Pin the Rust version](#pin-the-rust-version). |
| Native libraries | Ingot installs what common crates need to build and run, from the crates in `Cargo.lock`: OpenSSL for `openssl-sys`, `libpq` for `pq-sys`, the MySQL client library for `mysqlclient-sys`, SQLite for `libsqlite3-sys`, `protoc` for `prost-build`, and CMake, `libclang` or a C++ compiler for the crates that run them. The build plan lists each one. |
| Start command | The package's `default-run` binary, or its only binary, such as `/usr/local/bin/storefront`. With several binaries and no `default-run`, the build fails with `Found several binaries` until you set `default-run` in `Cargo.toml` or the start command. See [Set the start command](https://docs.sevalla.com/applications/builds/ingot.md#set-the-start-command). |
| Port | Sevalla sets the `PORT` environment variable to the web process's port, `8080` by default. The server must listen on it, on all network interfaces (`0.0.0.0`). Axum and Actix Web take the address from your code; [Rocket](https://docs.sevalla.com/guides/rust/rocket.md) needs both set in code, since it listens on `127.0.0.1:8000` by default. |
| Concurrency | Tokio, Actix Web and Rocket start one worker thread per CPU the instance can use: an Actix Web server on an **H1** instance starts 1 worker. To serve more traffic, choose a larger size or add instances. See [Scaling](https://docs.sevalla.com/applications/scaling.md). |
| Shutdown | Sevalla sends `SIGTERM` to stop an instance. Actix Web and Rocket handle it on their own; with Axum, pass a signal handler to `with_graceful_shutdown`, as in the [Axum guide](https://docs.sevalla.com/guides/rust/axum.md#shut-down-gracefully). Ingot's image runs the binary under `tini`, which passes the signal on. |
| Image | Ingot builds on `rust:1.99-slim-trixie` and runs the binary on `debian:trixie-slim`, which has the same GNU C library, with CA certificates and time zone data, as user `1000:1000`. |
| Runtime files | The binary runs from `/app`. Ingot copies the folders a Rust server usually reads at runtime, `assets`, `locales`, `migrations`, `public`, `static`, `templates` and `views`, and `config` when it holds no Rust code, into `/app`, so relative paths work. Files you include with `include_str!` or `include_bytes!` are part of the binary. |
| Migrations | A job with the start policy **Before deployment** that runs a migration binary of your crate. If it fails, the deployment fails and the previous version keeps running. With sqlx, Ingot sets `SQLX_OFFLINE=true` when the project has a `.sqlx` folder, so the query macros check against it instead of a database during the build. |
| Workers | A background worker that runs another binary, such as `/usr/local/bin/worker` built from `src/bin/worker.rs`. See [Run workers and jobs](https://docs.sevalla.com/applications/builds/ingot.md#run-workers-and-jobs). |
| Scheduled tasks | A cron job that runs a binary on a schedule. |
| Databases | PostgreSQL, MySQL, MariaDB, Redis or Valkey on Sevalla, reached over an [internal connection](https://docs.sevalla.com/databases/connect.md#connect-an-application) that adds the connection details as environment variables. |
| Files | The filesystem resets on every deployment. Keep uploads in [object storage](https://docs.sevalla.com/object-storage/overview.md), or attach a [disk](https://docs.sevalla.com/applications/disks.md). |
| Dockerfile | Switch the build strategy to [Dockerfile](https://docs.sevalla.com/applications/builds/dockerfile.md) on the application's **Settings** tab. See [Build with a Dockerfile](#build-with-a-dockerfile). |

Every process (web, worker, cron job and job) runs from the same image, each with its own start command. See [Processes](https://docs.sevalla.com/applications/processes.md) for every process type and its settings.

## Pin the Rust version

Ingot builds on Rust 1.99, its default line, unless the project sets a version. Pin the line you develop with in `rust-toolchain.toml`, which rustup also reads on your computer, so the build doesn't change when a new Ingot release moves its default line:

```toml rust-toolchain.toml theme={"theme":{"light":"github-dark-default","dark":"github-dark-default"}}
[toolchain]
channel = "1.99"
```

Ingot takes the version from the first of these that's set:

1. The `INGOT_RUST_VERSION` environment variable, marked **Available during buildtime**, such as `1.98`.
2. `versions.rust` in [ingot.json](https://docs.sevalla.com/applications/builds/ingot.md#configure-the-build).
3. The `channel` of `rust-toolchain`, or of `rust-toolchain.toml` when there's no `rust-toolchain` file.
4. The highest `rust-version` of the packages the build compiles, from `Cargo.toml`. It's a minimum: Ingot builds on its default line when that satisfies it.

How Ingot reads the channel:

* A line, such as `1.99`, builds on that line's newest release, and every new build picks up its patch releases.
* An exact release, such as `1.99.1`, stays on that release, and the build log warns `Rust is pinned to exactly 1.99.1, so its image won't receive security rebuilds; require 1.99.x to follow the line`.
* `stable` builds on Ingot's default line.
* `nightly` or `beta` fails the build with `rust-toolchain.toml asks for the "nightly" toolchain`: Ingot builds with stable releases only.

Ingot installs the `targets` and `components` the file lists, except the ones for development such as `clippy` and `rustfmt`, then leaves the file out of the build, so rustup doesn't download the toolchain it names. The build plan's **Rust** row shows the version and where it came from. See [Set the language version](https://docs.sevalla.com/applications/builds/ingot.md#set-the-language-version).

## Build with a Dockerfile

Ingot needs no Dockerfile, but you can write your own for full control of the image. A Dockerfile for Rust on Sevalla builds in a `rust` image of the line `rust-toolchain.toml` pins, compiles the dependencies from `Cargo.toml` and `Cargo.lock` in a layer of their own, so a code change doesn't compile them again, and builds with `--locked`. The binary links to the GNU C library, so the final stage runs on the Debian release it was built on, such as `debian:trixie-slim` for `rust:1.99-slim-trixie`, with CA certificates and a user other than root. A server that handles `SIGTERM` needs no init process; one that doesn't ignores it as process 1. Each guide has one: see [Deploy an Axum application](https://docs.sevalla.com/guides/rust/axum.md#deploy-with-a-dockerfile).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.