関連記事
こちらの記事の補足。
shuttleにデプロイする際に、環境変数を読み込むようにした。
実装
shuttleの公式はかなり分かりやすく、ほとんどサンプル通りに組むことで実装できた。
コード
Secrets.toml
APP_URL = 'WEBアプリケーションのURL'
main.rs
#[shuttle_runtime::main]
async fn axum(
#[shuttle_shared_db::Postgres] pool: PgPool,
+ #[shuttle_runtime::Secrets] secrets: SecretStore,
) -> shuttle_axum::ShuttleAxum {
// loggingの初期化
// RUST_LOG=debug cargo run
let log_level = env::var("RUST_LOG").unwrap_or("info".to_string());
env::set_var("RUST_LOG", log_level);
+ let app_url = secrets.get("APP_URL").expect("undefined [APP_URL]");
sqlx::migrate!()
.run(&pool)
.await
let app = create_app(
TodoRepositoryForDb::new(pool.clone()),
LabelRepositoryForDb::new(pool.clone()),
+ app_url,
);
// axum 0.7.5
let listener = tokio::net::TcpListener::bind("0.0.0.0:8000").await.unwrap();
tracing::debug!("listening on {:?}", listener);
axum::serve(listener, app.clone()).await.unwrap();
Ok(app.into())
}
fn create_app<Todo: TodoRepository, Label: LabelRepository>(
todo_repository: Todo,
label_repository: Label,
+ app_url: String,
) -> Router {
let allowed_origins = vec![
"http://localhost:3001".parse().unwrap(),
"http://127.0.0.1:3001".parse().unwrap(),
"http://localhost:8080".parse().unwrap(),
"http://127.0.0.1:8080".parse().unwrap(),
+ app_url.parse().unwrap(),
];
let cors = CorsLayer::new()
.allow_origin(AllowOrigin::list(allowed_origins))
.allow_methods(Any)
.allow_headers(vec![CONTENT_TYPE]);
Router::new()
.route("/", get(root))
.route("/todos", post(create_todo::<Todo>).get(all_todo::<Todo>))
.route(
"/todos/:id",
get(find_todo::<Todo>)
.delete(delete_todo::<Todo>)
.patch(update_todo::<Todo>),
)
.route(
"/labels",
post(create_label::<Label>).get(all_label::<Label>),
)
.route("/labels/:id", delete(delete_label::<Label>))
.layer(Extension(Arc::new(todo_repository)))
.layer(Extension(Arc::new(label_repository)))
.layer(cors)
}
デプロイ時のコマンドは特に変更なく、cargo shuttle deploy --no-test
でデプロイ完了した。
公式ドキュメントによると、開発環境と本番環境で分けたい場合は--secrets [file]
のオプションを追加するとよさそう。
派生記事リンク