Installation
archmax automation ships as one image, ghcr.io/archmax-ai/automation. A container of it runs
the whole platform: nginx serves the web app on the public port and passes /api/ to the API,
and the dispatcher runs beside them. The image carries no deployment’s settings, so the same image
serves every deployment: you hand it an env file and a config
when it starts.
To work on the code instead, see the development setup; to try the product on your machine first, follow the quickstart.
What it needs
Section titled “What it needs”| Service | What for |
|---|---|
| MongoDB | Agents, environments, sessions, turns and every other record. |
| Redis | The dispatcher’s queues and the per-agent locks around git operations. Optional for one container: without REDIS_URL the container runs its own (see the image). |
| An S3-compatible store | The only durable store: repository bundles, every draft and version, every session’s files. The bucket must exist. |
| An identity provider | Sign-in: an OIDC provider the web app signs in at (Auth0, Cognito, Okta, Keycloak), or an AWS load balancer that signs people in (AWS). The image runs with NODE_ENV=production, which refuses to boot until ARCHMAX_SIGN_IN names a sign-in mode. |
| A model endpoint and key for the design agent | The config’s designAgent section, which production also requires. |
Local disk is only git scratch (/data/scratch) and the skill registry clones
(/data/skill-registries), both disposable, so the container needs no volume. nginx sends
Strict-Transport-Security, which tells browsers to use https only, so serve the container
behind TLS termination: a load balancer or a proxy with a certificate.
Pull the image
Section titled “Pull the image”Each release is pushed for linux/amd64 and linux/arm64 under three
tags. Every commit on main that passes CI, and every pull request from a branch of the
repository, gets an image of its own:
| Tag | Names |
|---|---|
X.Y.Z |
One release, such as 1.5.0. Pin this in production. |
X.Y |
The newest release of that minor line. |
latest |
The newest release. |
unstable |
The newest commit on main that passed CI. Not a release. |
unstable-<sha> |
One commit on main that passed CI, by its first seven characters. The newest ten are kept. |
pr-<number> |
A pull request (its merge commit), rebuilt on every push to it and deleted when it closes. |
The package is private until an owner makes it public, so sign in to the registry first with a GitHub token that can read packages:
echo "$GITHUB_TOKEN" | docker login ghcr.io -u USERNAME --password-stdindocker pull ghcr.io/archmax-ai/automation:1.5.0The examples on this page use 1.5.0; put the release you run in its place.
The env file
Section titled “The env file”Where the platform runs is set in environment variables; startup fails with a message naming the
variable when a required one is missing. A production env file looks like this (replace every
<…>; Docker’s --env-file reads a # only at the start of a line):
MONGODB_URI=mongodb://<mongo host>:27017/archmaxREDIS_URL=redis://<redis host>:6379
S3_BUCKET=<bucket>S3_REGION=<region># Leave both keys out to sign with the host's AWS credentials (a task or pod role)S3_ACCESS_KEY_ID=<access key id>S3_SECRET_ACCESS_KEY=<secret access key># For MinIO or another S3-compatible store, also:# S3_ENDPOINT=http://<minio host>:9000# S3_FORCE_PATH_STYLE=true
# OIDC sign-in: the issuer, the SPA application's client id, and (for Auth0) the API# identifier its access tokens are issued for. With Auth0, the issuer is# https://<your-auth0-domain>/ with the trailing slash.ARCHMAX_SIGN_IN=oidcARCHMAX_OIDC_ISSUER=<https://auth.example.com/>ARCHMAX_OIDC_CLIENT_ID=<client id>ARCHMAX_OIDC_AUDIENCE=<https://api.example.com>
# Seals every stored credential in the database store, the default: openssl rand -base64 32MASTER_KEY=<base64 key>
# The public origin: invitation links, and the callback addresses the dispatcher registersAPP_BASE_URL=https://<app.example.com>OAUTH2_REDIRECT_URL=https://<app.example.com>/api/oauth2/callback
# Referenced by the config as a placeholderARCHMAX_DESIGN_AGENT_API_KEY=<key>
# An organization's email domain needs a DNS TXT record before it can onboard new users# (on by default). A single-tenant deployment whose Organization Owners are all trusted, or that cannot# reach public DNS, can verify domains without it:# ARCHMAX_DNS_VERIFICATION=offARCHMAX_SIGN_IN=oidc requires ARCHMAX_OIDC_ISSUER and ARCHMAX_OIDC_CLIENT_ID, and
MASTER_KEY is required in production, unless the deployment keeps its credentials’ secrets in
AWS Secrets Manager instead (ARCHMAX_SECRET_STORE=aws-secrets-manager, with no MASTER_KEY; see
where credentials are kept). Behind an AWS load balancer that signs people in, set
ARCHMAX_SIGN_IN=aws-alb with ARCHMAX_AWS_ALB_ARN and ARCHMAX_AWS_ALB_SIGN_OUT_URL instead of
the OIDC group (see AWS): a variable of the mode not named refuses the boot. Without APP_BASE_URL the platform falls back to the
first CORS_ALLOWED_ORIGINS entry, which defaults to http://localhost:5173.
Every variable, with its default, is on the environment variables page.
The config
Section titled “The config”What the platform offers (the design agent, the services, the Activepieces collections, the
skill registries and the OAuth apps) is one document, the config. Start from
config.yaml.example in the repository; in production it needs at least the design agent:
designAgent: apiBaseUrl: https://api.openai.com/v1 apiKey: "${{ARCHMAX_DESIGN_AGENT_API_KEY}}" model: gpt-6.1-sol prices: input: 2.00 output: 10.00The config holds no secret: each is a ${{VAR}} placeholder resolved from the environment at
boot. Hand it to the container in one of two ways:
- Mounted at
/app/config.yaml(-v "$PWD/config.yaml:/app/config.yaml:ro"), or anywhere else withARCHMAX_CONFIG_FILEnaming the path. - As one variable,
ARCHMAX_CONFIG, for a host with nothing to mount.pnpm config:envprintsconfig.yamlas the one line of JSON it holds, andpnpm config:env --base64the base64 form, for a host such as Railway that reads${{NAME}}inside a variable’s value itself.
ARCHMAX_CONFIG wins when both are present, with one warning naming the ignored file. The
config reference lists every section, among them
branding, which gives the deployment its own title, logo and
colours.
First boot
Section titled “First boot”docker run -d --name archmax -p 8080:8080 --cap-drop ALL \ --env-file archmax.env \ -v "$PWD/config.yaml:/app/config.yaml:ro" \ ghcr.io/archmax-ai/automation:1.5.0docker logs -f archmaxThe container needs nothing --cap-drop ALL removes, and with it no process the container
starts can read another’s environment, the variables you pass included (see
the image).
The entrypoint says what it started:
[entrypoint] nginx :8080 -> api 127.0.0.1:3001 (+ dispatcher), access log: errorsThe API’s lines follow tagged [api], the dispatcher’s [dispatcher]. A missing or invalid
variable, or an invalid config, stops that process with a message naming the variable or the
config path. The entrypoint restarts it every two seconds, so the container stays up while
that process cannot start: fix the setting and restart the container. A config entry whose
placeholder names an unset variable is left out instead, with a [config] line naming the
entry and the variable.
Before the API listens and the dispatcher takes a job, each brings the database up to date. On a
fresh database that means creating every collection’s schemaVersion index and nothing else:
there is no stored document for a data update to rewrite, and the boot logs nothing about it.
A later release that changes what a collection stores rewrites the stored documents the same
way when it first starts (see data updates at boot).
When the API is up, GET /api/health answers with the release it runs:
curl -s http://localhost:8080/api/health# {"status":"ok","version":"1.5.0"}The image’s own health check probes the same route on the internal API port every 30 seconds. Open the public origin in a browser to sign in: the web app reads its sign-in settings from the API, and in OIDC sign-in the identity provider’s SPA application has to list that origin (see sign-in).
Build the image from source
Section titled “Build the image from source”Building needs only Docker, from the repository root:
docker build -t archmax .docker build --build-arg APP_VERSION=1.5.0 -t archmax:1.5.0 .Without APP_VERSION the image reports dev. It runs the same way as the published image,
and the image reference describes what it contains. To keep it running, see
operating a deployment.