# Rustlift
[](https://www.rust-lang.org/)
[](https://github.com/hghalebi/rustlift/actions/workflows/rust.yml)
[](https://azure.microsoft.com/en-us/products/app-service/)
[](LICENSE)
Rustlift is a typestate-driven deployment tool that builds and deploys the Axum server in this repository to Azure App Service.
This repository is distributed as a source-available project under a
non-commercial license.
```text
Init -> Authenticated -> InfraReady -> ArtifactReady -> Live
```
Each transition is encoded in the type system, so invalid stage order is rejected at compile time.
## Quickstart
```bash
cargo install cross
az login
export AZURE_SUBSCRIPTION_ID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
cargo run --bin rustlift
```
## What Rustlift does
Running `cargo run --bin rustlift` performs one deployment pipeline:
1. Authenticates using your Azure CLI session.
2. Ensures Azure infrastructure exists:
Resource Group (`{APP_NAME}-rg`), Linux App Service Plan (`{APP_NAME}-plan`, SKU `B1`), and Web App (`APP_NAME`).
3. Builds `server` for `x86_64-unknown-linux-musl` using `cross`.
4. Creates `deploy.zip` containing `server` and `startup.sh`.
5. Deploys the zip with `az webapp deployment source config-zip`.
6. Verifies `https://{APP_NAME}.azurewebsites.net/health`.
## Prerequisites
| Rust (stable) | Build and run binaries | [rustup.rs](https://rustup.rs) |
| Docker | Required by `cross` images | [Get Docker](https://docs.docker.com/get-docker/) |
| cross | Cross-compile Linux `musl` binary | `cargo install cross` |
| Azure CLI (`az`) | Auth and zip deployment | [Install Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli) |
First-time setup:
```bash
cargo install cross
az login
rustup target add x86_64-unknown-linux-musl # optional, useful for IDE support
```
## Configuration
Rustlift is configured only through environment variables:
| `AZURE_SUBSCRIPTION_ID` | yes | none | Azure subscription ID |
| `APP_NAME` | no | `rust-enterprise-api` | Web App name and DNS prefix |
| `AZURE_LOCATION` | no | `eastus` | Region for Resource Group and App Service |
| `RUST_LOG` | no | `info` | Log level for `rustlift` |
| `PORT` | no | `8080` | Local/server runtime port for `server` binary |
Derived names:
- Resource Group: `{APP_NAME}-rg`
- App Service Plan: `{APP_NAME}-plan`
- Binary inside zip: `server`
## Feature flags
This project currently defines no Cargo feature flags.
## Usage
Deploy with defaults:
```bash
export AZURE_SUBSCRIPTION_ID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
cargo run --bin rustlift
```
Deploy with custom app and region:
```bash
AZURE_SUBSCRIPTION_ID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" \
APP_NAME=my-api \
AZURE_LOCATION=westeurope \
RUST_LOG=debug \
cargo run --bin rustlift
```
Run the Axum server locally:
```bash
cargo run --bin server
PORT=3000 cargo run --bin server
```
Endpoints:
| `/` | GET | `Hello, Azure!` | Basic service endpoint |
| `/health` | GET | `OK` | Health probe used by deployment verification |
## Infrastructure details
The Web App is configured with:
- `linux_fx_version = "DOTNETCORE|8.0"`
- `app_command_line = "sh startup.sh"`
- App settings:
- `WEBSITES_PORT=8080`
- `WEBSITE_RUN_FROM_PACKAGE=1`
- `https_only = true`
## Repository layout
| `src/main.rs` | Deployment CLI entrypoint (`rustlift`) |
| `src/pipeline.rs` | Typestate pipeline and Azure operations |
| `src/errors.rs` | Error taxonomy used across stages |
| `src/resilience.rs` | Retry wrapper and backoff policy |
| `src/bin/server.rs` | Axum app that is deployed |
| `Cross.toml` | Cross image config for Linux `musl` builds |
| `startup.sh` | Startup command wrapper executed on Azure |
| `examples/probe_deps.rs` | Azure SDK dependency probe example |
## Reliability model
- Errors are strongly typed via `DeployError` in `src/errors.rs`.
- Fatal errors (for example missing config or build failures) stop immediately.
- Transient errors (for example network/infra failures) are retried by `reliable_op` in `src/resilience.rs`.
- Retry policy:
- Max elapsed time: 5 minutes
- Max retry interval: 30 seconds
- Backoff multiplier: 1.5x
## Testing
```bash
cargo test
cargo run --example probe_deps
```
## Community
- Contribution guide: [`CONTRIBUTING.md`](CONTRIBUTING.md)
- Code of Conduct: [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md)
- Security policy: [`SECURITY.md`](SECURITY.md)
- Support policy: [`SUPPORT.md`](SUPPORT.md)
- Changelog: [`CHANGELOG.md`](CHANGELOG.md)
- Release process: [`RELEASE.md`](RELEASE.md)
## Troubleshooting
- `Missing AZURE_SUBSCRIPTION_ID`: export a valid subscription ID before running.
- `Azure CLI ('az') not found`: install Azure CLI and ensure it is on `PATH`.
- Auth failures: run `az login` again and retry.
- `cross` build failures: verify Docker is running and `cross` is installed.
- Health check failures: inspect Azure logs for startup or binding issues.
## Licence
This project uses a dual-licence model:
- Non-commercial use (learning, hobby, and non-commercial contributions): Rustlift Non-Commercial Licence v1.0.
- Commercial use: separate paid commercial licence.
See [`LICENSE`](LICENSE) for full terms.
Note: the current non-commercial licence is not OSI-approved.
If you plan a public source-available release, follow [`RELEASE.md`](RELEASE.md).
### Contributing
By submitting a pull request, you agree to license contributions under the same non-commercial terms and grant rights described in [`LICENSE`](LICENSE).