Hyprvolt documents what an on-premise business, organization or homelab runs: where each box is, what sits in which rack unit, when its warranty ends, which IP is free on which VLAN, how things depend on each other, and the runbooks that explain them. It is a self-hosted web app that runs in one Docker container, with its data in a single SQLite volume.
Features
- Places — sites, buildings, rooms, racks and shelves, with breadcrumbs on everything, and rack elevations, front and rear, that flag overlaps and anything that no longer fits
- Hardware — servers, network gear, UPSes, storage, IP phones, cameras and desks, with serials, asset tags, warranties, specs and a lifecycle
- What runs where — hypervisors, VMs, LXC and Docker containers and compose stacks; services and what they run on, including cloud services such as Microsoft 365
- Networks — VLANs, subnets with a map of used and free addresses, Wi-Fi networks, ports and cables traced end to end, DNS records, and where the internet comes in, with the line's circuit, speeds and static addresses
- Diagrams — a network diagram drawn from the cables (per building, per network or the whole site), a map of each record's links, and a dependency diagram, all zoomable
- What breaks — typed links between any two records, with cables counting as dependencies, so a switch lists everything plugged into it and everything running on those. Maintenance windows show everything they take down
- A site setup guide — documents a site a step at a time, from buildings and rooms out through VLANs, network gear, servers, services and endpoints. It can suggest the cabling for you, labels cables by network, and ends by drafting the site's runbook
- Knowledge base — Markdown documents that attach to records and link to them with
[[slug]], with code highlighting, task lists, nested pages and restricted documents - Secrets vault — passwords and keys on any record, encrypted with a key kept out of the database, each reveal recorded in the history
- Software and contracts — installations and license seats, vendors, people and contracts
- Certificates and backups — TLS certificates kept current by reading them from the servers that serve them, and backup jobs whose scripts report each run
- Import and export — CSV export of any list, CSV import with column matching and a check first, a JSON export of everything, and an import of services from a Homepage dashboard that matches each one to what it runs on
- Everyday polish — attachments, pictures, tags, custom fields and a full change log on every record; delete with Undo, archive, and search everything with
Ctrl K; printable asset labels with QR codes - Viewer, editor and admin roles, optional Cloudflare Turnstile, and light and dark themes
- A JSON API for scripts, with per-user tokens that can be limited to reading
- A module system, so new kinds of records arrive without changes to the core
- A demo homelab to try it on, and backups made, scheduled, downloaded and restored from Settings
Install with Docker Compose
No clone needed — the image is on Docker Hub. Save this as docker-compose.yml in an empty directory:
# The project name, fixed so the container and its volume keep their names
# whatever the folder is called.
name: hyprvolt
services:
hyprvolt:
image: hyprlab/hyprvolt:latest
container_name: hyprvolt
ports:
# host:container. Change the left side if 8101 is taken on your host.
- "8101:8000"
environment:
# What the app calls itself.
- APP_NAME=${APP_NAME:-Hyprvolt}
- APP_TAGLINE=${APP_TAGLINE:-IT documentation for on-premise infrastructure.}
# Session signing key. If unset, one is generated and kept in the volume.
- SECRET_KEY=${SECRET_KEY:-}
# The secrets vault's key. If unset, one is made in the volume; keep a
# copy of it elsewhere either way: losing it loses the secrets.
- SECRETS_KEY=${SECRETS_KEY:-}
# Where Settings > Backups keeps backups; /data/backups (the data
# volume) unless set. Mount another disk and point this at it.
- BACKUP_DIR=${BACKUP_DIR:-}
# Set to 1 when the app is served over HTTPS.
- SESSION_COOKIE_SECURE=${SESSION_COOKIE_SECURE:-0}
# How many reverse proxies sit in front (Cloudflare Tunnel, Caddy...).
- TRUST_PROXY=${TRUST_PROXY:-0}
# Cloudflare Turnstile. Usually set up in Settings > Security instead.
- TURNSTILE_SITE_KEY=${TURNSTILE_SITE_KEY:-}
- TURNSTILE_SECRET_KEY=${TURNSTILE_SECRET_KEY:-}
# Fresh-install defaults. After setup, Settings > Admin wins.
- ALLOW_REGISTRATION=${ALLOW_REGISTRATION:-0}
- WORKER_MINUTES=${WORKER_MINUTES:-15}
- ITEMS_PER_PAGE=${ITEMS_PER_PAGE:-40}
# The time zone times are typed and shown in, such as America/Chicago.
- TZ=${TZ:-UTC}
volumes:
- hyprvolt-data:/data
restart: unless-stopped
volumes:
hyprvolt-data:Start it and open http://localhost:8101:
docker compose up -dThe first visit opens the setup wizard, which creates the admin account and then goes straight into the guide that documents your first site — there is no default account or password. Want to look around first? The guide's first page offers to load a demo homelab instead (flask seed-demo does the same from the server).
To follow the beta channel, change the image tag to :beta (previews of the next release, such as 1.4.0-beta.2 — back up first), or pin a version such as :1.4.0, or a line such as :1.4 for its patches only.
Setting up a site
The setup guide walks through a site in five parts, each step a list of rows you edit in place, saved as you type:
- The place — the site, its buildings and rooms (as a drag-and-drop tree), racks, and the vendors it deals with
- The network — where the internet comes in, VLANs, subnets and wireless networks
- The equipment — network gear, servers and storage
- What runs — hypervisors, virtual machines and services (or import them from a Homepage
services.yaml) - The endpoints — the UPSes that power them, and the cables between everything
Each step has a What goes here button explaining what belongs in it and why. The Cables step can Suggest cables — the modem to the router, that to the core switch, and every device to its nearest switch that carries its subnet — and draws the network diagram as you go. The last page counts what was recorded and offers to start the site's runbook: a draft knowledge-base document linking to everything the guide recorded, with headings for who to call, what to check first and how to recover.
Secrets
Passwords, API keys, SSH keys and license keys live in the Secrets tab of the record they belong to. Admins always see them; viewers and editors only when an admin grants access. A value stays hidden until Show (which hides it again after 30 seconds), and every Show and Copy is written to the record's history. Values are never searched, exported or given to an API token.
They are encrypted with a key that is not in the database — from SECRETS_KEY, or else secrets.key in the volume. Backups leave the key out on purpose, so download a copy from Settings › Secrets and keep it somewhere other than this server: losing the key loses the secrets.
The API
Everything the interface does goes through a JSON API. Make a token in Settings › API tokens (optionally read-only) and send it as a header:
curl -H "Authorization: Bearer hv_…" "http://localhost:8101/api/entities?type=server"
curl -H "Authorization: Bearer hv_…" -H "Content-Type: application/json" \
-d '{"type": "server", "name": "srv3", "fields": {"ram_gb": 64}}' \
http://localhost:8101/api/entitiesPOST /api/entities/by-slug/<slug> creates or updates a record by slug, so an import can run again without making copies. No token can reveal a secret, download the secrets key or a backup, or make tokens — those need someone signed in.
Configuration
Everything is optional — the app starts with none of it set. Put values in a .env file next to docker-compose.yml, then docker compose up -d to apply:
| Variable | Default | Purpose |
|---|---|---|
APP_NAME / APP_TAGLINE | Hyprvolt / its tagline | What the app calls itself, on the sign-in page and in About |
SECRET_KEY | generated | Signs sessions; if unset, one is generated and kept in the volume |
SECRETS_KEY | made in the volume | Encrypts the secrets vault — keep a copy off the server |
BACKUP_DIR | /data/backups | Where Settings › Backups keeps backups; point it at another disk |
SESSION_COOKIE_SECURE | 0 | Set to 1 when the app is served over HTTPS |
TRUST_PROXY | 0 | How many reverse proxies are in front — usually 1 behind one |
TURNSTILE_SITE_KEY / TURNSTILE_SECRET_KEY | empty | Cloudflare Turnstile; usually set in Settings › Security instead |
ALLOW_REGISTRATION | 0 | Whether anyone can create an account; the setup wizard's answer wins |
WORKER_MINUTES | 15 | How often background work runs; 0 keeps the worker from starting |
ITEMS_PER_PAGE | 40 | Records per page |
TZ | UTC | The time zone the app starts with; Settings › Admin changes it |
DATA_DIR | /data | Where the database and attachments live inside the container |
APP_TAGLINE, ITEMS_PER_PAGE and the Turnstile keys are only fresh-install defaults — once a setting is saved in the app, what is saved there wins. Behind Cloudflare Tunnel, Caddy, Traefik or nginx, set TRUST_PROXY=1 (the number of proxies in front) and, with HTTPS at the proxy, SESSION_COOKIE_SECURE=1.
Example .env
Copy this to .env next to your docker-compose.yml and adjust:
# Copy to .env and adjust. Everything is optional: the app starts with none of
# it set. The last three are only seeded on a fresh install; after the setup
# wizard, Settings > Admin wins.
# What the app calls itself.
APP_NAME=Hyprvolt
APP_TAGLINE=IT documentation for on-premise infrastructure.
# Session signing key. If unset, one is generated and kept in the data
# directory, so sessions survive a restart.
SECRET_KEY=
# The key that encrypts the secrets vault. If unset, one is made in the data
# directory the first time a secret is saved. Either way, keep a copy of it
# away from this server: losing it loses the secrets. `flask secrets new-key`
# prints a fresh one.
SECRETS_KEY=
# Where Settings > Backups keeps backups. Unless set, the data volume's
# backups folder, on the same disk as the data: mount another disk and point
# this at it to keep backups apart.
BACKUP_DIR=
# Set to 1 when the app is served over HTTPS, so session cookies are Secure.
SESSION_COOKIE_SECURE=0
# How many reverse proxies sit in front of the app. 0 trusts no
# X-Forwarded-* header; a number higher than the real one lets clients spoof
# their address.
TRUST_PROXY=0
# Cloudflare Turnstile. Usually set up in the app instead, in Settings >
# Security, which checks the keys with a live challenge before saving them.
# Keys here are a fresh-install default; what is saved in the app wins.
TURNSTILE_SITE_KEY=
TURNSTILE_SECRET_KEY=
# ——— Fresh-install defaults ———
ALLOW_REGISTRATION=0
WORKER_MINUTES=15
ITEMS_PER_PAGE=40
# The time zone times are typed and shown in, such as America/Chicago.
TZ=UTCUpdating & backups
docker compose pull && docker compose up -dMigrations run by themselves at startup; a major version (2.0.0) means an existing install needs something done by hand, and the changelog says what.
Backups are all done in Settings › Backups, no terminal needed: make one now, or let the background worker make one every 24 hours and keep the newest 7. A backup holds every record, account, setting and attached file (the database is copied with SQLite's online backup API, so it is consistent while people keep working). Restore… shows what a backup holds before replacing anything, and saves the current state as a backup first, so a restore can be undone. To move to a new server, install there, upload the backup and restore it — then put the secrets key back in Settings › Secrets.
AI notice
Hyprvolt is built by a human maintainer who uses generative AI as a development tool. The maintainer decides what gets built, reviews the results, tests every release and signs off on everything that ships. The app itself contains no AI and makes no requests to AI services.
Tech stack & license
Flask · SQLAlchemy · SQLite · gunicorn · cryptography · Pygments — no frontend framework. Free and open source under the MIT License. Full docs and releases on GitHub, images on Docker Hub.