Run your own deploy platform.
OxDe is a self-hostable alternative to Vercel, Netlify, and Coolify, written in Rust, small enough to run on a Raspberry Pi. It gives you app/deployment management via a dashboard and JSON API, subdomain-based routing, zip-upload and git-based deploys (including a build step), and long-lived app processes run in rootless Podman containers.
- Git deploys: shallow clone straight from a repo URL and branch, no CI runner in between.
- Zip upload: drag a build folder into the dashboard when there's no repo to point at.
- Run real apps: not just static files, long-running processes run in their own containers.
- Subdomain routing: each app gets its own origin, isolated from every other app on the instance.
- Build step: set a build command and OxDe runs it in a container before serving the output.
- Dashboard & API: everything the dashboard does is a call to the same JSON API you can script against.
- Rust, edition 2024 (a recent stable toolchain, install via rustup).
- Vite+ installed globally, so the
vpcommand is on yourPATH, used to build the dashboard frontend (oxde-ui/). Vite+ manages the Node.js runtime and package manager (pnpm) for you. - Podman (rootless), reachable at its default local socket, needed to run git-sourced apps declared as a long-lived process ("run mode") or with a build step. Not required for zip-upload or static git deploys.
- On macOS, container IPs aren't reachable from the host by default; install
podman-mac-net-connectto route to them for local testing.
- On macOS, container IPs aren't reachable from the host by default; install
OxDe reads a TOML config file, oxde.toml in the working directory by default (override with $OXDE_CONFIG). Copy oxde.example.toml to oxde.toml and adjust it, it documents every setting, required and optional, with comments.
Building always builds the dashboard frontend first, since dashboard_assets.rs's rust-embed derive needs oxde-ui/dist to exist at compile time.
cargo xtask build # builds oxde-ui/dist, then cargo build
cargo xtask build -- --release # release build
cargo xtask build-ui # dashboard frontend only (vp install && vp build in oxde-ui/)
cargo run # requires cargo xtask build-ui at least once firstOther useful commands:
cargo test # run tests
cargo test <test_name> # run a single test
cargo check # check without building
cargo +nightly fmt # format
cargo clippy # lintoxde-db/ holds OxDe's SQLite-compatible database (data_dir/oxde.db, via turso/toasty) and its schema, defined in oxde-db/src/models.rs. Schema changes go through migrations rather than being pushed wholesale on every startup.
OxDe applies any pending migration automatically on startup - there's nothing to run by hand to bring an existing data_dir/oxde.db up to date.
When you change a model in oxde-db/src/models.rs, generate the migration for it and commit the result:
cargo xtask migration generate --name describe_the_changeThis diffs the new model shape against the last generated snapshot and writes the SQL migration, an updated schema snapshot, and a history entry under toasty/ (toasty/migrations/, toasty/snapshots/, toasty/history.toml) - check all three into version control alongside the model change. cargo xtask migration apply runs the same apply step OxDe runs at startup, useful for testing a migration without starting the server; cargo xtask migration --help lists the rest (drop, reset, snapshot), inherited from toasty-cli.
oxde-ui/ is a React 19 + TypeScript + Vite+ project with its own package.json/lockfile, not part of the Cargo workspace. xtask/ (a real Cargo workspace member, aliased as cargo xtask via .cargo/config.toml) is what wires it into the Rust build above so it can't be forgotten.
To work on it directly:
vp install # install dependencies, run after cloning and whenever package.json/lockfile change
vp dev # start the Vite dev server with hot reload
vp build # type-check (tsc) and produce a production build
vp preview # preview a production build
vp check # format, lint, type-check
vp test # run testsIf setup, runtime, or package-manager behavior looks wrong, run vp env doctor. Run vp help for the full command list, or vp <command> --help for details on a specific one. Docs are local at node_modules/vite-plus/docs or online at https://viteplus.dev/guide/.
MIT, see LICENSE.