Quickstart
One path, no choices: a fresh Ubuntu or Debian server, the installer, the setup interview, and the owner-claim token. Everything else is a decision you can make later.
Before you start, read Requirements and sizing — the floor is 4 vCPU and 8 GB of RAM, and the reason is transcoding, not web serving.
docker-compose.prod.yml uses the !reset / !override merge tags to close the
Postgres, Redis and search port publishes. On an older Compose those tags are
silently ignored and your database is published to the internet while the
deploy reports success. deploy.sh, rollback.sh and restore.sh each parse
docker compose version --short and refuse to run below 2.24. The installer
installs a current Compose for you; verify with nmap from another host anyway.
Do not use a 2 GB droplet. ffmpeg runs inside the api container, so one
TargetAll job on a 1080p source is twelve full-source encode passes. Postgres,
api, frontend, search, Caddy and one transcode need roughly 4 GB before ClamAV.
Step 1 — run the installer
On the server, as a user who can sudo:
curl -fsSL https://raw.githubusercontent.com/yegamble/vidra/main/install.sh | sh
It detects the platform, installs Docker Engine and the Compose v2 plugin from
Docker's own apt repository if they are missing, downloads vidra-core's latest
release bundle, verifies it against the release's SHA256SUMS, unpacks it into
/opt/vidra, installs the checksum-verified vidra CLI into
/usr/local/bin, and then hands the terminal to vidra setup.
Everything it would change sits behind one confirmation, read from
/dev/tty because under curl … | sh stdin is the script itself. Pass --yes
where there is no terminal to ask on.
You should now see the installer's summary of what it found and what it installed, followed immediately by the first question of the setup interview. Nothing is running yet: the installer starts no containers and opens no ports.
Step 2 — answer vidra setup
The interview writes env/production.env (mode 0600) and renders
deploy/Caddyfile.local from the deployment template. It asks for your domain
and TLS mode, media storage, which optional components you want, and mints every
secret the template leaves blank.
vidra setup --template env/production.env.example # if you need to re-run it
vidra setup --template env/production.env.example --web # same questions, in a browser
Re-running is safe. The file being written is always read back first and every
value it already sets is preserved; a secret is only ever replaced when
--rotate names it. The installer never passes --yes to it, so an existing
env file is never silently rewritten.
Then bring the stack up:
cd /opt/vidra
vidra deploy
You should now see vidra deploy walk its gated pipeline — pre-deploy dump,
pull, the two migrators, up -d --no-build, health probes — and finish with
/readyz answering 200. Confirm it yourself:
curl -fsS http://127.0.0.1:8080/readyz
Step 3 — claim the owner account
The first admin is claimed, not registered. While the instance is unclaimed
— empty users table, unredeemed token — every signup path answers
403 owner_claim_required. The only way in is a one-time token the api mints at
boot and prints to its own log.
./deploy/compose.sh logs api | grep 'FIRST-RUN SETUP REQUIRED'
Use compose.sh, never a bare docker compose logs api — on a deployment host
the bare form auto-loads docker-compose.override.yml and addresses a different
project than the deploy scripts do. Take the newest line: every api restart
mints a fresh token and invalidates the previous one.
Redeem it at https://<your domain>/setup/claim in the browser, or directly:
curl -X POST https://example.com/api/v1/setup/claim-owner \
-H 'Content-Type: application/json' \
-d '{"token":"<the token>","username":"...","email":"...","password":"..."}'
Only the token's hash is stored, so a lost token is re-minted by restarting the api — never recovered.
You should now see your instance's home page at your domain, and be able to
sign in as the owner. Verify you actually got admin before you trust it:
GET /api/v1/admin/system with your access token must return 200, and /admin
in the UI must render.
Next steps
- Lock the box down. Production deployment
covers the firewall, the swapfile, the backup timer and the
nmapcheck that proves your database is not on the internet. - Decide your registration policy.
REGISTRATION_ENABLED=falseis the right default for a private launch; see Moderation and instance settings. - Prove your backups work. Run
./deploy/backup.shonce by hand, then restore it into a scratch stack. See Operator CLI. - Coming from PeerTube? Migrate from PeerTube.
- Just want to develop against it? Development setup.