Skip to content

elitan/velo

Repository files navigation

Velo

Velo

Web-first Postgres branching.

Velo runs a small self-hosted control plane for production Postgres, backups, PITR, and disposable dev branches.

Model

  • Production Postgres runs on a prod server.
  • Velo web UI runs on a dev/control server.
  • Production uses pgBackRest backups and PITR.
  • Dev branches run as Docker Postgres containers on ZFS copy-on-write datasets.
  • Production is special, but appears beside branches in the UI.

Requirements

  • Ubuntu/Debian dev server
  • Ubuntu/Debian prod server
  • SSH access from dev to prod
  • Bun
  • Docker
  • ZFS
  • PostgreSQL client tools
  • pgBackRest

Install

On the dev/control server:

curl -fsSL https://raw.githubusercontent.com/elitan/velo/main/scripts/install.sh | bash

The installer clones the repo, installs runtime dependencies, builds the web UI, runs SQLite migrations, and starts velo-web on port 3000.

Open:

http://<dev-server-ip>:3000

Development

bun install
bun run db:migrate
bun run dev

Local Docker Loop

For fast local product work without Hetzner:

bun run local:reset
bun run local:dev

Open:

http://localhost:3000

This starts:

  • local prod Postgres on localhost:55432
  • local dev Postgres on localhost:55433
  • local MinIO on localhost:59000
  • local SQLite at .velo/local-docker.sqlite
  • real pgBackRest backups and WAL archive to MinIO

Local Docker is prod-like for backup and PITR work. It creates a pgBackRest stanza, checks WAL archiving, runs a full backup, and can restore a temporary Postgres container from PITR. It still does not prove SSH, systemd, Hetzner networking, R2, or ZFS COW. Use remote dev before merging infra-sensitive work.

Each git branch gets one local environment by default. Ports are assigned once and stored in .velo/local/<branch>/env, so multiple branches can run on the same computer without port collisions.

Useful local stack commands:

bun run local:up
bun run local:status
bun run local:down

Useful checks:

bun run typecheck
bun run test
bun run web:build
bash -n scripts/*.sh

Deploy

VELO_DEPLOY_DEV_HOST=157.180.22.136 \
VELO_DEPLOY_PROD_HOST=89.167.89.255 \
VELO_DEPLOY_USER=root \
VELO_DEPLOY_KEY=$HOME/.ssh/frost-e2e-ci \
bun run deploy

This resets the Hetzner app and database state, installs Velo, bootstraps Postgres and pgBackRest, and starts velo-web.

Remote Vite loop:

VELO_REMOTE_HOST=157.180.22.136 bun run remote:dev
VELO_REMOTE_HOST=157.180.22.136 bun run remote:sync

Repo Shape

src/db        SQLite schema, migrations, generated DB types
src/server    tRPC routers, jobs, setup, branch, restore services
src/web       TanStack Start UI
src/managers  Docker, ZFS, WAL, cert adapters
src/utils     small shared helpers
scripts       install, deploy, remote dev, cleanup

Notes

Velo v2 is web only. There is no CLI entrypoint, no npm binary, and no JSON state engine. Local state lives in SQLite at .velo/velo.sqlite.

About

Postgres with instant branching

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages