Install
What install.sh does, its options, and the flags you can pass to synap install.
The supported install path is install.sh, published with every release of the backend. It bootstraps a bare host
and hands over to the server CLI (synap install), which does the actual install. Images are pulled by digest from
the release manifest; nothing is built on the host.
Install the stable release
curl -fsSL https://github.com/synap-core/backend/releases/download/channel-stable/install.sh \
| sudo bash -s -- --domain pod.example.com --email you@example.comArguments after -- go to the installer.
What install.sh does
- Prerequisites. Installs
curl,tar,jqandopensslwithapt-getif one is missing (on a system withoutapt-getit stops and asks you to install it), installs Docker withget.docker.comif it is missing, and requires Docker Compose v2. - Release manifest. Downloads
release.jsonfor the release you asked for:stableby default. - Signature. Checks the manifest's keyless signature from Synap's CI with
cosign, ifcosignis installed. See Verifying releases. - Deploy bundle. Downloads the release's deploy bundle (the
synapscript,deploy/and Kratos configuration), checks its SHA-256 against the manifest, and unpacks it into/opt/synap. - CLI on PATH. Links
/opt/synap/synapto/usr/local/bin/synap. - Install. Runs
synap install --non-interactive --release <id>in/opt/synap, with every other flag you passed.
Run again with the same release, it re-enters synap install, which is idempotent and keeps your existing
deploy/.env. To move to another release, use synap update (see Upgrades).
install.sh options
| Option | Meaning |
|---|---|
--release <id|stable|fast> | The release to install. stable (default) is the latest tagged release; fast is the latest successful build of main; or a release ID such as v1.1.3. |
--dir <path> | Install directory. Default /opt/synap. |
--help | Print the usage. |
Environment variables: SYNAP_RELEASE (same as --release), SYNAP_DIR (same as --dir), SYNAP_BIN_DIR
(default /usr/local/bin) and SYNAP_RELEASE_VERIFY (see below). SYNAP_DOMAIN, SYNAP_EMAIL, SYNAP_ADMIN_EMAIL
and SYNAP_SMTP_URI are accepted as aliases of the matching flags.
synap install flags
These are passed through by install.sh. The installer always runs non-interactively.
| Flag | Meaning |
|---|---|
--domain <host> | The pod's host name, for example pod.example.com. |
--email <email> | Contact email for Let's Encrypt certificates. |
--admin-email <email> and --admin-password <secret> | Create the first admin during install. Both are needed in non-interactive mode. |
--smtp-uri <uri> | SMTP server for sign-in emails (SMTP_CONNECTION_URI). |
--edge caddy|tunnel|traefik | caddy (default): direct TLS. tunnel: Caddy behind a Cloudflare tunnel, needs --tunnel-token or --tunnel-token-file. traefik: an external edge in front of the pod. |
--tunnel cloudflare|pangolin, --tunnel-token <token>, --tunnel-token-file <path> | Expose the pod through a tunnel. Prefer --tunnel-token-file. |
--with-rsshub | Also start RSSHub and browserless (the rsshub profile). |
--intelligence-url <url>, --intelligence-key <key> | An Intelligence Service for the pod's built-in AI features. |
--name <name> | A pod name. Without --domain, the pod becomes pod.<name>.synap.live. |
--register-token <spr_…> | Register the pod with the Synap Control Plane, using a single-use code. Needs --name. See Connect to the Control Plane. |
--control-plane <url> | The Control Plane to register with (default https://api.synap.live). Only with --register-token. |
Run synap install --help on the server for the complete list.
Retired flags
install.sh refuses the flags of the retired installer with their new spelling instead of ignoring them:
--backend-version and --pod-agent-version (use --release), --control-plane-url and --provisioning-token
(use --register-token with --control-plane), and --token (use --register-token). --with-openclaw is accepted
and ignored: the pod no longer bundles an agent.
The first admin
Unless you passed --admin-email and --admin-password, or registered the pod with --register-token (the person
the code was created for becomes the owner), the pod starts with no admin. Create one from the server:
cd /opt/synap/deploy
sudo synap setup admin --email you@example.com --magic-link # prints a one-hour sign-up link
sudo synap setup admin --email you@example.com --password '<secret>' # or create the admin directly
sudo synap setup admin --status # needed | readyThe link opens https://<your domain>/setup?token=…, where you choose a password. Once the pod has an owner,
sudo synap setup admin --retire-token removes the bootstrap-only PROVISIONING_TOKEN from .env.
Verifying releases
Synap's CI signs every release manifest with a keyless cosign signature. SYNAP_RELEASE_VERIFY controls what the
installer (and synap update) does with it:
| Value | Behaviour |
|---|---|
warn (default) | Verifies when cosign is installed. A missing cosign, a missing signature or a failed check prints a warning and the install continues. |
enforce | Any of those refuses the install. |
off | No check, for a private mirror. |
Install cosign and set SYNAP_RELEASE_VERIFY=enforce to refuse unsigned or tampered releases. Set it on the sudo
command, because sudo drops variables exported in your shell:
curl -fsSL https://github.com/synap-core/backend/releases/download/channel-stable/install.sh \
| sudo SYNAP_RELEASE_VERIFY=enforce bash -s -- --domain pod.example.com --email you@example.com
sudo SYNAP_RELEASE_VERIFY=enforce synap updateA manual synap update also reads SYNAP_RELEASE_VERIFY from deploy/.env.
Installing from a checkout
Developers can run ./synap install --from-source --domain localhost in a clone of the backend repository to build
the images locally. This is a development path, not a way to run a production pod; see the contributing guide in the
backend repository.
