Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add environment page, update information #199

Merged
merged 3 commits into from
Oct 9, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions configuration/environment.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
---
title: "Deployment environment"
description: "Details about the environment your app runs in."
---

This page answers:

- What container is my app running in?
- What tools and programs are installed?
- How do I set environment variables?

## Deployer and Rust version

Deployments are currently built and run in our `shuttle-deployer` container, which is based on a Rust Bookworm docker image (Debian 12).

The current Rust version is `1.72.0`, toolchain `stable-x86_64-unknown-linux-gnu`.
It's not currently possible for you to change this, but being able to choose which toolchain your project will be compiled with is a planned feature.

The targets `wasm32-wasi` and `wasm32-unknown-unknown` are installed, which enables compiling `shuttle-next` apps and WASM frontends.

## External tools

Apart from what is already found in the Debian image [[1]](https://github.com/debuerreotype/docker-debian-artifacts/blob/bfa3d175e4153a23ffb4cf1b573d72408333b4e2/bookworm/rootfs.manifest) [[2]](https://github.com/docker-library/buildpack-deps/blob/fdfe65ea0743aa735b4a5f27cac8e281e43508f5/debian/bookworm/Dockerfile), these `apt` packages are also installed:

- `llvm-dev`
- `libclang-dev`
- `clang`
- `cmake`
- `lld`
- `mold`

Additionally, these tools are installed:

- `cargo-binstall` (latest)
- `trunk 0.17.2`
- `protoc 22.2`

*Installing more dependencies is not officially supported, but can be done with [a bit of tinkering](https://github.com/shuttle-hq/shuttle/issues/703#issuecomment-1515606621).*

## Environment variables

There are some environment variables set in the Shuttle container.
Check for `SHUTTLE=true` for custom behavior when running on Shuttle.

```bash
SHUTTLE=true
RUST_VERSION="1.72.0"
RUSTUP_TOOLCHAIN="1.72.0"
```

### Build environment

If you have build flags or env variables that need to be set during compilation, you can add them in `.cargo/config.toml` ([docs](https://doc.rust-lang.org/cargo/reference/config.html)) and include it in your deployment. Below are some examples.

```toml .cargo/config.toml
[build]
rustflags = ["--more", "cheese"]

[env]
MY_ENV_VAR = "Shuttle to the moon! 🚀🚀🚀"

[target.x86_64-unknown-linux-gnu]
linker = "clang"
rustflags = ["-C", "link-arg=-fuse-ld=/usr/bin/ld.lld"]
```

### Runtime environment

See [Shuttle Secrets](/resources/shuttle-secrets)

## Limitations

<Warning>
Most of the limits below are due to change as we roll out paid tiers. Read more about Pricing [here](https://www.shuttle.rs/pricing).
</Warning>

Currently we limit a project container's memory usage to 4 GB during high contention and 6 GB otherwise.

CPU usage per project is currently limited to 4 threads. However, because of how this limit is implemented through Docker, popular crates like `num_cpus` may think it has access to all of the host's threads.

In terms of database resources, the only restriction we have is that an RDS database has a max storage of `10GB`.
jonaro00 marked this conversation as resolved.
Show resolved Hide resolved

Other than that any reasonable usage is acceptable during our beta, but we will intervene when we detect applications that use excessively large amounts of storage (after attempting to contact the owner).
8 changes: 4 additions & 4 deletions configuration/project-name.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ They are listed below in the same order as `cargo-shuttle` will prioritize them.

## via the `--name` option

When running commands, the project name can always be overridden with the `--name` option:
When running commands, the project name can always be overridden with the `--name` option, regardless of which directory you are in.

```bash
# This will create a project called `my-project-name`.
# Create a project called `my-project-name`
cargo shuttle start --name my-project-name

# This will check the deployment list of `my-project-name` regardless of which directory you are in.
# Check the deployment list of `my-project-name`
cargo shuttle deployment list --name my-project-name
```

Expand All @@ -37,7 +37,7 @@ name = "my-project-name"

In the absence of either of the previous two options, the project will be named based on the content of the `name = ` field of the `[package]` section in the `Cargo.toml` configuration file.

A new Shuttle project can be named by passing in a project name with the `--name` option.
A new Shuttle project can be named by passing in a project name with the `--name` option, for example:

```bash
cargo shuttle init --template axum --name my-project-name some-directory
Expand Down
2 changes: 1 addition & 1 deletion configuration/shuttle-versions.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: "Shuttle versions"
description: "How Shuttle versions work"
description: "How Shuttle versioning works"
---

- When you start or restart a project, a Shuttle `deployer` Docker container is started with the [latest released](https://github.com/shuttle-hq/shuttle/releases) version of Shuttle.
Expand Down
9 changes: 9 additions & 0 deletions examples/examples.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
title: "Examples"
---

{/* TOOD: Add this page if it gets more content */}

This section of the docs has easy to follow guides for getting started with all supported frameworks.

For the full list of official examples, as well as even more templates made by the community, check out the [examples repo](https://github.com/shuttle-hq/shuttle-examples#readme).
20 changes: 12 additions & 8 deletions getting-started/idle-projects.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,8 @@
title: "Idle Projects"
---

Shuttle imposes no restrictions on how many projects a user can
create. While we are in beta this is a win-win, users creating many and
varied projects is great for testing both our code and how we handle
load. However, this leads to a sizable amount of idle projects. To
remedy this, we put these idle projects to sleep, by default after **30 minutes**
of very low activity.
To help handle the load of our users, and to help them save on compute costs (Pro tier),
we currently default to putting idle projects to sleep, by default after **30 minutes** of very low activity.

By activity we mean both:

Expand All @@ -16,7 +12,7 @@ increased when a project receives traffic (for example, traffic to an
API endpoint for an axum server, or calling the commands of a Discord bot).
An HTTP server (eg. axum or rocket), will need about 2 requests per minute over the idle-time period to be considered
active, a Discord bot will need about 6 calls per minute.
- User interaction, for example running `cargo shuttle status` or any other CLI commands except for `cargo shuttle project <cmd>` commands.
- User interaction, for example running `cargo shuttle status` or any other CLI commands that interact with the deployed service.

If the project is sleeping, traffic to the project or user
interaction will wake it, and this usually takes around one
Expand All @@ -31,7 +27,7 @@ interaction through the CLI will (but traffic will keep it from going to

Since we don't really want to restrict active users yet, this limit
can be freely modified. You can change it by passing in a flag when
creating a project:
creating or restarting a project:

```bash
cargo shuttle project start --idle-minutes 40
Expand All @@ -42,3 +38,11 @@ the idle timeout will be disabled and your project will never sleep.
This is especially useful for Discord bots, since they will not be
awoken by traffic (people using the bot commands in a Discord channel),
only by developer interaction through the Shuttle CLI.

### Checking the timeout

You can check the current idle timeout of a project with:

```bash
cargo shuttle project status
```
Binary file modified images/shuttle-macros.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 12 additions & 16 deletions introduction/how-shuttle-works.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ title: "How Shuttle works"
The simplest way to build and deploy a web app on Shuttle looks like this:

```rust
use axum::{routing::get, Router};

async fn hello_world() -> &'static str {
"Hello, world!"
}

#[shuttle_runtime::main]
async fn axum() -> shuttle_axum::ShuttleAxum {
async fn main() -> shuttle_axum::ShuttleAxum {
let router = Router::new().route("/", get(hello_world));

Ok(router.into())
Expand All @@ -20,17 +22,17 @@ async fn axum() -> shuttle_axum::ShuttleAxum {
This example spins up a server where the `/` endpoint returns `Hello, world!`.
But most importantly, the code you see in the snippet above, is all it takes for `cargo shuttle deploy` to deploy it.

This is possible due to the `#[shuttle_runtime::main]` procedural macro. The macro wraps your app with Shuttle's runtime. The Shuttle runtime receives commands from the deployers, such as `load`, `start`, and `stop`. The loading phase provisions resources for the app (see Provisioning Resources below).
This is possible due to the `#[shuttle_runtime::main]` procedural macro. The macro wraps your app with Shuttle's runtime. The Shuttle runtime receives commands from the deployers, such as `load`, `start`, and `stop`. The loading phase provisions resources for the app (see below).

### Provisioning Resources
## Provisioning Resources

![Shuttle macros](/images/shuttle-macros.png)

In the example above, the 3 annotations in the main function expand to code that makes the Shuttle runtime provision them on our end.

Here are the examples on how to use them, once you add the required annotations to your code:

**Secrets**
### Secrets

```rust
#[shuttle_runtime::main]
Expand All @@ -46,7 +48,7 @@ async fn axum(
}
```

**Postgres Database**
### Postgres Database

```rust
#[shuttle_runtime::main]
Expand All @@ -62,20 +64,14 @@ async fn axum(

For more info on resources, head on over to our [Resources](/resources/overview) section.

### Deploying your Project

When you run `cargo shuttle deploy`, your project code is archived and sent to our servers where it is compiled to a binary. Our codegen in `shuttle_runtime::main` will embed a gRPC server in the binary that we will be used to start and stop your service, as well as a `Loader` struct that will provision the resources you request in the arguments to your main function. Your service will then be started on Shuttle’s infrastructure in the `eu-west2` region of AWS.

### Project Limitations

Currently we limit a project container’s memory usage to `4GB` during high contention and `6GB` otherwise.
## Deploying your Project

CPU usage per project is currently limited to four threads. However, because of how this limit is implemented through Docker, popular crates like `num_cpus` may think it has access to all of the host’s threads.
When you run `cargo shuttle deploy`, your project code is archived and sent to our servers where it is compiled. Our codegen in `shuttle_runtime::main` will embed a gRPC server in the binary that we will be used to start and stop your service, as well as a `Loader` struct that will provision the resources you request in the arguments to your main function. Your service will then be started on Shuttle's infrastructure in the `eu-west2` region of AWS.

In terms of database resources, the only restriction we have is that an RDS database has a max storage of `10GB`.
## More reading

Other than that any reasonable usage is acceptable during our beta, but we will intervene when we detect applications that use excessively large amounts of storage (after attempting to contact the owner).
Check out the [files](/configuration/files) and [environment](/configuration/environment) sections for more details.

---

If you wish to contribute to Shuttle and learn more about how Shuttle works under the hood, check out our [Contributing Guide](/community/contribute).
If you wish to contribute to Shuttle and learn more about how Shuttle works under the hood, check out our [Contributing Guide](/community/contribute).
62 changes: 34 additions & 28 deletions migration/migrating-to-shuttle.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,55 +3,60 @@ title: "Migrating to Shuttle"
description: "Short guide on how to migrate your existing project over to Shuttle"
---

## Setup

### Setup
<Note>
This guide assumes that you have Shuttle already setup.
If you don't, head on over to our [installation](/getting-started/installation) guide.
</Note>

This guide assumes that you have Shuttle already setup. If you don't, head on over to our [installation](/getting-started/installation) & [quick start](/getting-started/quick-start) guides in order to install Shuttle & create your first project.
For this example, we'll assume you are migrating an Axum project.

For this example, we'll assume you are migrating your Axum project. Once you've created your project, you'll want to add `shuttle_runtime` and `shuttle_axum` to your dependencies to be able to use shuttle's runtime with the Axum framework. You can run the following command below like so to do this:
The first step is to add `shuttle-runtime` and `shuttle-axum` to your dependencies to be able to use Shuttle's runtime with the Axum framework.

```bash
cargo add shuttle_runtime shuttle_axum
cargo add shuttle-runtime shuttle-axum
```

Any secrets you need to use will be kept in a `Secrets.toml` file (dev secrets to be held in `Secrets.dev.toml`) which will be placed at the `Cargo.toml` level - you'll want to use the `shuttle_secrets` crate to be able to use the new secrets:
Any [secrets](/resources/shuttle-secrets) you need to use will be kept in a `Secrets.toml` file (dev secrets to be held in `Secrets.dev.toml`) which will be placed at the `Cargo.toml` level - you'll want to use the `shuttle-secrets` crate to be able to use the new secrets:

```bash
cargo add shuttle_secrets
cargo add shuttle-secrets
```

Your secrets file will look the same as your previous .env file, so you won't need to change anything.

You can also easily get a provisioned database like so (this example will be for a provisioned PostgresQL instance specifically):
You can also easily get a provisioned database like so (this example will be for a provisioned PostgreSQL instance specifically):

```bash
cargo add shuttle-shared-db --features postgres
```

If you have any database records you'd like to keep, it would be a good idea to make sure you export them before you start as you'll want to make sure those are preserved; otherwise, you'll lose the data. **You will not need a secrets file if you only need a provisioned PG database - this will be automatically be provisioned to you in the form of a SQLx connection.**
If you have any database records you'd like to keep, it would be a good idea to export them so that they can be migrated to the new database.
**You will not need a secrets file if you only need a provisioned Postgres database - this will be automatically be provisioned to you in the form of a SQLx connection.**

### Migrating your Code
## Migrating your Code

To be able to run your project on Shuttle, you need to make a few changes to your code. Instead of running on the `tokio` runtime, you should use the `shuttle_service::main` macro instead like so and swap out `dotenvy` for Shuttle's Postgres annotation:
To be able to run your project on Shuttle, you need to make a few changes to your code.
Instead of the `tokio::main` macro, you will use the `shuttle_runtime::main` macro and swap out `dotenvy` for Shuttle's Postgres annotation:

This is what your `main.rs` file looks before:

```rust
// main.rs
```rust main.rs
#[tokio::main]
async fn main() {
dotenv().ok();
dotenvy::dotenv().ok();

let postgres = dotenvy::var("DATABASE_URL").expect("No database URL was set!");
let url = dotenvy::var("DATABASE_URL").expect("No database URL was set!");

let postgres = sqlx::Pool::connect(&postgres).await.unwrap();
let pool = sqlx::Pool::connect(&url).await.unwrap();

sqlx::migrate!()
.run(&postgres)
.run(&pool)
.await
.expect("Migrations failed :(");

let router = create_api_router(postgres);
let router = create_api_router(pool);
let addr = SocketAddr::from(([0, 0, 0, 0], 8000));

Server::bind(&addr)
Expand All @@ -63,32 +68,33 @@ async fn main() {

And this is what it looks like after:

```rust
```rust main.rs
#[shuttle_runtime::main]
pub async fn axum (
#[shuttle_shared_db::Postgres] postgres: PgPool,
#[shuttle_secrets::Secrets] secrets: shuttle_secrets::SecretStore
#[shuttle_shared_db::Postgres] pool: PgPool,
#[shuttle_secrets::Secrets] secrets: shuttle_secrets::SecretStore,
) -> shuttle_axum::ShuttleAxum {

sqlx::migrate!()
.run(&postgres)
.run(&pool)
.await
.expect("Migrations failed :(");

let router = create_api_router(postgres);
// Use secrets for anything that needs them

let router = create_api_router(pool);

Ok(router.into())
Ok(router.into())
}
```

If you need more than a simple router, you'll want to create a custom struct that holds all of your required app state information inside and then create an `impl` for the struct - you can find more about that [here.](https://docs.shuttle.rs/tutorials/custom-service) Anything outside of your entry point function (the function that uses the `shuttle_runtime::main` macro) doesn't need to be changed. If you are using secrets as well as a database connection, you may wish to create a struct that holds both of these values and then pass it into the function that generates the router.

### Deploying
## Deploying

If you haven't yet, you will probably want a `Shuttle.toml` file at the `Cargo.toml` level to name your project to whatever you'd like, like so:
To ensure that you get a unique project name, create a `Shuttle.toml` file at the `Cargo.toml` level to name your project to whatever you like.

```ini
name="<app-name-here>"
```toml
name = "my-unique-app-name-here"
```

Now all you need to do is to run the following commands:
Expand Down
Loading