Announcing Proliferate
Proliferate

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 --eval below 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:

curl -fsSLO https://raw.githubusercontent.com/proliferate-ai/proliferate/main/server/deploy/install.sh
less install.sh
sudo bash install.sh --domain proliferate.company.com

Or pipe straight to a shell if you trust the source:

curl -fsSL https://raw.githubusercontent.com/proliferate-ai/proliferate/main/server/deploy/install.sh \
  | sudo bash -s -- --domain proliferate.company.com

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:

Installed server-v0.3.18

  Control plane:  https://proliferate.company.com
  Claim page:     https://proliferate.company.com/setup   (open in a browser with the setup token above)

  Manage this instance from /opt/proliferate/server/deploy:
    Update:   sudo /opt/proliferate/server/deploy/update.sh
    Doctor:   sudo /opt/proliferate/server/deploy/doctor.sh

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:

{
  "apiBaseUrl": "https://proliferate.company.com"
}

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:

https://proliferate.company.com/register?token=<invitation-id>&email=<email>

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.

Info:

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:

sudo ./update.sh   # pull the new image, run migrations, restart

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

Info:

Scheduled background jobs are not available on self-hosted servers. The stack ships no worker tier.

Next steps

On this page