Before you begin
Requirements and decisions
Use a Linux host with a current Docker Engine, Docker Compose plugin, Git and enough persistent storage for your retention period. Choose a DNS name such as nms.example.com, then decide whether Caddy owns public ports 80/443, coexists with Apache or Nginx, or uses a private CA.
git --version docker --version docker compose version openssl version
Server installation
Clone and prepare the source
Clone
sudo mkdir -p /opt/golive-nms sudo chown "$USER":"$USER" /opt/golive-nms git clone https://github.com/TerminalAddict/golive-nms.git /opt/golive-nms cd /opt/golive-nms
Create private configuration
cp .env.example .env chmod 600 .env nano .env
Select exactly one TLS override
Use the tabs below, then copy the matching supplied file to compose.override.yml.
Inspect before running
docker compose config docker compose config -q
HTTPS
Choose a TLS layout
Caddy owns public 80 and 443
GOLIVE_DOMAIN=nms.example.com GOLIVE_WEB_PORT=443 cp deploy/compose.direct.yml compose.override.yml
Public DNS must point to this host. Ensure no other process owns ports 80 or 443.
Existing Apache keeps port 80
GOLIVE_DOMAIN=nms.example.com GOLIVE_WEB_PORT=8443 GOLIVE_ACME_PORT=18080 cp deploy/compose.apache.yml compose.override.yml cp deploy/apache-golive-acme.conf deploy/apache-golive-acme.generated.conf nano deploy/apache-golive-acme.generated.conf
Replace @GOLIVE_DOMAIN@ and @ACME_PORT@, review, then install:
sudo install -m 0644 deploy/apache-golive-acme.generated.conf /etc/apache2/sites-available/golive-acme.conf sudo a2enmod proxy proxy_http sudo a2ensite golive-acme.conf sudo apachectl configtest sudo systemctl reload apache2
Existing Nginx keeps port 80
GOLIVE_DOMAIN=nms.example.com GOLIVE_WEB_PORT=8443 GOLIVE_ACME_PORT=18080 cp deploy/compose.nginx.yml compose.override.yml cp deploy/nginx-golive-acme.conf deploy/nginx-golive-acme.generated.conf nano deploy/nginx-golive-acme.generated.conf
Replace the domain, ACME port and web port placeholders, then install:
sudo install -m 0644 deploy/nginx-golive-acme.generated.conf /etc/nginx/sites-available/golive-acme.conf sudo ln -s /etc/nginx/sites-available/golive-acme.conf /etc/nginx/sites-enabled/golive-acme.conf sudo nginx -t sudo systemctl reload nginx
Private or LAN-only TLS
GOLIVE_DOMAIN=nms.internal.example GOLIVE_WEB_PORT=8443 cp deploy/compose.internal.yml compose.override.yml
After startup, export and trust Caddy's root on browsers and enrolling hosts:
docker compose cp caddy:/data/caddy/pki/authorities/local/root.crt ./golive-caddy-root.crt sudo cp ./golive-caddy-root.crt /usr/local/share/ca-certificates/golive-caddy-root.crt sudo update-ca-certificates
Secrets and settings
Configure .env
Replace every change-me value with an independent secret.
GOLIVE_DOMAIN=nms.example.com GOLIVE_WEB_PORT=443 GOLIVE_COLLECTOR_PORT=9443 POSTGRES_PASSWORD=use-a-long-random-password GOLIVE_ENCRYPTION_KEY=use-an-independent-random-32-byte-value GOLIVE_ADMIN_EMAIL=admin@example.com GOLIVE_ADMIN_PASSWORD=use-a-different-long-password GOLIVE_AGENT_TOKEN=use-a-long-random-emergency-token GOLIVE_MONIT_USERNAME=monit GOLIVE_MONIT_PASSWORD=use-a-long-random-monit-password GOLIVE_BACKUP_PASSPHRASE=use-a-long-random-backup-passphrase GOLIVE_SYSLOG_PORT=5514 GOLIVE_TRAP_PORT=1162 GOLIVE_BACKUP_INTERVAL=24h GOLIVE_BACKUP_KEEP=10 GOLIVE_RETENTION_DAYS=395
openssl rand -hex 24 openssl rand -base64 32
Optional OIDC SSO
GOLIVE_OIDC_ISSUER=https://identity.example.com GOLIVE_OIDC_CLIENT_ID=golive-nms GOLIVE_OIDC_CLIENT_SECRET=replace-with-client-secret GOLIVE_OIDC_REDIRECT_URL=https://nms.example.com/api/v1/auth/oidc/callback
Server network access
Open only what you use
| Purpose | Port | Required |
|---|---|---|
| UI and enrollment | 443 or 8443 TCP/HTTPS | Yes |
| Public ACME | 80 TCP | Public TLS |
| Agents, collectors, Monit | 9443 TCP/HTTPS | When used |
| Syslog | 5514 TCP/UDP | Optional |
| SNMP traps | 1162 UDP | Optional |
sudo ufw allow 8443/tcp comment 'GoLive web and enrollment' sudo ufw allow 9443/tcp comment 'GoLive agents collectors and Monit' # Optional receivers sudo ufw allow 5514/tcp sudo ufw allow 5514/udp sudo ufw allow 1162/udp
sudo firewall-cmd --permanent --add-port=8443/tcp sudo firewall-cmd --permanent --add-port=9443/tcp sudo firewall-cmd --reload
First start
Build and verify
cd /opt/golive-nms docker compose config -q docker compose up -d --build --wait docker compose ps
Inspect failures with:
docker compose logs --tail=200 app docker compose logs --tail=200 caddy docker compose logs --tail=200 postgres
Deliberately reset a failed first install
docker compose down -v --remove-orphans docker compose config docker compose up -d --build --wait
First login
Establish your operating model
Open the configured HTTPS URL and sign in with GOLIVE_ADMIN_EMAIL and GOLIVE_ADMIN_PASSWORD.
- Create sites and locations.
- Create managers, site managers and viewers; assign site grants.
- Add encrypted SNMP, RouterOS, SSH or Monit credentials.
- Create email, Slack and Teams alert channels.
- Send a test through every channel.
- Add devices, parent relationships and checks.
- Create maintenance windows for scheduled outages.
Remote Linux hosts
Install the static Linux agent
No runtime dependencies and no inbound agent port. In Settings → Agents and collectors, choose Linux agent, select its site and generate a one-use, 15-minute enrollment token.
uname -m wget https://github.com/TerminalAddict/golive-nms/releases/download/VERSION/golive-agent_VERSION_linux_amd64.deb sudo dpkg -i ./golive-agent_VERSION_linux_amd64.deb sudoedit /etc/golive-agent.env
sudo dnf install ./golive-agent_VERSION_linux_amd64.rpm # or: sudo rpm -Uvh ./golive-agent_VERSION_linux_amd64.rpm sudoedit /etc/golive-agent.env
sudo apk add --allow-untrusted ./golive-agent_VERSION_linux_amd64.apk sudo vi /etc/golive-agent.env
tar -xzf golive-agent_VERSION_linux_amd64.tar.gz cd golive-agent_VERSION_linux_amd64 sudo install -m 0755 golive-agent /usr/bin/golive-agent sudo install -d -m 0700 /var/lib/golive-agent sudo install -m 0600 golive-agent.env.example /etc/golive-agent.env sudo install -m 0644 deploy/golive-agent.service /etc/systemd/system/ sudoedit /etc/golive-agent.env
GOLIVE_SERVER=https://nms.example.com:9443 GOLIVE_ENROLL_URL=https://nms.example.com GOLIVE_ENROLLMENT_TOKEN=PASTE_THE_ONE_TIME_TOKEN
sudo systemctl daemon-reload sudo systemctl enable --now golive-agent sudo journalctl -u golive-agent -f
sudo rc-update add golive-agent default sudo rc-service golive-agent start tail -f /var/log/golive-agent.log
After enrollment, remove the enrollment URL and token, leaving only GOLIVE_SERVER, then restart.
Remote sites
Install a site collector
A collector connects outbound to GoLive and polls its site's private targets. It opens no inbound port.
- Choose Remote site collector in Settings.
- Assign the site and generate a token.
- Install the matching
golive-collectorpackage or tarball. - Configure server, enrollment URL and token as above.
- Start it, check its journal, then remove enrollment values.
sudoedit /etc/golive-collector.env sudo systemctl enable --now golive-collector sudo journalctl -u golive-collector -f
Central polling automatically resumes if the collector is unavailable or revoked.
Monit integration
Send all Monit services to GoLive
set eventqueue
basedir /var/lib/monit/events
slots 1000
set mmonit https://monit:YOUR_MONIT_PASSWORD@nms.example.com:9443/collector
with timeout 15 seconds
and register without credentialssudo monit -t sudo monit reload sudo monit status
Optional remote actions
set httpd port 2812 and
allow golive:LONG_UNIQUE_PASSWORD
allow localhostsudo ufw allow proto tcp from 203.0.113.10 to any port 2812 comment 'GoLive Monit control' sudo monit -t sudo systemctl reload monit
- Create a Monit remote-control credential in Settings → Network credentials.
- Open the device and enter
http://host:2812. - Select the credential, save, then use Test & sync services.
- Use audited start, stop, restart, monitor and unmonitor controls.
Complete firewall matrix
Every communication
| Source → destination | Port | Purpose |
|---|---|---|
| Browser → NMS | Web HTTPS | UI, API, enrollment |
| Agent / collector → NMS | Web HTTPS | One-time CSR |
| Agent / collector / Monit → NMS | 9443 TCP | Reports and assignments |
| NMS → Monit | 2812 TCP | Optional actions |
| Devices → NMS | 5514 TCP/UDP; 1162 UDP | Syslog and traps |
| NMS / collector → targets | ICMP / configured TCP | Checks |
| NMS / collector → SNMP | 161 UDP | Polling |
| NMS / collector → MikroTik | 8728 / 8729 TCP | RouterOS |
| NMS → managed device | 22 TCP | Config capture |
| NMS → SMTP | 25 / 465 / 587 TCP | |
| NMS → webhooks / OIDC | 443 TCP | Alerts and SSO |
| Hosts → DNS / NTP | 53 / 123 | Names and time |
Agents and collectors do not listen for NMS connections. A site collector—not the central server—needs access to that site's targets.
Protect your history
Back up and restore
cd /opt/golive-nms docker compose run --rm backup backup
docker compose stop app victoriametrics victorialogs docker compose run --rm backup restore /backups/golive-YYYYMMDDTHHMMSSZ.tar.age docker compose up -d --wait
Safe maintenance
Upgrade only this project
cd /opt/golive-nms docker compose run --rm backup backup git pull --ff-only docker compose up -d --build --wait docker image prune docker compose ps
Never stop every container on a shared host. Migrations run at startup. Agent package upgrades retain state and do not require reenrollment.
Diagnostics
Troubleshooting checklist
- Check DNS from the affected host.
- Synchronize clocks.
- Distinguish enrollment web port from collector port 9443.
- Use an unused token under 15 minutes old.
- Confirm certificate trust.
- Inspect Compose service status and logs.
- Inspect agent or collector journals.
- Check NAT and both firewalls.
- Confirm the identity is not revoked.
- Test direct target reachability from the polling host.
getent hosts nms.example.com curl -v https://nms.example.com/ openssl s_client -connect nms.example.com:9443 -servername nms.example.com </dev/null