Guides
Self-hosting
You can run the Oloproof workbench on your own server: on premises, in a private cloud, or with a Canadian cloud provider. The bundle in deploy/self-hosted/ runs the same two images as oloproof.com (web and worker) and PostgreSQL, pulled by digest. Your data stays wherever you run it, and nothing is sent to Oloproof.
Requirements
- One Linux host with Docker Engine and the Compose plugin. 4 GB of memory and 2 CPUs are enough for a team; the worker is capped at 1.5 GB and the web at 768 MB.
- Disk for PostgreSQL. Every run you push is stored there.
- A reverse proxy for HTTPS (Caddyfile.example is a working example; nginx works too).
- Access to ghcr.io/etobicoke/oloproof, or the images copied into your own registry.
Install
cd deploy/self-hosted
sh generate-env.sh # writes .env and fills every secretSet OLOPROOF_WEB_IMAGE, OLOPROOF_WORKER_IMAGE (both ...@sha256: digests) and OLOPROOF_PUBLIC_URL in .env, and at least one way to sign in: mail for password accounts (OLOPROOF_MAIL_FROM with OLOPROOF_SMTP_URL or OLOPROOF_RESEND_API_KEY) or an OAuth provider. The web refuses to start without one. Then start it:
docker compose --env-file .env up -d
curl -fsS http://127.0.0.1:3000/api/healthThe migrate service brings the database up to date before the web and worker start. Sign-up is by invitation, issued with OLOPROOF_OPERATOR_TOKEN (deploy/README.md, "Signup").
Configuration
.env.example lists every variable the web and worker read, each marked required, generated or optional. An empty optional variable turns its feature off. Keep the generated secrets: a new database password locks the database out, and a new signing key starts a new signer. A self-hosted bundle has no billing, so every workspace has the free tier's monthly case counts; raise OLOPROOF_FREE_TIER_PUSHED_MONTHLY and OLOPROOF_FREE_TIER_MANAGED_MONTHLY for your team.
No outbound network by default
The stack sends no telemetry and calls no Oloproof service. It reaches the network only for what you turn on: mail (an SMTP relay inside your network, or Resend), OAuth sign-in, Turnstile, and the model providers a workspace stores a key for. With none of them set it runs with no route out. For an air-gapped host, copy the three images into your own registry and point the image variables at it. Password accounts need mail, so on an air-gapped network set OLOPROOF_SMTP_URL to a relay inside it.
Backups
sh backup.sh /srv/backups/oloproofbackup.sh writes a compressed pg_dump to the directory you choose. Schedule it with cron or a systemd timer, and copy the directory off the host yourself. The script shows the restore command.
The dump does not hold .env, and .env holds OLOPROOF_CONTENT_KEY and the other generated secrets: without it a restored database cannot read its encrypted content. Back up .env when you create it and whenever you change it, separately from the dumps and offline (a password manager or an encrypted drive), never beside them.
Upgrades
Write the new release's two digests into .env, then run:
sh upgrade.sh /srv/backups/oloproofIt backs up, pulls, migrates and restarts the web and worker. Expect a short interruption. To roll back, write the previous digests and restore the backup it took.
What is supported
- One host. There is no high availability: the stack is as available as its machine.
- Data residency is wherever you run it. Oloproof holds none of your data.
- No zero-downtime releases. Those belong to the hosted service only.
- The bundle is checked by deploy/self-hosted/check.sh, which starts it under its own project name, waits for /api/health, fetches the public pages and removes it.