opschain server start
Included from Basic tier
Start the OpsChain server in the foreground: HTTP(S) API, data store, scheduler, runner protocol and log streaming, as one process. The command prints the listen URL once the socket is open —
opschain server start
opschain server listening on http://127.0.0.1:8443
— then serves until SIGTERM or SIGINT. The first signal begins a graceful shutdown (drain runners and parked polls, stop the scheduler, close the store) with a 30-second grace period; a second signal abandons the grace period and stops hard.
Configuration layering
Configuration resolves lowest-to-highest:
$OPSCHAIN_HOME/server/config.yamlandserver/keys.env— written byopschain server configure. Print the annotated key catalog withopschain server configureand its template flag (seeopschain docs cli/server-configure) rather than guessing key names; the running server also serves the same catalog atGET /api/admin/config.- Environment variables — the
keys.envnames (OPSCHAIN_TOKEN_SECRET_KEY,OPSCHAIN_PRIMARY_KEY,OPSCHAIN_KEY_DERIVATION_SALT),OPSCHAIN_LDAP_PASSWORD,OPSCHAIN_SERVER_ADMIN_TOKEN,OPSCHAIN_ENABLE_BASIC_AUTH,OPSCHAIN_CLUSTER_NAME, theOPSCHAIN_LDAP_*overlay and anyOPSCHAIN_VAULT_*values. - Flags — a flag explicitly passed on this invocation wins over the file value even when the flag's value equals its default.
On PostgreSQL the token secret is a start requirement: when neither
OPSCHAIN_TOKEN_SECRET_KEY (environment or keys.env) nor the stored
token.secret_key supplies one, server start refuses by name —
token secret: a PostgreSQL server needs one — set OPSCHAIN_TOKEN_SECRET_KEY … or store token.secret_key — rather than serve every caller as the
superuser. opschain server configure writes the key, so a configured
home never hits this; a settings read that fails at boot refuses the same
way instead of opening. Only a test lane declares the open posture, with
server.unauthenticated_postgres: true in config.yaml, and the hardened
posture refuses that declaration. The SQLite store is unchanged: it has no
auth stack either way.
Flags
| Flag | Meaning |
|---|---|
--listen <host:port> | Listen (bind) address; port 0 picks a free one. Default 127.0.0.1:8443 — loopback — on every store (the config file's listen when set). On the embedded SQLite store a non-loopback address is honoured and called out in the startup notice, because that server has no sign-in. |
--store <path or DSN> | The data store: a SQLite database path, or a postgres:// DSN. Parameters left out of the DSN fall back to the standard PG* environment variables. Default: <opschain home>/opschain.db — the development harness below; the full server needs postgres://. |
--tls-cert <file> | TLS certificate file. Set both TLS flags to serve HTTPS; without them the server speaks plain HTTP (loopback/dev). |
--tls-key <file> | TLS private key file. |
--admin-token <token> | Static admin bearer token admitted to the admin service on a store WITHOUT the auth stack, where it is the sole guard (default off). On PostgreSQL with a resolvable token secret the lane is retired: the token is refused with the typed ERROR_REASON_ADMIN_TOKEN_RETIRED answer, a boot notice says so, and admin surfaces authenticate user sessions and API keys through the /admin RBAC gate. Falls back to OPSCHAIN_SERVER_ADMIN_TOKEN when the flag is empty. |
--confirm-eula | Accept the LimePoint EULA on a fresh installation's first start (read it with opschain eula). Recorded once, then inert. |
--dev-run-seam | Mount the admin-gated run-creation seam under /admin/e2e/runs (interim, superseded by the v1 API). |
--lease-ttl <d> | Job lease TTL before a silent runner's step fails as runner_lost (default 3m). |
--poll-window <d> | Long-poll park window for runner job acquisition (default 50s). |
--replica-retention <d> | How long a dead scheduler replica's membership row stays visible before the leader reaps it (default 24h). |
Global flags that matter here: --home picks the server home the
configuration is read from; --log-file <path> writes JSON log lines to a
rotated file instead of stderr. When the config file's logging: block
names a file, file logging engages without the flag; the flag overrides the
path while the rotation settings (size, age, backup count) always come
from the logging: block.
The embedded SQLite store: a development harness
Started with no store configured, the server runs on the embedded
SQLite file and is a development harness — the run engine behind the
run/step/log API, the runner and agent fleet, licensing and the local
secret store — for tests, runner-fleet play and GUI development against
its API. It has no sign-in, so the binary labels it: it binds to loopback
unless --listen says otherwise, it does not serve the GUI (the root URL
answers a plain page saying the GUI needs a server on PostgreSQL), and
once the socket is open it prints this notice on the notice stream
(stderr, or the log file):
opschain server: development harness on the embedded SQLite store (no `store` configured)
opschain server: serves: the run engine behind the run/step/log API, the runner and agent fleet, licensing, the local secret store
opschain server: does not serve: users and sign-in, the estate, templates, the workflow catalog, notifications, governance, providers, the web GUI (the root URL answers a page saying so)
opschain server: bound to http://127.0.0.1:8443 (loopback — the default on this store; pass --listen host:port or set listen: in config.yaml to bind elsewhere)
opschain server: to evaluate the full server — PostgreSQL, the server and the web GUI in one command — run the go-opschain Docker Compose (`./configure`, then `docker compose up`); `opschain docs storage` has the route and the DSN it exposes
With an explicit non-loopback --listen the fourth line reads bound to http://0.0.0.0:8443 — NOT loopback: this harness has no sign-in, so anything that can reach the address can use it. The notice never
carries a secret. A server on PostgreSQL prints no such notice and binds
exactly as configured. opschain docs storage ("The SQLite server is a
labelled development harness" and "Evaluating the full server") has the
whole contract.
The EULA gate
A fresh installation refuses to start until the LimePoint EULA is accepted:
interactively (on a terminal the agreement is printed and the word accept
is required), with --confirm-eula, or with the config file's eula:
accepted: true. Acceptance is recorded once per installation and a later
EULA revision never re-gates.
Exit codes
| Code | Meaning |
|---|---|
| 0 | Clean shutdown after a signal. |
| 1 | The server failed to configure, listen or serve (the error is printed). |
| 2 | Usage error — unknown flag or stray argument. |
See also
opschain docs cli/server-configure— write the configuration this command reads.opschain docs cli/server-backupandopschain docs cli/server-restore— embedded-deployment backups.opschain docs cli/eula— read the agreement the first start requires.opschain docs storage— the stores, the harness contract and the one-command evaluation route.opschain learn 0.1— install and first contact.