---
title: "Environment Variables"
url: "https://control.actana.ai/docs/reference/environment-variables"
description: "Every variable for the Panel, Compose, the container Core, and the metal Core layout."
updated: 2026-09-01T09:03:19+00:00
---

Everything is environment variables. There is no config file. Pin images with `ACTANA_TAG` — one tag, `x.y.z` (the current release; `npm view @actana/cli version` prints it), because Panel and Core are version-locked.

## Panel

| Env | Default | Meaning |
| --- | --- | --- |
| `AC_PANEL_PORT` / `PORT` | `7420` | Listen port |
| `AC_PANEL_HOST` / `HOST` | `0.0.0.0` | Bind address. `127.0.0.1` keeps a shared host on loopback |
| `AC_PANEL_DATA_DIR` | `/data` in the image; platform data dir otherwise | The one directory all Panel state lives in |
| `AC_SECRETS_KEY` | generated at `<data dir>/secrets.key` | 32-byte key (hex or base64) sealing stored Core credentials |
| `ACTANA_UPDATE_CHECK` | on | `0`, `false`, or `off` stops the daily release check |

Generate a secrets key with `openssl rand -hex 32`. Set `AC_SECRETS_KEY` to keep it **out of** the data volume, so a copied volume or backup alone cannot open fleet credentials. Losing whichever key is in use means re-pairing every Core. The update check reads GitHub `releases/latest`, caches 24h, and only ever shows a banner.

## Compose

Copy `deploy/.env.example` to `.env` beside `docker-compose.yml`. All values optional. `ACTANA_TAG` (default `latest`) is the image tag **both** services pull — one variable, because Panel and Core are version-locked. `ACTANA_IMAGE_NAMESPACE` defaults to `actana`. `AC_SECRETS_KEY` and `ACTANA_UPDATE_CHECK` are the same as the Panel table, applied to both services.

`ACTANA_PUBLIC_HOST` is **not** in `.env`. It lives in `docker-compose.yml` beside the Core service it names — a second Core needs a second value.

## Core in a container

Only `ACTANA_PUBLIC_HOST` is required. The image never guesses it: a container hostname is its ID, and a guessed SAN would change the certificate on every recreation.

| Variable | Default | What it does |
| --- | --- | --- |
| `ACTANA_PUBLIC_HOST` | — **required** | Comma-separated list of dial addresses; every entry becomes a SAN on the server cert; a pairing hands back one of them as the endpoint |
| `ACTANA_PORT` | `8443` | Core-link port, and the port the image exposes |
| `ACTANA_LABEL` | first public host | Name the Panel shows for this Core |
| `ACTANA_UPDATE_CHECK` | on | Same daily check; `actana status` and `docker compose logs core` |

Since 0.4.2 the value is a **comma-separated list** — `localhost,host.docker.internal,core,192.168.1.50` — and the certificate carries every name in it. Typical entries:

- the compose **service name** (`core`) — what the Panel dials over the network
- `localhost` — a CLI on the same machine, dialling the **published** port
- `host.docker.internal` — a CLI inside **another container** (Docker Desktop resolves it to the host; it does not resolve on the host itself)
- a **LAN IP** — reserved as static in the router, for machines elsewhere on the network

`actana pair new --public-host <addr>` chooses which entry a code's redemption hands back; it selects from the list and can never extend it. Changing the list re-signs the certificate, but clients dialling a name that stays in the list keep working. On Cores older than 0.4.2 the value is one address, and every change re-signs it for the new name **only** — every paired client, Panel included, re-pairs. Rename the service and update the matching entry to keep them agreeing.

## Core on metal

`ACTANA_HOME`, `ACTANA_BIN_DIR`, `ACTANA_CONFIG_DIR`, `ACTANA_DATA_DIR`, plus `XDG_DATA_HOME` / `XDG_CONFIG_HOME` (macOS included, if set), move where things land. `install.sh` does not read them — the CLI does. Public host is `actana setup --public-host`, stored in `actana.json`.

| Path | Contents |
| --- | --- |
| `~/.local/share/actana/versions/<version>/` | Bundle (`bin/actana`, `app/`, `node/`). `current` points at it |
| `~/.local/share/actana/data/missioncontrol.db` | SQLite: projects, tasks, sessions, event log |
| `~/.config/actana/material.json` | CA, certs, bearer, coreId. `chmod 0600` |
| `~/.config/actana/actana.json` | Version, port, host, public host, label. No secrets |
| `~/.local/bin/actana` | Symlink to `current/bin/actana` |

Linux unit: `~/.config/systemd/user/actana-core.service`. macOS: `~/Library/LaunchAgents/com.actana.core.plist` and `~/Library/Logs/Actana/core.log`. Those two service paths are fixed; everything else honours XDG.

## See also

- [Reference](/docs/reference)
- [Install](/docs/install)
- [Observability](/docs/reference/observability)
