logo
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.

Usage

Depend on shuttle-service in Cargo.toml:

shuttle-service = "0.2"

and make sure your crate has a cdylib output target:

[lib]
crate-type = ["cdylib"]

See the declare_service! macro for more information on how to implement a service. Here’s a simple example using rocket to get you started:

#[macro_use]
extern crate shuttle_service;

#[macro_use]
extern crate rocket;

use rocket::{Build, Rocket};

#[get("/hello")]
fn hello() -> &'static str {
    "Hello, world!"
}

fn init() -> Rocket<Build> {
    rocket::build().mount("/", routes![hello])
}

declare_service!(Rocket<Build>, init);

Complete examples can be found in the repository.

Deploying

You can deploy your service with the cargo shuttle subcommand. To install run:

$ cargo install cargo-shuttle

in a terminal. Once installed, run:

$ cargo shuttle auth {my_name}

which will create and configure an API key. Then deploy the service with:

$ cargo shuttle deploy

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

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

Using sqlx

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

#[macro_use]
extern crate shuttle_service;
use shuttle_service::{Factory, Error};

#[macro_use]
extern crate rocket;
use rocket::{Rocket, Build, State};

use sqlx::PgPool;

struct MyState(PgPool);

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

async fn state(factory: &mut dyn Factory) -> Result<MyState, shuttle_service::Error> {
   let pool = sqlx::postgres::PgPoolOptions::new()
       .connect(&factory.get_sql_connection_string().await?)
       .await?;
   Ok(MyState(pool))
}

fn rocket() -> Rocket<Build> {
    rocket::build().mount("/", routes![hello])
}

declare_service!(Rocket<Build>, rocket, state);

To learn more about how to build services with states, and services that require additional resources, see Factory.

Configuration

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

Getting API keys

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

$ cargo shuttle auth {my_name}

replacing {my_name} by your desired account name.

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.

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.

Re-exports

pub use rocket;
pub use error::Error;

Modules

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

Macros

Helper macro that generates the entrypoint required of any service. Likely the only macro you need in this crate.

Structs

A convenience struct for building a Service from a Rocket instance.

Traits

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

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.