Skip to content

Latest commit

 

History

History
123 lines (91 loc) · 5.52 KB

File metadata and controls

123 lines (91 loc) · 5.52 KB
title description icon
Shuttle Shared Databases
Learn about the Shuttle Shared Database resource.
database

This plugin manages databases on Shuttle and connects them to your app. A shared database is in the same cluster as other user's databases, but it is not accessible by other users.

If you want a high performing and isolated database, we also offer dedicated Shuttle AWS RDS.

You can connect to any type of remotely hosted database from your code, so do not let our current database offerings limit your creativity! Got other databases you want to see on Shuttle? Let us know!

The Shared Database is intended primarily for experimentation and development. Since it runs on AWS RDS instances shared with other Shuttle users, performance may be impacted during times of high demand from other databases. For business-critical workloads, we recommend using a dedicated [Shuttle AWS RDS database](./shuttle-aws-rds).

The Shuttle Shared Postgres cluster is RDS-based and uses Postgres version 16. Contact support if you want to enable common Postgres Extensions for your project.

Usage

Start by adding the shuttle-shared-db dependency. Each type of shareable database is behind its own feature flag and macro attribute path.

Engine Feature flag Attribute path
Postgres postgres shuttle_shared_db::Postgres

Output type

By default, you can get the connection string to the database and connect to it with your preferred library. You can also specify other return types to get rid of common boilerplate.

Depending on which type declaration is used as the output type in the macro, additional feature flags need to be activated:

Postgres output types:

Feature flag Type declaration Description
String The connection string including username and password (example)
sqlx (with rustls) or sqlx-native-tls sqlx::PgPool An sqlx connection pool (example)
diesel-async diesel_async::AsyncPgConnection An async diesel connection
diesel-async-bb8 diesel_bb8::Pool<diesel_async::AsyncPgConnection> A bb8 connection pool
diesel-async-deadpool diesel_deadpool::Pool<diesel_async::AsyncPgConnection> A deadpool connection pool
opendal-postgres opendal::Operator An OpenDAL Operator key-value storage interface
opendal-postgres shuttle_shared_db::SerdeJsonOperator A wrapper over Operator with interface for serde types (example)

Lastly, add a macro annotation to the Shuttle main function. Here are examples for Postgres:

// Use the connection string
#[shuttle_runtime::main]
async fn main(#[shuttle_shared_db::Postgres] conn_str: String) -> ... { ... }

// With sqlx feature flag, get a PgPool connected automatically
#[shuttle_runtime::main]
async fn main(#[shuttle_shared_db::Postgres] pool: sqlx::PgPool) -> ... { ... }

Parameters

Parameter Type Description
local_uri &str If specified, on local runs, use this database instead of starting a Docker container for it

When passing in strings, you can also insert secrets from Secrets.toml using string interpolation. To insert the PASSWORD secret, pass it in like this:

#[shuttle_runtime::main]
async fn main(
    #[shuttle_shared_db::Postgres(
        local_uri = "postgres://postgres:{secrets.PASSWORD}@localhost:16695/postgres"
    )] conn_str: String,
) -> ... { ... }

Caveat: If you are interpolating a secret from Secrets.dev.toml, you need to set the same secret in Secrets.toml to a empty string so that this step does not crash in deployment.

The URI should be formatted according to the Postgres documentation.

If you do not specify a local_uri, then cargo-shuttle will attempt to spin up a Docker container and launch the database inside of it. For this to succeed, you must have Docker installed and you must also have started the Docker engine. If you have not used Docker before, the easiest way is to install the desktop app and then launch it in order to start the Docker engine.

Example

The Shuttle main function below uses the #[shuttle_shared_db::Postgres] attribute macro to provision a shared Postgres database, which can be accessed with an sqlx Pool.

#[shuttle_runtime::main]
async fn main(
    #[shuttle_shared_db::Postgres] pool: PgPool,
) -> shuttle_axum::ShuttleAxum {
    sqlx::migrate!()
        .run(&pool)
        .await
        .expect("Failed to run migrations");

    let state = MyState { pool };
    let router = Router::new()
        .route("/todos", post(add))
        .route("/todos/:id", get(retrieve))
        .with_state(state);

    Ok(router.into())
}

The full example can be found on GitHub.

{/* TODO limitations, limits? */}