Environment Variables
The .env reference for a running Astervis install.
Every setting for a running Astervis install lives in a single file: /opt/astervis/.env.
The installer generates it for you during setup — random passwords and secrets included —
so on a fresh install you usually never touch it. This page is for the times you do: when
you need to understand what a value means, point Astervis at a different MariaDB, or rotate
a secret.
The file is owned by root and written with mode 0600 (only root can read it). It's read
by Docker Compose, which injects the values into the containers, so changes only take
effect after you restart the stack.
Astervis is on-premise only. Everything in this file — database, Redis, the PBX
connection, recordings — stays on your server. The one variable that points off-server
is AI_GATEWAY_URL, and only if you've enabled the optional AI features. See
AI & Privacy.
Editing and applying changes
Edit the file as root
sudo nano /opt/astervis/.envRestart the stack to apply
cd /opt/astervis
docker compose up -dCompose recreates only the containers whose environment actually changed. For a full
bounce, use docker compose down && docker compose up -d, or the installer's wrapper:
sudo astervis-installer restart.
Some values are baked in on first run and cannot be changed by editing .env alone.
The most important is POSTGRES_PASSWORD: PostgreSQL only applies it when the data
directory is first initialised, so editing it later won't change the role's real
password and migrate will fail to authenticate. If you must rotate the DB password,
reset the role inside the database too — don't just edit the file.
PostgreSQL / TimescaleDB
The primary data store. A single TimescaleDB-HA image (PostgreSQL 16 with the TimescaleDB
and pgvector extensions) holds your CDR analytics, AI transcripts, and vector embeddings.
It binds to 127.0.0.1:5432 on the host and is never exposed externally.
| Variable | Default | Description |
|---|---|---|
POSTGRES_USER | astervis | Database role used by the backend and queue. |
POSTGRES_PASSWORD | generated (24 chars) | Role password. Set on first init only — see the warning above. |
POSTGRES_HOST | timescaledb | Compose service name. Containers resolve it on the internal network. |
POSTGRES_PORT | 5432 | PostgreSQL port (host-published on 127.0.0.1). |
POSTGRES_DB | astervis | Database name. |
Redis
Used for Better Auth session caching and the BullMQ job queue that drives the AI pipeline.
Binds to 127.0.0.1:6380 on the host (mapped from the container's 6379).
| Variable | Default | Description |
|---|---|---|
REDIS_HOST | redis | Compose service name. |
REDIS_PORT | 6379 | In-container Redis port. |
Backend and frontend ports
These are in-container ports. Only nginx is reachable from outside the host — on port 8443 — so changing these values won't expose anything new; they coordinate the reverse proxy with the apps behind it.
| Variable | Default | Description |
|---|---|---|
BACKEND_PORT | 5555 | Elysia.js backend API port (container astervis-app). |
PORT | 6464 | Next.js admin UI port (container astervis-nextjs). |
HOST_URL | your domain or IP | Public base URL Astervis advertises to clients. |
BACKEND_TRPC_API_URL | http://app:5555 | Internal URL the admin uses to reach the backend. |
The product UI is always served at https://<your-domain-or-IP>:8443. That 8443 is the
only port the installer opens to the network — every other service binds to loopback.
Authentication (Better Auth)
Astervis uses Better Auth with Redis-cached sessions and JWTs
for API calls. The secret is generated for you; the URL must match the address users
actually visit, including the :8443 port.
| Variable | Default | Description |
|---|---|---|
BETTER_AUTH_SECRET | generated (32 chars) | Signs and encrypts sessions. Rotating it logs everyone out. |
BETTER_AUTH_URL | https://<domain-or-IP>:8443 | Public auth base URL. Must match the address in the browser. |
NEXT_PUBLIC_TIMEZONE | Asia/Tashkent | Timezone the admin UI renders timestamps in. The DB always stores UTC. |
MySQL / PBX
How Astervis reaches your PBX's MariaDB to read Call Detail Records and operator data. The installer auto-detects these from FreePBX where it can.
| Variable | Default | Description |
|---|---|---|
MYSQL_HOST | host.docker.internal | See the rewrite note below. |
MYSQL_PORT | 3306 | MariaDB port. |
MYSQL_USER | auto-detected | CDR DB user (e.g. freepbxuser). Also used by the CDC service. |
MYSQL_PASSWORD | auto-detected | Password for the above. |
MYSQL_DB | asteriskcdrdb | CDR database. |
MYSQL_USERS_DB | asterisk | Asterisk config DB (operators, queues). |
MYSQL_TIMEZONE | server timezone | How the PBX stores calldate, so Astervis can normalise it. |
MYSQL_HOST is rewritten on purpose. Your MariaDB usually listens on the host, not
inside a container — so a value like localhost or 127.0.0.1 would point a container
at its own loopback, where nothing is listening. The installer rewrites any loopback
value (localhost, 127.0.0.1, ::1, 0.0.0.0) to host.docker.internal so
containers reach the host's MariaDB. A real LAN or remote IP is left untouched. If you
move the database, set this to the new reachable address — not localhost.
ARI (Asterisk REST Interface)
The backend connects to Asterisk's REST interface for live call control — for example, the
blacklist fallback that hangs up a blocked caller on ChannelCreated.
| Variable | Default | Description |
|---|---|---|
ARI_HOST | host.docker.internal | Reaches Asterisk's HTTP server on the host. |
ARI_PORT | 8088 | Asterisk ARI/HTTP port. |
ARI_LOGIN | configured at install | ARI username. |
ARI_PASSWORD | configured at install | ARI password. |
ARI_TC_DEVICE | auto-detected | FreePBX Time Condition device used to detect after-hours calls. |
AMI (blacklist sync)
The phone blacklist keeps Asterisk's astdb in sync over the
Asterisk Manager Interface, so blocked numbers are rejected at the PBX itself.
| Variable | Default | Description |
|---|---|---|
AMI_HOST | host.docker.internal | Reaches the AMI listener on the host. |
AMI_PORT | 5038 | Asterisk Manager Interface port. |
AMI_LOGIN | configured at install | AMI username. |
AMI_PASSWORD | configured at install | AMI password. |
Recording access
Call recordings are mounted read-only from the PBX into the backend and queue containers. The signing secret protects recording download URLs so they can't be guessed or shared without authorisation.
| Variable | Default | Description |
|---|---|---|
RECORDING_SIGN_SECRET | generated (32 chars) | HMAC secret that signs time-limited recording URLs. |
The recordings themselves aren't an env var — they're a bind mount. The installer mounts the host's monitor directory into the containers:
volumes:
- /var/spool/asterisk/monitor:/recordsInside the containers, recordings appear under /records. If your PBX stores recordings
elsewhere, adjust the host side of that mount in docker-compose.yml.
AI
Optional. These point the stack at the central AI Gateway, which runs transcription and QA analysis on Google Gemini (Vertex AI). If your license doesn't include AI, these are harmless and unused.
| Variable | Default | Description |
|---|---|---|
AI_GATEWAY_URL | https://ai-gateway.astervis.io | Where the backend verifies the AI license and submits audio for analysis. |
BACKEND_URL | your backend URL | Where the gateway posts webhook callbacks with finished results. |
AI_GATEWAY_URL is the only outbound endpoint in this file. When AI is on, the audio of
a finished call is sent there for analysis — nothing else leaves the server. See
AI & Privacy for the full picture.
Astervis Agent
The installer also runs as a small REST API agent (astervis-agent) on the host, port
9876. The product uses it to check for updates, validate the license, and renew certs.
Because the agent lives on the host, the backend reaches it via host.docker.internal.
| Variable | Default | Description |
|---|---|---|
ASTERVIS_AGENT_API_KEY | generated (32 chars) | Sent as X-API-Key to authenticate to the agent. |
ASTERVIS_AGENT_API_URL | http://host.docker.internal:9876 | Where the backend reaches the agent. |
CDC / replication (litcdc)
Astervis replicates every CDR out of the PBX's MariaDB binlog using litcdc, a tiny Rust
service that takes a one-time snapshot of the cdr table and then streams changes in
realtime to TimescaleDB. (litcdc replaced the old Debezium + Redpanda pipeline; it's a
single ~10–25 MiB process.) Most of its tuning lives in docker-compose.yml, but one knob
surfaces in .env:
| Variable | Default | Description |
|---|---|---|
REPLICATION_THROTTLE_MS | 0 | Delay between replication batches, in milliseconds. 0 = drain at full speed. |
Keep REPLICATION_THROTTLE_MS=0 unless you have a specific reason to slow replication.
Zero throttle drains the litcdc buffer fast — roughly 150 events/sec, clearing a 64k-row
historical backfill in about 8 minutes — and keeps the durable buffer shallow.
Runtime and paths
| Variable | Default | Description |
|---|---|---|
DATA_DIR | /opt/astervis | Base directory for host-mounted data (DB, Redis, litcdc buffer, uploads, SSL). |
NODE_ENV | production | Node runtime mode. Leave as production. |
NODE_OPTIONS | --max-old-space-size=3072 | Node.js heap cap (MB). Raise only on a memory-rich host running into OOM. |
A minimal example
A trimmed .env showing the shape of the file. The real one the installer writes has more
entries and real generated secrets — this uses placeholders, never copy these values.
# PostgreSQL / TimescaleDB
POSTGRES_USER=astervis
POSTGRES_PASSWORD=replace-with-generated-secret
POSTGRES_HOST=timescaledb
POSTGRES_PORT=5432
POSTGRES_DB=astervis
# Redis
REDIS_HOST=redis
REDIS_PORT=6379
# Backend / frontend
BACKEND_PORT=5555
PORT=6464
HOST_URL=https://pbx.example.com:8443
BACKEND_TRPC_API_URL=http://app:5555
# Auth (Better Auth)
BETTER_AUTH_SECRET=replace-with-generated-secret
BETTER_AUTH_URL=https://pbx.example.com:8443
NEXT_PUBLIC_TIMEZONE=Asia/Tashkent
# MySQL / PBX (host rewritten to host.docker.internal)
MYSQL_HOST=host.docker.internal
MYSQL_PORT=3306
MYSQL_USER=freepbxuser
MYSQL_PASSWORD=replace-with-pbx-db-password
MYSQL_DB=asteriskcdrdb
MYSQL_USERS_DB=asterisk
MYSQL_TIMEZONE=Asia/Tashkent
# ARI
ARI_HOST=host.docker.internal
ARI_PORT=8088
ARI_LOGIN=astervis
ARI_PASSWORD=replace-with-ari-password
# AMI (blacklist)
AMI_HOST=host.docker.internal
AMI_PORT=5038
AMI_LOGIN=astervis
AMI_PASSWORD=replace-with-ami-password
# Recording
RECORDING_SIGN_SECRET=replace-with-generated-secret
# AI (optional)
AI_GATEWAY_URL=https://ai-gateway.astervis.io
BACKEND_URL=https://pbx.example.com:8443
# Agent
ASTERVIS_AGENT_API_KEY=replace-with-generated-secret
ASTERVIS_AGENT_API_URL=http://host.docker.internal:9876
# CDC / replication
REPLICATION_THROTTLE_MS=0
# Runtime
DATA_DIR=/opt/astervis
NODE_ENV=production
NODE_OPTIONS=--max-old-space-size=3072Never commit, paste, or share /opt/astervis/.env. It contains your database
password, the Better Auth secret, your PBX MariaDB credentials, ARI/AMI passwords, the
recording-signing secret, and the agent API key. Anyone with this file can read your call
data and impersonate the stack. Keep it on the server, mode 0600, root-only. If a secret
is exposed, rotate it and restart the affected services.
Related
Last updated on