Expand description

Shuttle - Deploy Rust apps with a single Cargo subcommand

Hello, and welcome to the shuttle API documentation!

Shuttle is an open-source app platform that uses traits and annotations to configure your backend deployments.


Start by installing the cargo shuttle subcommand by runnning the following in a terminal:

$ cargo install cargo-shuttle

Now that shuttle is installed, you can create your first project using:

cargo shuttle init my-rocket-app

By looking at the Cargo.toml file of the created project you will see the crate has a cdylib type. This is because all shuttle projects are loaded by shuttle during runtime as dynamic libraries. Thus, you can convert any library crate to a shuttle project by adding these lines to Cargo.toml.

crate-type = ["cdylib"]

Another piece needed for a shuttle project is the shuttle-service dependency. Go ahead and update the shuttle-service dependency inside Cargo.toml to prepare this crate as a rocket project by adding the web-rocket feature on the shuttle-service dependency.

shuttle-service = { version = "0.3.2", features = ["web-rocket"] }

Now replace src/lib.rs with the following content.

extern crate rocket;

use shuttle_service::ShuttleRocket;

fn hello() -> &'static str {
    "Hello, world!"

async fn init() -> ShuttleRocket {
    let rocket = rocket::build().mount("/", routes![hello]);


See the shuttle_service::main macro for more information on supported services - like Axum. Or look at more complete examples in the repository, but take note that the examples may update before official releases.

Running locally

To test your app locally before deploying, use:

$ cargo shuttle run

You should see your app build and start on the default port 8000. You can test this using;

$ curl http://localhost:8000/hello
Hello, world!


You can deploy your service with the cargo shuttle subcommand too. But, you will need to authenticate with the shuttle service first using:

$ cargo shuttle login

this will open a browser window and prompt you to connect using your GitHub account.

Then, deploy the service with:

$ cargo shuttle deploy

Your service will immediately be available at {crate_name}.shuttleapp.rs. For example:

$ curl https://my-rocket-app.shuttleapp.rs/hello
Hello, world!

Using sqlx

Here is a quick example to deploy a service which uses a postgres database and sqlx:

Add the sqlx-postgres feature to the shuttle-service dependency inside Cargo.toml:

shuttle-service = { version = "0.3.2", features = ["web-rocket", "sqlx-postgres"] }

Now update the #[shuttle_service::main] function to take in a PgPool:

extern crate rocket;

use rocket::State;
use sqlx::PgPool;
use shuttle_service::ShuttleRocket;

struct MyState(PgPool);

fn hello(state: &State<MyState>) -> &'static str {
    // Do things with `state.0`...
    "Hello, Postgres!"

async fn rocket(pool: PgPool) -> ShuttleRocket {
    let state = MyState(pool);
    let rocket = rocket::build().manage(state).mount("/", routes![hello]);


For a local run, shuttle will automatically provision a Postgres instance inside a Docker container on your machine and connect it to the PgPool.

For deploys, shuttle will provision a database for your application and connect it to the PgPool on your behalf.

To learn more about shuttle managed services, see shuttle_service::main.


The cargo shuttle command can be customised by creating a Shuttle.toml in the same location as your Cargo.toml.

Change the name of your service

To have your service deployed with a different name, add a name entry in the Shuttle.toml:

name = "hello-world"

If the name key is not specified, the service’s name will be the same as the crate’s name.

Alternatively, you can override the project name on the command-line, by passing the –name argument:

cargo shuttle deploy --name=$PROJECT_NAME
Using Podman instead of Docker

If you are using Podman instead of Docker, then cargo shuttle run will give got unexpected error while inspecting docker container: error trying to connect: No such file or directory error.

To fix this error you will need to expose a rootless socket for Podman first. This can be done using:

podman system service --time=0 unix:///tmp/podman.sock

Now set the DOCKER_HOST environment variable to point to this socket using:

export DOCKER_HOST=unix:///tmp/podman.sock

Now all cargo shuttle run commands will work against Podman.

Getting API keys

After you’ve installed the cargo-shuttle command, run:

$ cargo shuttle login

this will open a browser window and prompt you to connect using your GitHub account.

We’re in alpha 🤗

Thanks for using shuttle! We’re very happy to have you with us!

During our alpha period, API keys are completely free and you can deploy as many services as you want.

Just keep in mind that there may be some kinks that require us to take all deployments down once in a while. In certain circumstances we may also have to delete all the data associated with those deployments.

To stay updated with the release status of shuttle, join our Discord!

Join Discord

If you have any questions, join our Discord server. There’s always someone on there that can help!

You can also open an issue or a discussion on GitHub.


pub use log;
pub use error::Error;


Types representing various errors that can occur in the process of building and deploying a service.


Helper macro that generates the entrypoint required of any service.


The Tokio runtime.

A wrapper that takes a user’s future, gives the future a factory, and takes the returned service from the future The returned service will be deployed by shuttle



Factories can be used to request the provisioning of additional resources (like databases).

Used to get resources of type T from factories.

A convenience trait for handling out of the box conversions into Service instances.

The core trait of the shuttle platform. Every crate deployed to shuttle needs to implement this trait.

Type Definitions

A tokio handle the service was started on

Attribute Macros

Helper macro that generates the entrypoint required by any service - likely the only macro you need in this crate.