AcahtiDocs
EN中文GitHubSelf-host

DocsGet started

Install

Self-host an Acahti instance with one command, or have your coding agent run it over SSH.

On a Linux host, as a sudoer:

curl -fsSL https://acahti.benchyard.com/install.sh | bash -s -- --domain acahti.example.com

The script installs Docker if it is missing, pulls the release image from ghcr.io/acahti-ai/acahti, copies its compose file and host scripts into ~/acahti, generates secrets into ~/acahti/.env, and starts the instance. Nothing is built on the host.

Or let your coding agent do it:

Install https://acahti.benchyard.com/install.md
Self-host Acahti on my infrastructure. Ask me for the domain, SSH access, and Runner host.

Have ready#

  • A Linux host with sudo and at least 2 GiB RAM.
  • A public HTTPS hostname. You terminate TLS at your own reverse proxy or tunnel and forward it to the gateway.
  • Optionally, a second host for the Runner, reachable over SSH from the first. CI never runs on the control plane.

Options#

Option .env Meaning
--domain HOST DOMAIN, ROOT_URL Public hostname; required on first install
--org NAME ACAHTI_ORG Organization repositories live under (default acme)
--runner SSH ACAHTI_BUILD Runner host, set up over SSH, such as ci@10.0.0.5
--bind ADDR GATEWAY_BIND Gateway listen address (default 127.0.0.1:8080; 0.0.0.0:8080 when a Runner is set)
--version X.Y.Z ACAHTI_VERSION Release to install (default: the latest)
--dir PATH Install directory (default ~/acahti)

Options are written to .env and kept for later runs. Data lives under ACAHTI_DATA (default /var/lib/acahti).

After install#

  1. Point your proxy or tunnel at the gateway and open the instance URL.
  2. Invite members from the web app. Each person joins at <instance>/join.
  3. Paste the agent prompt from the instance home page into a coding agent, open the Board, and watch it run the demo loop.

Upgrade#

Back up PostgreSQL and ACAHTI_DATA, then run the installer again:

curl -fsSL https://acahti.benchyard.com/install.sh | bash

It installs the latest release, keeps .env and data, and resyncs the Runner. --version pins a release. An instance older than 0.15.0 upgrades to 0.15.2 first, then to the latest release. Never docker compose down -v on a live instance.

Release delivery#

The gateway, MinIO, Caddy edge, Gotenberg, Tika and ONLYOFFICE Docs are separate images. MinIO uses ghcr.io/acahti-ai/acahti:minio-<MINIO_IMAGE_VERSION>, edge uses caddy:<CADDY_VERSION>-alpine, Gotenberg uses gotenberg/gotenberg:<GOTENBERG_VERSION> for Office previews, Tika uses apache/tika:<TIKA_VERSION> to extract searchable text from PDF and Office files, and onlyoffice/documentserver:<ONLYOFFICE_VERSION> edits knowledge files in the browser. Those versions are pinned in versions.env; application releases reuse them. For an offline install, load all six image archives before running the installer. ONLYOFFICE needs up to 3 GiB of memory and a minute or two after start before documents open in the editor; until then they show their PDF preview. A proxy in front of the edge must accept request bodies of at least 200 MiB for uploads. The installer reuses cached images and pulls only on a cache miss.

Upgrades reconcile changed services and wait for health. Runtime configuration and remote Runner bundles are synchronized only when their inputs change; a gateway release alone does not reinitialize them.

Private registry access#

For a private mirror, authenticate Docker with an account that can read the registry before running the installer (docker login <registry>). Use a read-only package credential or a registry credential helper; do not place credentials in the installation's .env, Git repository, command examples or shared archives.

Gateway updates#

The stable edge service owns the published HTTP port. During an update the single gateway first returns 503 from its readiness probes, while continuing to serve requests already dispatched by edge. After two seconds it closes event streams and drains ordinary requests for up to 25 seconds. Compose allows 30 seconds before killing the container. The replacement starts only after the old process exits, so file-backed credentials and background jobs never have two writers.

Caddy checks readiness every 250 milliseconds. Requests arriving during the replacement wait for an upstream for up to 120 seconds. Only GET and HEAD may be retried after a failed upstream round trip. A write can wait after a dial failure without sending its body; writes already sent upstream are never replayed. SSE clients reconnect after the old stream closes. This does not provide durable replay of events emitted while a client is disconnected.

This is a bounded waiting strategy: normal updates avoid gateway errors but add latency. Clients must allow enough time for the handoff. Requests exceeding the drain deadline, clients with shorter timeouts, failed startup, and outages beyond the edge retry budget can still fail. It is not multi-replica high availability. Changes to edge or to stateful dependencies also need a maintenance window; the request-waiting guarantee covers gateway-only updates.

The installer pins the gateway to its downloaded digest (or local image ID for an offline archive), preserves a protected .previous-release.* host bundle, and restores that bundle on failure. scripts/upgrade.sh downloads images before replacement and restores the previous gateway image and environment if readiness fails. A failed upgrade still exits unsuccessfully, including after a successful rollback. Database migrations must be reviewed separately: image rollback does not undo database changes. Back up the database and persistent data before an upgrade that changes them.

CADDY_VERSION pins the official public caddy:<version>-alpine edge image. A normal installation downloads it automatically. Operators using an internal registry can mirror that version and set CADDY_IMAGE to its repository name; this is an installation setting, not a product fork. Offline installs must load all six image archives. Leave the edge image and configuration unchanged during gateway-only updates.

For agents: install.mdEdit this page