Self-Hosting

Self-Hosting

Run Appstrate on your own infrastructure with the one-line installer or Docker Compose.

Self-hosting gives you control over your data, your network and your configuration. Appstrate has no third-party service dependency at boot: the database, queue, cache and storage all have in-process fallbacks, and everything else (Google or GitHub sign-in, SMTP, LLM providers, OpenTelemetry) is opt-in through environment variables.

Install

curl -fsSL https://get.appstrate.dev | bash

This downloads the appstrate CLI for your OS and architecture, verifies it against a minisign-signed checksum manifest, and puts it on your PATH (default ~/.local/bin). It then prints the next step:

appstrate install

appstrate install asks for a tier and an install directory (default ~/appstrate). On a fresh Docker-tier install it also asks for an optional owner email, a public URL (Enter keeps http://localhost:<port>) and the agent execution backend. It asks for a port only if the default one is taken. It generates the secrets, writes .env and docker-compose.yml, starts the stack, waits for the health check and opens the dashboard. Press Enter at the tier prompt to take the recommended Tier 2 stack (PostgreSQL and Redis, files on a persisted volume). If Docker is not reachable, the default becomes Tier 0.

For unattended installs (CI, cloud-init, Ansible), pass --yes. The script then installs and starts everything in one command:

curl -fsSL https://get.appstrate.dev | bash -s -- --yes

Every appstrate install flag (--tier, --dir, --port, --app-url, --run-adapter) passes through. Details, the verification options and the lifecycle commands (appstrate start, stop, logs, status, uninstall) are in the self-hosting README. To manage the Compose files yourself, see Docker Compose.

Requirements

TierHost dependenciesWhat runs
0Bun 1.3.14 or later (the installer fetches Bun if it is missing, but does not check its version)PGlite, filesystem storage, runs as host subprocesses
1Docker Engine 20+ with Compose v2 (recommended, not checked by the installer), access to the Docker socketPostgreSQL
2Same as Tier 1PostgreSQL and Redis
3Same as Tier 1PostgreSQL, Redis and bundled MinIO

The self-hosting README recommends at least 4 GB of available RAM for the Docker tiers. The shipped root docker-compose.yml caps the platform container at 8 GiB, PostgreSQL at 1 GiB, Redis at 256 MiB and MinIO at 512 MiB. Agent runs are separate sibling containers, each bounded by the run limits (1536 MiB and 2 vCPU by default), so size the host for your expected concurrency. See Isolation and Security.

On Windows, run the installer inside WSL2.

How the pieces fit

  • Tiers decide which data services you run. Each missing service is replaced by an in-process fallback. See Progressive Infrastructure.
  • Execution backends decide where agent runs execute: docker (one isolated container pair per run), process (host subprocesses, no isolation, the code default) or firecracker (microVMs, opt-in). They are independent of the tiers.
  • Modules are optional features loaded at boot from the MODULES variable. The default set is oidc, webhooks, mcp, core-providers and @appstrate/module-chat. Others are opt-in. See Modules.

First run and auth modes

Appstrate ships in open mode by default: anyone who can reach the instance can sign up, and creating an organization is an explicit step in the onboarding flow (the creator becomes its owner).

For a private deployment, use closed mode: signup is disabled, organizations are created by invitation or by an operator, and the first owner claims the instance with a single-use bootstrap token.

  • If you enter an owner email at the interactive prompt, or set APPSTRATE_BOOTSTRAP_OWNER_EMAIL for a non-interactive install, the installer writes closed-mode settings and a fresh AUTH_BOOTSTRAP_TOKEN into .env.
  • An unattended install with --yes and no owner email is closed by default too on the Docker tiers (1 to 3). It generates a token, disables signup and prints a banner with the claim URL. Tier 0 stays in open mode unless you set APPSTRATE_BOOTSTRAP_OWNER_EMAIL.
  • Open <APP_URL>/claim, paste the token and choose the owner email and password. The root organization is created in the same step.
  • Remove AUTH_BOOTSTRAP_TOKEN from .env once the instance is claimed.

The token only works if the container receives it, and a Compose file forwards only the variables it lists. The Compose files shipped since 1.0.0-beta.65 list AUTH_BOOTSTRAP_TOKEN. A file that predates that release does not: add a bare - AUTH_BOOTSTRAP_TOKEN line under appstrate.environment and restart before you open /claim (see Compose forwards only what it lists).

Two rules about the named accounts:

  • When AUTH_BOOTSTRAP_OWNER_EMAIL is set, the claim accepts that address only. Any other address is refused with 403 bootstrap_owner_email_mismatch.
  • The token works only while the instance has no organization. Once one exists, /claim answers 410. An address named in AUTH_BOOTSTRAP_OWNER_EMAIL or AUTH_PLATFORM_ADMIN_EMAILS that has no account yet is not created by the sign-up form: it gets its account from a magic link (SMTP required) or from a Google or GitHub sign-in whose provider asserts the address as verified. The claim itself creates one account, the owner's.

The full matrix of flags, recipes, known limits and recovery procedures is in AUTH_MODES.md. The variables are listed in Environment Variables.

Guides

On this page