Quickstart

Get SpeakNode running in a few minutes

SpeakNode ships as a bundle — a docker-compose.yml and a reference .env.example — served directly from this docs site. Images live in our private container registry at registry.nodul.ru — pull access is granted via a read-only token (see below).

1. Download the quickstart bundle

mkdir SpeakNode && cd SpeakNode
curl -O https://docs.dev.voxagent.ru/cdn/docker-compose.yml
curl -O https://docs.dev.voxagent.ru/cdn/.env.example
  • docker-compose.yml — full service stack (includes a one-shot postgres-init service that creates the extra databases/users after Postgres is healthy)
  • .env.example — reference environment variables

2. Request a registry token

Container images at registry.nodul.ru/voxagent/nodevoice/* require a read-only token. Tokens are issued per customer on request — email us at help@mail.voxagent.app and we'll send you one.

Once you have it, log in on the host — docker will prompt for username and password:

docker login registry.nodul.ru/voxagent/nodevoice

3. Configure

cp .env.example .env

The baseline .env.example already contains everything needed to bring the stack up locally — you can leave it as-is and start. Provider keys (LLM / STT / TTS), Keycloak SMTP, billing, telephony and other integrations are optional and only needed for the corresponding functionality.

Full variable reference is in Configuration.

4. Start the stack

Apple Silicon / ARM64. Our images are built for linux/amd64. To make docker pull/run that platform explicitly (on M1/M2/M3 via Rosetta), every command below is prefixed with DOCKER_DEFAULT_PLATFORM=linux/amd64. On Intel machines the prefix is a harmless no-op — feel free to leave it in.

Pull the latest images first so you're not running a stale :latest cached from a previous docker login:

DOCKER_DEFAULT_PLATFORM=linux/amd64 docker compose pull

4a. Local laptop (default)

The stack works out-of-the-box at http://localhost:4200 — no extra configuration needed:

DOCKER_DEFAULT_PLATFORM=linux/amd64 docker compose up -d

4b. Remote VM / server

If you run compose on a VM (cloud, LAN server) and access it from a different device, the browser will hit localhost of the laptop, not the VM. Regenerate .env so that public URLs point to the VM's address:

# get the VM's IP (run ON the VM):
curl -4 https://ifconfig.me           # cloud VM with public IP
hostname -I | awk '{print $1}'        # LAN server (Linux)

# generate .env with that host:
DOCKER_DEFAULT_PLATFORM=linux/amd64 PUBLIC_HOST=10.0.0.5 \
    docker compose run --rm env-gen

# now start normally:
DOCKER_DEFAULT_PLATFORM=linux/amd64 docker compose up -d

env-gen is a one-shot helper container. It does not start with docker compose up (sits behind the tools profile) — you invoke it explicitly.

4c. VM with HTTPS + real domain

To serve the stack via https://demo-app.dev.example.io, https://demo-api.dev.example.io, etc. with automatic TLS (Caddy local CA or Let's Encrypt) — set up DNS records (see below) and generate .env in TLS mode.

DNS — what points where

All subdomains point to the same IP — your VM's IP. Caddy inside the stack routes by subdomain. Two ways to configure DNS:

Option A — wildcard (recommended)

TypeNameValue
A*.dev.example.io<your VM IP>
Adev.example.io<your VM IP> (optional)

Option B — explicit A-records per subdomain

TypeNameService
Ademo-app.dev.example.ioAngular Client (app frontend)
Ademo-widget.dev.example.ioAngular Widget (embed widget)
Ademo-api.dev.example.ioASP.NET Backend (REST API)
Ademo-identity.dev.example.ioKeycloak (login / OAuth)
Ademo-livekit.dev.example.ioLiveKit (WebRTC + WebSocket)
Ademo-docs.dev.example.ioDocs
Ademo-s3.dev.example.ioMinIO S3 API
Ademo-s3-console.dev.example.ioMinIO Web Console
Ademo-lago.dev.example.ioLago Billing UI
Ademo-lago-api.dev.example.ioLago Billing API
Ademo-webhooks.dev.example.ioWebhook Receiver
Ademo-kafka-ui.dev.example.ioKafka UI (optional, devops)

Wait for DNS to propagate (typically 5-30 minutes, check: dig +short demo-app.dev.example.io).

Start the stack

DOCKER_DEFAULT_PLATFORM=linux/amd64 PUBLIC_HOST=dev.example.io PUBLIC_MODE=tls \
    docker compose run --rm env-gen

# start stack + caddy edge (tls profile):
DOCKER_DEFAULT_PLATFORM=linux/amd64 COMPOSE_PROFILES=tls docker compose up -d

# one time — trust caddy's local CA:
docker compose exec caddy caddy trust

Access: https://demo-app.dev.example.io, https://demo-identity.dev.example.io, https://demo-api.dev.example.io, etc.

TLS certificates. By default Caddy uses a local CA — certs are trusted only on the machine where you ran caddy trust. For publicly trusted Let's Encrypt: comment out local_certs in caddy/Caddyfile, set a real CADDY_LE_EMAIL=... in .env, and make sure ports 80/443 on your VM are reachable from the internet.


First boot takes a few minutes — Postgres initialises, Keycloak imports the realm, Lago runs migrations and seeds the billing organisation.

5. Wait for angular-client to become healthy

Check service status:

docker compose ps -a --format "table {{.Service}}\t{{.Status}}\t{{.Ports}}"

As soon as the angular-client row shows Up ... (healthy), the app is ready — open it at http://localhost:4200.

6. Create a user

On the sign-in screen hit Sign up and create an account.

The docker compose bundle ships with email verification disabled (KEYCLOAK_VERIFY_EMAIL=false), so registration is instant.

Enable email verification

To require users to confirm their email before first login, edit .env:

  1. Turn the flag on:
    KEYCLOAK_VERIFY_EMAIL=true
  2. Fill in Keycloak SMTP credentials (used for verification + password-reset emails):
    KEYCLOAK_SMTP_HOST=smtp.example.com
    KEYCLOAK_SMTP_PORT=465
    KEYCLOAK_SMTP_FROM=no-reply@example.com
    KEYCLOAK_SMTP_USER=<smtp-user>
    KEYCLOAK_SMTP_PASSWORD=<smtp-password>
    KEYCLOAK_SMTP_SSL=true       # for port 465
    KEYCLOAK_SMTP_STARTTLS=false # flip to true for port 587
  3. Recreate Keycloak to pick up the changes:
    docker compose up -d --force-recreate keycloak

Other entrypoints

Once the stack is fully up:

Ports are configurable in .env under the HOST PORTS section — change any that clash with something already running on your machine.

Next steps

On this page