Quickstart
Stand up a self-hosted Proliferate server in about 15 minutes.
From a fresh Linux host to a working team install: the server up under Docker Compose, the instance claimed, your desktop app connected, and your first teammate invited.
About 15 minutes of hands-on time, plus DNS propagation. The Docker page goes deeper on the server pieces.
Provision a host
You need:
- A Linux host (x86_64 or aarch64) with Docker Engine and the Compose v2 plugin.
- A DNS name pointed at it, like
proliferate.company.com. Skip this and use--evalbelow to evaluate without a domain. - Ports 80 and 443 reachable from your users and from the internet, so Let's Encrypt can issue certificates.
Install
The installer resolves the newest server release, verifies its checksum,
installs to /opt/proliferate, and boots the stack. Read it before running it as
root:
Or pipe straight to a shell if you trust the source:
No domain yet? --eval derives a hostname from the host's public IP
(<ip>.sslip.io) and still gets real Let's Encrypt TLS, with no DNS setup.
--version X.Y.Z pins a release instead of taking the newest.
The installer tracks the newest server-v* tag — never GitHub's generic
"latest", which is usually bundle-less. It generates .env.static with
SITE_ADDRESS and the image tag set, runs the same preflight bootstrap.sh
does, brings the stack up, and prints the claim URL:
The setup token prints just above that block. It is never served over HTTP — it
lives at /var/lib/proliferate/setup/setup-token inside the API container, so a
publicly reachable server is safe while it waits to be claimed.
The token stays valid until you claim the instance. doctor.sh checks status and
wait-for-health.sh reprints the token, both under
/opt/proliferate/server/deploy.
Rerunning the installer is safe: it refreshes the scripts and leaves
.env.static, generated secrets, and data alone. To fetch the bundle and run
bootstrap.sh yourself, see
Docker on any server.
Claim your instance
Open the claim URL and enter your email, a password, and the setup token. The organization name is optional — leave it blank and it comes from your email domain.
Submitting creates your account, makes you the owner, and closes signup for
good: /setup returns 404 from then on.
Self-hosted servers run in single-org mode by default: SINGLE_ORG_MODE is on
whenever PROLIFERATE_TELEMETRY_MODE is not hosted_product, so there is one
organization and everyone you invite joins it.
Connect the desktop app
Everyone can already work in a browser at https://proliferate.company.com.
Connect the desktop app when you need local repositories or a local AnyHarness
runtime.
Download it, choose Connect to a server on the sign-in screen, and enter your URL. The app verifies the server, shows its host and version, and relaunches connected.
For fleets, write the same setting to ~/.proliferate/config.json:
The file is read once at startup, so restart to apply it. Add
"telemetryDisabled": true to turn off desktop telemetry for that install. See
Connect the desktop app.
Sign in
Sign in with the email and password you set at /setup.
The app asks your server which methods it offers (GET /auth/desktop/methods).
Without GitHub OAuth configured, that is the email and password form. The base
install needs no OAuth app.
To add GitHub sign-in, create a GitHub OAuth app with callback URL
https://proliferate.company.com/auth/github/callback, set
GITHUB_OAUTH_CLIENT_ID and GITHUB_OAUTH_CLIENT_SECRET, and restart. See
GitHub sign-in.
Invite your team
Invite each teammate by email from the desktop app. Registration is invite-only and proven by token: the server answers any unknown or mismatched token with the same 403.
Every pending invitation has a Copy invite link action, pointing at your registration page with the token and email prefilled:
They open it, choose a password, and land in your organization. Then they install the desktop app and connect it to your server.
Configure email delivery (Resend, optional) and the server sends the link for you. Inviting the same email again issues a fresh link and kills the old one.
Roles are honored: invite someone as an admin and they are one the moment they
register. ALLOWED_EMAIL_DOMAINS restricts which emails you can invite.
ADMIN_EMAILS in .env.static guarantees admins: every listed email holds at
least the admin role, reasserted at each sign-in. It is also how you recover
from a lockout — add your email, restart, sign in.
Removing an email never demotes anyone, and the last admin can never be removed.
The flip side: a listed email is reinstated at its next sign-in, so offboarding
someone on the list means removing them from ADMIN_EMAILS and restarting.
Updating
Updating is one command, from /opt/proliferate/server/deploy:
Your server reports versions at GET /meta, and desktop update checks route
through it — GET /desktop/updater/latest.json redirects to the signed build
matching the version your server pins. Connected apps follow the server, so
updating the server updates the fleet. See
Updates & versioning.
What's not here yet
Scheduled background jobs are not available on self-hosted servers. The stack ships no worker tier.