Install¶
One command, run as root — that's all. A fresh Debian 13 in a dedicated VM is
recommended (see Prerequisites), but it works just as well on
Ubuntu or alongside other services:
If curl is missing (minimal Debian), wget works too:
As root, without sudo
The installer needs root privileges (Docker, /opt, systemd). On Debian,
sudo is often not even installed — so log in as root first:
su - (Debian) or sudo -i (Ubuntu), then run the one-liner.
What the installer does¶
[1/6] Checking system – architecture, RAM, ports 80/443
[2/6] Installing prerequisites – openssl/curl, Docker (if needed)
[3/6] Downloading Vesana – compose file + configuration template
[4/6] Configuration – server address, license key (optional)
[5/6] Generating secrets – passwords, encryption key
[6/6] Starting Vesana – pull images, start stack, wait for health,
schedule the active checker setup
Long steps (Docker install, image download) run quietly in the background —
the full output goes to /var/log/vesana-install.log.
You are asked exactly two things:
- Address where Vesana should be reachable in the browser (suggested: the detected server IP — Enter accepts it)
- License key — Enter skips it (free Community Edition)
Then head to the browser: https://<your-address>/setup starts the
setup wizard. The certificate warning on first visit is expected
(self-signed certificate).
The installer ends by printing a setup link that carries a one-time code (…/setup?setup_token=…) and the code once more below it. If you open /setup by hand, the wizard asks for that code — you can paste the code or simply the whole link into the field. It is also in .env as VESANA_SETUP_TOKEN. Nobody else can set up the instance in the minutes between installation and completion. Once setup is complete the code no longer matters.
Finding the setup code again¶
If the installer output is gone, the code is in .env on the server:
Then open https://<your-address>/setup?setup_token=<code>, or open /setup
and enter the code in the field. It stays valid until the setup wizard is
complete.
Port 80 or 443 in use¶
If a web server is already running on the machine (Apache, nginx, a reverse
proxy), the installer reports ports 80/443 are already in use in step 1 and
offers to run Vesana on other ports — the other service keeps running:
Enter accepts the suggestion (always a port that is free right now; a free
standard port stays the suggestion). The address in the next step already
includes the port (https://<ip>:9443) — it belongs there, because agents and
collectors connect to that address later, too. Leave it out only behind a
reverse proxy that listens on 443 itself. If a firewall is active (e.g. ufw),
allow the chosen HTTPS port there. At the end you get the setup link and the
setup code as usual.
For an install without a terminal the same choice exists as the environment
variables VESANA_HTTPS_PORT and VESANA_HTTP_PORT (see
Unattended install).
If you answer the port question with n, you can still install Vesana
(without starting it) and switch the ports yourself later:
-
Set other ports in
/opt/vesana/.env, for example:The port belongs in
BASE_URLtoo — agents and collectors connect to that address later. Alternatively stop the other service (e.g.systemctl disable --now apache2) and keep 80/443. -
Run the installer again (the same one-liner). It finds the existing
.env, leaves the configuration untouched, skips the port check, starts Vesana and ends by printing the setup link with the code and the new port.
If you start the stack by hand with
docker compose -f /opt/vesana/docker-compose.prod.yml up -d instead, no link
is printed — take the code from .env as described under
Finding the setup code again.
Active checker & first network scan¶
The installation automatically sets up the active checker (Active Collector):
active checks like ping/SNMP/HTTP directly from the Vesana server. It runs as a
systemd service on the server, outside Docker. For this the installer creates a
systemd timer (vesana-ac-autoinstall.timer) that looks every 3 minutes and sets
up the service as soon as the setup wizard is finished — typically 1–3 minutes
later, across reboots too. Afterwards the timer switches itself off.
On first contact it looks up the reachable networks once and scans up to three
small private IPv4 networks (at most /22, e.g. 192.168.1.0/24) once for
devices — the results are under Discovery. It never scans public networks on
its own (such as the network of a rented server at a hosting provider). If the
active checker does not come online within 14 days, this first scan is dropped.
Status and any errors: Admin → Agents & Collectors → Active checker (+ diagnostic log),
log of the setup timer: journalctl -u vesana-ac-autoinstall.
Back up the FIELD_ENCRYPTION_KEY¶
Losing the key = losing data
At the end of step 5 the installer prints the FIELD_ENCRYPTION_KEY. It
protects encrypted fields (e.g. SNMP communities) and is deliberately
not part of backups. If it is lost, that data is permanently
unrecoverable.
Right after installation:
- Copy the key from the output (also in
/opt/vesana/secrets/) - Store it in a password manager (Bitwarden, 1Password, KeePass)
- Additionally keep an offline or separately stored copy
IPv6 (optional)¶
By default Vesana publishes its ports on IPv4 only. To make it reachable over IPv6 as well, set VESANA_IPV6=true in /opt/vesana/.env (during installation: the environment variable VESANA_IPV6=true) and run the next update. This needs Docker 27 or newer with IPv6 NAT; if Docker cannot do that (too old, rootless, ip6tables disabled), Vesana stays on IPv4 and states the reason in the updater log or the installer. Ports with a fixed address (HTTP_PORT=127.0.0.1:8285) stay unchanged.
Unattended install (automation)¶
Every question has an environment variable — so the installer runs without a terminal (Ansible, cloud-init, CI):
| Variable | Meaning |
|---|---|
VESANA_BASE_URL |
server address (required for unattended) |
VESANA_LICENSE_KEY |
license key (empty = Community) |
VESANA_DIR |
install directory (default /opt/vesana) |
VESANA_REGISTRY_USER / VESANA_REGISTRY_TOKEN |
private registry (Enterprise) |
VESANA_HTTPS_PORT / VESANA_HTTP_PORT |
other ports than 443/80 (e.g. when a web server uses them) |
VESANA_IPV6 |
true = also publish the ports over IPv6 (default: IPv4 only; needs Docker 27+ with IPv6 NAT) |
VESANA_VERSION |
install a specific version (image tag, e.g. v1.903.0); unset = current released version |
VESANA_PG_SIZING |
default = keep the template's Postgres memory values instead of deriving them from RAM (see Self-hosting) |
VESANA_PULSE |
off = the instance sends no instance pulse (test/throwaway installs) |
VESANA_NO_START |
any value (e.g. 1) = install but do not start |
VESANA_NONINTERACTIVE |
any value = no questions, even when a terminal is present |
Re-run¶
The installer is re-runnable: if /opt/vesana/.env already exists, the
configuration is left untouched (no secret rotation; overly open file
permissions on .env are tightened to root-only) — it makes sure the stack is
running. In doing so it downloads the current compose file and images again;
unless VESANA_VERSION is pinned in .env, the instance ends up on the current
released version — without the pre-update backup of the
GUI updater. So do not use it as an update substitute on a
production instance. For a complete reinstall:
docker compose -f /opt/vesana/docker-compose.prod.yml down -v
(deletes all data!), then rm /opt/vesana/.env and run the one-liner
again.
Next¶
- Setup wizard in the browser — admin account, license, first tenant, size
- Enable backups — before using it in production