Get started
Go from a fresh Linux server to your first Upstand deployment.
Upstand is a self-hosted control plane for deploying applications, Docker Compose stacks, and databases to Docker Swarm. The first installation runs on one manager node; add workers after the control plane is healthy.
Before you start
Prepare these four things:
- A fresh Linux VM with at least 2 vCPU, 4 GB RAM, and 30 GB free disk. Ubuntu 22.04+ or Debian 12+ is the supported starting point.
- A DNS name for the dashboard and API, such as
app.example.comandapi.example.com, both pointing at the manager's public IP. This is recommended for production but optional for the first run: when the installer runs on a public IPv4 manager it can use temporaryapp.<ip>.nip.ioandapi.<ip>.nip.ioorigins automatically. - Inbound TCP 80 and 443 open to the internet. For a multi-node cluster, also allow TCP 2377, TCP/UDP 7946, and UDP 4789 between cluster nodes only.
- Root or passwordless-sudo SSH access to the manager.
Do not expose PostgreSQL, Redis, or the Upstand API directly. The installer keeps control-plane services private and Caddy exposes HTTPS entry points.
Install
Run this on the manager. Replace the example hosts before pasting it.
curl -fsSL https://raw.githubusercontent.com/mhbdev/upstand/master/install.sh | sudo bashIf you already have domains, export BETTER_AUTH_URL, CORS_ORIGIN, and NEXT_PUBLIC_SERVER_URL before running the command. The installer is non-interactive by default; when origins are omitted it derives temporary HTTPS nip.io origins from the public IPv4 address. To answer origin prompts explicitly, pass --interactive. Replace temporary origins in /etc/upstand/.env and rerun the installer after DNS is ready.
The first run installs Docker when required, initializes Swarm, creates an attachable upstand-network, pulls immutable release images, generates Docker secrets under /etc/upstand/secrets/, and waits for Postgres, Redis, API, dashboard, and docs health checks.
Open https://app.example.com/login. The first person to open a new installation creates its owner account. Store that account securely: later visitors can sign in but cannot create a second bootstrap owner.
Verify
docker stack services upstand
curl -fsS https://api.example.com/health/readyEvery service should report 1/1; the health response must report database, Redis, workers, and Caddy as ready.
Next: self-hosting, remote servers, or deployments.
Local development
The repository has one local topology: docker-compose.local.yml. It provides
PostgreSQL, Redis, the hot-reloading API, the dashboard, and the documentation
site with bind mounts. Start it with:
bun run docker:local:up
bun run db:pushThe production topology is intentionally separate: docker-compose.prod.yml is
a Docker Swarm stack consumed by install.sh. There is no third default
Compose file.