Deployment
Step 1 — get the repo onto the Proxmox host and start setup
Either the one-liner (as root on the PVE host), which installs git if needed, clones — or updates — the repo into /opt/alethurgy-src, and starts the guided setup:
bash <(curl -fsSL https://raw.githubusercontent.com/alethurgy-com/alethurgy/main/bootstrap.sh)
or the same steps by hand:
apt-get install -y git
git clone https://github.com/alethurgy-com/alethurgy /opt/alethurgy-src
cd /opt/alethurgy-src
./proxmox-setup.sh
Use bash <(curl …), not curl … | bash — the setup is interactive. To re-run later: git -C /opt/alethurgy-src pull && /opt/alethurgy-src/proxmox-setup.sh (the script also offers to pull when it notices it’s behind origin).
Step 2 — answer the guided questions
Every question has a default — press Enter to accept it. On a first run the defaults are derived from the Proxmox host (gateway, DNS server, bridge, subnet prefix, storage, first free VMID block, DNS domain suffix, timezone) plus sensible sizing; VM IPs default to .20/.21/.22 in the gateway’s subnet. Your answers are saved to /opt/alethurgy/proxmox-setup.env (mode 600 — it holds the passwords and Cloudflare token) and become the defaults next time, so a re-run is just Enter, Enter, Enter.
| Flag | Effect |
|---|---|
./proxmox-setup.sh | interactive; saved answers are the defaults |
./proxmox-setup.sh --non-interactive | re-run with the saved answers, no prompts |
./proxmox-setup.sh --reset | ignore saved answers and start fresh |
./proxmox-setup.sh --answers FILE | use a different answers file |
You’ll be asked, in order:
| Question | Notes |
|---|---|
| Topology | Split (3 VMs, recommended) or single VM |
| Storage / bridge / VLAN | Validated against pvesm status |
| Static IPs or DHCP | Static recommended; asks per-VM IPs, prefix, gateway |
| DNS server | Internal resolver handed to the VMs |
| TLS mode | cloudflare (default: Let’s Encrypt wildcard via Cloudflare DNS-01) or internal (Caddy private CA) |
| Domain | cloudflare: a zone/subdomain hosted in Cloudflare, e.g. lab.example.com; internal: any local suffix, e.g. lab.internal. Web UIs live at https://<service>.<domain> |
| Let’s Encrypt email, Cloudflare API token | cloudflare mode only. Token is verified live (/user/tokens/verify) and the matching zone is looked up |
| Create wildcard DNS record? | cloudflare mode: creates/updates a DNS-only *.<domain> A record → metrics VM via the Cloudflare API |
| Site label, timezone, base VMID | VMIDs used: base, base+1, base+2 |
| ntfy server + topic | Default: public ntfy.sh with a random topic |
| Grafana / Graylog admin passwords | Enter blank to autogenerate (or to keep the saved one on re-runs) |
| VM sizing | Sane defaults offered (see Prerequisites) |
| PVE API token | Say yes — it creates a read-only monitoring@pve!exporter token (PVEAuditor) and wires pve_exporter automatically |
The script then:
- Downloads the Debian 12 genericcloud image (cached in
/var/lib/vz/template/cache/). - Creates the VM(s): cloud-init,
--cpu host, qemu-guest-agent installed via a vendor snippet, your SSH key injected (/root/.ssh/id_ed25519, generated if missing). - Waits for each VM’s IP via the guest agent, pushes the repo, and runs
scripts/deploy-stack.shinside with the right profile (core/logs/siem). - Each profile installs Docker, renders configs from templates, downloads the Grafana dashboard library from grafana.com, and brings services up phase by phase with health checks (Prometheus ready, Grafana healthy, Graylog lb-status, Wazuh dashboard responding…).
- Writes
POST-SETUP.md(your remaining-steps checklist) into the repo directory and appends the new VMs toinventory.md.
Runtime: roughly 10–25 minutes depending on download speeds. Graylog and Wazuh are the slow starters.
Deploying without Proxmox
deploy-stack.sh is standalone — on any Debian 12 / Ubuntu 22.04+ box:
sudo ./scripts/deploy-stack.sh --profile all # or core / logs / siem
Run interactively it asks the same questions (every one with a default) and saves answers to /opt/alethurgy/.env, which become the defaults next time; --non-interactive reuses them without prompting.
Step 3 — first login
In cloudflare mode with the DNS record created automatically, the names below resolve as soon as the deploy finishes; otherwise add *.<your-domain> → metrics VM IP (Cloudflare DNS-only, or local DNS). Then:
| Service | URL | First login |
|---|---|---|
| Grafana | https://grafana.<domain> | admin / your password — dashboards preloaded under Preloaded Library |
| Prometheus | https://prometheus.<domain> | no auth (LAN + proxy only) |
| Alertmanager | https://alertmanager.<domain> | no auth |
| Uptime Kuma | https://kuma.<domain> | create admin on first visit |
| Node-RED | https://nodered.<domain> | enable auth immediately (it has Docker socket access) |
| Netdata | https://netdata.<domain> | no auth |
| LibreNMS | https://librenms.<domain> | create admin on first visit |
| ntopng | https://ntopng.<domain> | admin / admin — change it |
| Graylog | https://graylog.<domain> | admin / your Graylog password |
| Wazuh | https://wazuh.<domain> | admin / SecretPassword — change it (see Post-setup) |
In cloudflare mode the certificate is a publicly-trusted Let’s Encrypt wildcard (*.<domain>) — no browser warnings, automatic renewal. Only in internal mode do you need to trust Caddy’s root certificate — see Post-setup, step 1.
Re-running / recovering
Everything is idempotent:
proxmox-setup.shdetects existing VMIDs and offers to reuse them.deploy-stack.shreloads saved answers from/opt/alethurgy/.envand re-renders configs + re-ups compose stacks (no data loss — data lives in named Docker volumes).- A failed phase can be retried by simply re-running the script.