ちょっと話題の記事

RustのサーバレスプラットフォームShuttleを使ってみる

2022.10.11

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

Introduction

Shuttle は、Rustアプリを無料でデプロイ可能なクラウドプラットフォームです。
Shuttle は Rust ネイティブのクラウド開発プラットフォームで、
すべてのインフラストラクチャを管理しながらアプリをデプロイできます。

cargo shuttleコマンドでアプリケーションをパッケージ化し、
Shuttleのプラットフォームにデプロイ可能です。
そこでアプリがビルドされ、Shuttleから付与された
一意のサブドメインでアプリを公開できます。

Shuttleの主な特徴は以下になります。

Rustフレームワークのサポート

cargo shuttleコマンドでアプリのコードを生成するとき、
現状では下記フレームワークを指定して生成することができます。

  • Axum
  • Poem
  • Rocket
  • Salvo
  • Serenity
  • Tide
  • Tower

SerenityでDiscordのボットを作ることも可能。

DBなどのリソースをコードによってプロビジョニング可能

Shuttleではアノテーションを使用してデータストアやキャッシュと依存関係を記述します。
以下のように記述すれば、DBとの依存関係が起動時に設定されて使用することができます。

#[shuttle_service::main]
async fn rocket(
    #[shared::Postgres] pool: PgPool, //自動でDBのプロビジョニングを行い、プールされたコネクションを返す
) -> Result<...> {
    // application code
}

将来的には、インフラ関係の設定はコードから直接定義できるようになるとのことです。

簡単にデプロイ

コマンド1つで簡単にRustアプリをクラウドにデプロイできます。
デプロイは迅速に実施され、更新時のダウンタイムは発生しません。

# デプロイはこれだけ
% cargo shuttle deploy

Environment

  • OS :  MacOS 12.4
  • Rust : 1.62.1

Create Shuttle Application

では、Cargo ShuttleをインストールしてRustアプリをデプロイしてみましょう。

セットアップ&Hello world

まずはShuttle用コマンドラインツールをインストールします。

% cargo install cargo-shuttle

Shuttleのログインページにログインすると、APIキーが表示されます。
このAPIキーをつかってログインします。

% cargo shuttle login --api-key <API Key>

initコマンドでアプリの雛形を生成できます。
このとき、axumやrocketなど、ベースに使用するフレームワークを指定できます。
今回はaxumを指定。

% cargo shuttle init --axum shuttle-example && cd shuttle-example/

===============================
[2022/10/17 追記]

デプロイできなくなってたので、確認したらv0.6がリリースされて、
手順が追加されてました。
project newコマンドを実行して、
プロジェクトを作成する必要があるみたいです。
このコマンドを実行すると、内部で分離された
デプロイ用コンテナーが開始するとのこと。

% cargo shuttle project new

あと、SaivoとかWarpもサポートされてた。

===============================

src/lib.rsには、アプリコードが記述されています。
/helloにアクセスすればメッセージが表示される状態。

use axum::{routing::get, Router};
use sync_wrapper::SyncWrapper;

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

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

    Ok(sync_wrapper)
}

ローカルで起動するならrunを実行します。
localhost:8000/helloにアクセスすればメッセージが表示されます。

% cargo shuttle run
    Starting shuttle-example on http://127.0.0.1:8000

deployコマンドでshuttle環境にデプロイできます。

% cargo shuttle deploy
    Finished dev [unoptimized + debuginfo] target(s) in 26.56s

        Project:            xxxxx
        Deployment Id:      xxxxx
        Deployment Status:  DEPLOYED
        Host:               <URL>
        Created At:         2022-10-11 06:50:49.492625836 UTC

なお、デプロイ時に↓のようなエラーが出た場合、git commitしてから再度デプロイしましょう。

Caused by:
    2 files in the working directory contain changes that were not yet committed into git:

    Cargo.toml
    src/lib.rs

デプロイしたアプリを削除するにはdelete。

% cargo shuttle delete

とても簡単にRustアプリの生成&デプロイができました。
まだα版なので不具合などもありますが、正式リリースが楽しみです。

References