Migration checklist

Before starting your migration, check if your project meets these requirements:

✅ Supported Service Types

⚠️ Other Considerations

  • External resources can still be used by connecting to them
  • Database migrations need to be handled separately
  • Check that your project:
    • Is compatible with the latest Rust version
    • Can be built and run in a Docker container
If you’re unsure about any compatibility requirements, join our Discord community for help!

Migration Steps

Remember to install the Klyra CLI if you haven’t yet!

1. Add Klyra Dependencies

Add the required Klyra dependencies to your Cargo.toml:

# Add the Klyra runtime
cargo add klyra-runtime

# Add your framework integration if supported (e.g., for Axum)
cargo add klyra-axum

# Add any Klyra resources you need (e.g., Postgres)
cargo add klyra-shared-db --features postgres,sqlx

2. Update Your Main Function

Common steps needed for migrating are:

  • Change the main function to use #[klyra_runtime::main].
  • Change the return type and return the framework’s Router or config. This varies by framework, check examples for more.
  • Add a Secrets.toml file and use #[klyra_runtime::Secrets] instead of loading environment variables.
  • Use #[klyra_shared_db::Postgres] instead of manually connecting to a database.

Here is an example of what an Axum service might look like before and after migrating:

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

    let db_url = std::env::var("DATABASE_URL").unwrap();
    let secret = std::env::var("MY_SECRET").unwrap();

    let pool = sqlx::Pool::connect(&db_url).await.unwrap();
    sqlx::migrate!().run(&pool).await.unwrap();

    // Use secrets for anything that needs them

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

    Server::bind(&addr)
        .serve(router.into_make_service())
        .await
        .unwrap()
}
main.rs (after)
#[klyra_runtime::main]
async fn main(
    #[klyra_shared_db::Postgres] pool: PgPool,
    #[klyra_runtime::Secrets] secrets: klyra_runtime::SecretStore,
) -> klyra_axum::KlyraAxum {
    sqlx::migrate!().run(&pool).await.unwrap();

    // Use secrets for anything that needs them

    let router = create_api_router(pool);

    Ok(router.into())
}

3. Add Klyra configuration

If your app uses gitignored files, or uses static files at runtime, you need to add a Klyra.toml file with some file declarations. Read more in Deployment files.

4. Testing it locally

klyra run

5. Deploy

If everything is ready to launch:

klyra deploy
The first deployment might take a few minutes as it sets up your infrastructure.

Next Steps