Deploydodo is a self-hosted deployment dashboard: a Rust (Axum) backend, a React frontend, and an SSH-based terminal (dodosh) for connecting to servers — including the machine deploydodo itself runs on ("local" servers), which are just an SSH connection to a fixed host under the hood.
- Rust (stable toolchain)
- cargo-make —
cargo install cargo-make - sqlx-cli —
cargo install sqlx-cli --no-default-features --features postgres,rustls - Node.js
v22.12.0and npm - Docker with Docker Compose (used to run Postgres locally, and to build/run the staging deployment)
- An SSH server running locally (e.g. macOS's built-in Remote Login) — deploydodo's "local server" feature connects to your own machine over SSH
git clone https://github.com/LibertyRepublic/deploydodo deploydodo
cd deploydodo
npm install --prefix frontenddeploydodo talks to the machine it's running on the same way it talks to any remote server: over SSH. configure_rsa.sh generates a keypair and authorizes it for the current user:
./configure_rsa.shThis creates key_rsa / key_rsa.pub in the repo root and appends the public key to ~/.ssh/authorized_keys. Both key_rsa* files are gitignored — treat key_rsa as a secret.
Make sure Remote Login (Mac OS) / an SSH daemon is actually enabled on your machine and reachable on the port you'll configure below, or the local-server terminal feature won't be able to connect.
Create a .env file in the repo root (gitignored) with:
DATABASE_URL=postgres://deploydodo:deploydodo@localhost:5432/deploydodo
LOCAL_SSH_HOSTNAME=localhost
LOCAL_SSH_PORT=22
LOCAL_SSH_USERNAME=<your local username>
LOCAL_SSH_PRIVATE_KEY=key_rsaDATABASE_URLmust match the Postgres credentials indev.docker-compose.yaml(deploydodo/deploydodo/ dbdeploydodoon port5432by default).LOCAL_SSH_PRIVATE_KEYis a path to the private key file (not the key contents) — point it atkey_rsafrom step 2.- These are loaded once at startup by
backend/src/env.rs; the process panics immediately if any are missing or invalid, so this is the one file to get right before running anything.
cargo make devThis single command:
- Starts a Postgres container via
dev.docker-compose.yaml(port5432, persisted in a named volume) - Runs the backend (
cargo run -p backend), which applies pendingsqlxmigrations automatically on startup - Runs the frontend dev server (
npm run dev) in parallel
The backend listens on http://localhost:3000 and serves the API; the frontend dev server prints its own URL (typically http://localhost:5173) with API requests proxied through to the backend.
Open the frontend URL. Since no admin user exists yet, you'll land on the setup wizard:
- Create an admin account — name, email, password (8+ characters).
- Add a server — choose "local" to connect to the machine deploydodo is running on (via the SSH config from step 3), or "remote" to add another server by hostname + SSH key.
From there you can open a terminal to any configured server from the dashboard.
| Task | Command |
|---|---|
| Run backend + frontend + dev DB | cargo make dev |
| Run just the backend | cargo make backend |
| Run just the frontend | cargo make frontend |
| Add a new migration | cargo make migration <name> |
| Revert the last migration | cargo make undo-migration |
| Regenerate the frontend's typed API client from the backend's OpenAPI schema | cargo make generate-schema |
Migrations live in backend/migrations and run automatically whenever the backend connects to the database — no separate migrate step needed in normal development.
The Docker image expects pre-built artifacts rather than building Rust/Node inside the container, so build first, then bring up the stack:
cargo make build-backend-linux # cross-compiles the backend for aarch64-unknown-linux-musl
cargo make build-frontend # builds the frontend into target/dist
cargo make compose # builds the Docker image and runs staging.docker-compose.yamlstaging.docker-compose.yaml additionally expects:
- A
local.envfile in the repo root — gitignored, not committed:
DATABASE_URL=postgres://deploydodo:deploydodo@dododb:5432/deploydodo
LOCAL_SSH_HOSTNAME=deploydodo.host
LOCAL_SSH_PORT=22
LOCAL_SSH_USERNAME=benjamin
LOCAL_SSH_PRIVATE_KEY=key_rsa- The
key_rsaprivate key generated in step 2, mounted into the container at/key_rsa.
The staging compose file runs Postgres and the app on an internal network, exposing only the app on port 3000.
backend/— Axum API server, Postgres access viasqlx, OpenAPI schema generationdodosh/— SSH/terminal crate used by the backend to connect to local and remote serversfrontend/— React + Vite dashboard UIdev.docker-compose.yaml/staging.docker-compose.yaml— local and staging deployment stacksMakefile.toml— allcargo maketask definitions