Install Polaris
Run the portal with Docker Compose, put TLS in front and finish the setup wizard.
Requirements
- A Linux host with Docker Engine and the Compose plugin. 2 vCPU and 4 GB RAM are enough for a few thousand hosts; MariaDB needs most of the disk.
- A hostname for the web UI (e.g.
mon.example.com). Optionally separate hostnames for the satellite API and the websocket. - Outbound HTTPS from Polaris to crt.sh, RIPEstat and the RDAP servers of the registries, if you use those data sources. Polaris works without them.
- Access to the private images in the GitHub Container Registry:
docker login ghcr.iowith a token that hasread:packages.
The stack
| Service | Role |
|---|---|
mariadb | all data, sessions, the cache and the job queue |
web | nginx and PHP-FPM: the UI and, unless split off, the Pulsar API |
reverb | websocket server (Laravel Reverb) for immediate checks |
scheduler | runs the background tasks every minute (list) |
queue | works off queued jobs: notifications, reports, IP enrichment |
api (profile split-api) | the Pulsar API on its own hostname |
caddy (profile proxy) | TLS proxy with Let’s Encrypt for UI, API and websocket |
All four Polaris services run the same image with a different CONTAINER_ROLE.
Install
mkdir asterion && cd asterion
# docker-compose.yml and .env.example come with every release on GitHub
cp .env.example .env
Edit .env. The minimum:
APP_URL=https://mon.example.com
POLARIS_API_URL=https://mon.example.com
DB_PASSWORD=<long random>
DB_ROOT_PASSWORD=<long random>
POLARIS_WS_URL=wss://ws.mon.example.com
REVERB_APP_KEY=<random>
REVERB_APP_SECRET=<long random>
POLARIS_DOCS_URL=https://asteriondoc.meinlan.at
Leave APP_KEY empty: it is generated on the first start into the storage volume. Every variable is explained in the configuration reference.
docker compose up -d
docker compose logs web | grep -i "setup token"
Warning
Back upAPP_KEY (storage/app/.app_key in the polaris-storage volume) together with the database. It encrypts satellite secrets, TOTP secrets and notification credentials. A database restore without it loses them.TLS
Polaris itself speaks plain HTTP on port 8000 (UI and API) and 8081 (websocket). Put a TLS proxy in front:
- Own proxy (nginx, Traefik, HAProxy): forward
mon.example.comto port 8000 andws.mon.example.comto 8081 with websocket upgrade. PassX-Forwarded-Proto: https. - Built-in Caddy: set
POLARIS_HOST,POLARIS_API_HOST,POLARIS_WS_HOSTandACME_EMAIL, thendocker compose --profile proxy up -d.
With the proxy on the same host, set POLARIS_BIND=127.0.0.1 so the ports are not reachable around it, and narrow TRUSTED_PROXIES to the address of the proxy (default: loopback and private networks).
The Pulsar API refuses plain HTTP unless POLARIS_PULSAR_ALLOW_HTTP=true (lab only).
Setup wizard
Open https://mon.example.com/setup and enter the setup token from the log. The wizard
- checks the configuration (database, key, URLs, websocket, mail),
- creates your organisation (the first tenant) with its abuse contact,
- creates the first super admin,
- and then disables itself.
Unattended alternative: set POLARIS_ADMIN_EMAIL and POLARIS_ADMIN_PASSWORD before the first start, or run docker compose exec web php artisan polaris:admin you@example.com.
HTTPS-only mode
Without a websocket (POLARIS_WS_URL empty or BROADCAST_CONNECTION not reverb) satellites only run synced plans. Check now and Run now are disabled, and the first scan of new targets becomes a one-time plan that runs at the satellite’s next sync (within a minute).
Separate API hostname
# .env: POLARIS_API_URL=https://api.mon.example.com POLARIS_WEB_MODE=ui
docker compose --profile split-api up -d
The api container serves only the signed Pulsar API and a small landing page. The UI container then refuses API calls.
Upgrade
docker compose pull && docker compose up -d
The web container runs the database migrations on start (POLARIS_AUTO_MIGRATE, default on). See Backup and upgrade.