Vaier — Norwegian for wire, pronounced VY-er — wires together WireGuard, Traefik, and Google or GitHub sign-in (via oauth2-proxy) into a single web UI. One wildcard DNS record, made once, covers everything from here: add a Docker container on any VPN peer, pick a subdomain, and Vaier handles the reverse proxy and HTTPS automatically.
You spin up a container on a homelab box. Now you need a WireGuard peer, a DNS record, a Traefik dynamic-config entry, a Let's Encrypt cert, a forward-auth rule, and a bookmark somewhere you'll actually find later. Every new service repeats the whole dance. Every drift is silent.
One wildcard DNS record, made once, before you ever run docker compose up.
From then on, Vaier discovers containers on every connected peer, lets you pick a
subdomain, generates the Traefik route, provisions the cert, optionally gates it behind
Google or GitHub sign-in, and rolls back the flow if anything fails. Nothing to add to
DNS, ever — the name already resolves. Your homelab now feels like a PaaS.
Create, delete, and monitor WireGuard peers. Download QR codes, .conf files, docker-compose, or setup scripts — whichever fits the peer type. And you never type a CIDR: Vaier reads the network a server sits on over the SSH connection it already has, then says "Colina 27 sits on 192.168.1.0/24" and names the interface it read it from. One click and the whole fleet reaches that network — never one that would cut a machine off its own uplink.
Open a real, persistent SSH shell to any machine — peers, LAN servers, or the Vaier host itself — in its own window. Backed by tmux on the machine, it reattaches automatically across reconnects and even a Vaier redeploy. Credentials stay server-side; the browser never sees the secret. No key for a machine yet? Vaier mints an ed25519 keypair itself, keeps the private half, and hands you the one line to paste into authorized_keys. Paste your own key instead and it's checked while you're still looking at the form — a .pub or a PuTTY .ppk is caught there, not at the next thousand connects. Every machine says which user Vaier acts as on it, with root flagged on its card — so you know what a delete reaches before you click it. And when a host key changes, Vaier refuses the connection and hands you the way back: clear the pin, reconnect, re-pinned on first use.
The vault's other half: a secret that has to live on every machine, rather than one Vaier uses to reach one — a CLI's login file, an API token. Paste it once and Vaier puts it at the same path on every machine that runs a shell it can reach, at the mode you pick. It never reads what you handed it: it copies the bytes and checks what came back, so a file that lands owned by the wrong user is a reported failure instead of one that looks right and silently doesn't work. One strip per credential says where it's in place, where it's out of date, and where it never landed — machines with no shell to hold it are named underneath, not counted against you. Vaier rechecks every five minutes and puts back whatever went missing, but only for a credential you've distributed at least once. Withdraw takes it off the fleet everywhere it can reach and stops Vaier putting it back.
Sign every machine's Claude Code CLI in to your own Anthropic account from the browser — no terminal on the box, no credential file copied around. Vaier starts the sign-in on the machine, hands you the link, takes the code Anthropic shows you back to the CLI waiting there, and then asks the machine where it landed. The credential is Anthropic's to mint and the CLI's to keep: it never passes through Vaier, nothing about it is stored, and Sign out asks that CLI to let go rather than deleting a file. The machine's own page names the user Vaier acts as there and the account it's signed in as — a sign-in lives in one user's home, and a box can be signed in as one login and expired as another — so a fleet quietly split across two accounts shows up before something fails oddly. That page says it in Claude's own clay too, faded when signed out, so it never disagrees with the card. And you don't have to open a machine: its card in the fleet wears a small mark in that same clay, hollow when it's signed out — colour for whose sign-in it is, weight for whether anyone holds one, leaving green, amber and red to the marks that mean trouble. It comes from the same five-minute rounds that read its disks, and a sign-in you just finished lands on the card at once rather than waiting for the next one. Nothing is woken to draw it — and a machine Vaier hasn't asked, one with no Claude on it, or one that didn't answer gets no mark at all, never one that says signed out.
Any container on any peer becomes a public HTTPS subdomain in one click — no DNS step, since the name already resolves under your wildcard record — with automatic rollback if the route fails.
A dashboard linking every published service — automatically switching to direct LAN URLs when you're on the same network.
Traefik dynamic config is generated for you, with a per-service auth mode — public or social sign-in — a CrowdSec-powered edge that blocks malicious traffic before it reaches your backends, and a branded offline page when a backend is down.
Vaier stays out of DNS entirely: one *.yourdomain.com record, made once at whatever host your domain lives on, covers the console, sign-in, and every service you'll ever publish — checked and reported at every boot.
Every Google or GitHub identity is an access entry with a role — pending, user, or admin — and free-form per-service groups. Approve newcomers and gate services from the UI, no YAML.
Every disk on every machine is watched, with a fill-rate forecast that learns the disk over a week and mails you days before it crosses the line you set — "1.2 GiB/day, reaches its 80% threshold in 4.5 days". It counts down to your threshold rather than to 100%, so the warning lands while there's still something to do about it, and it tracks free space rather than a rounded percentage, so a slow creep can't hide in the rounding. A nightly build-and-prune sawtooth doesn't fake an emergency either. A disk already too full when Vaier starts is mailed about on sight, then again only when it climbs five points — never "still full" on a timer — and the all-clear waits until it has drained five points back under the line, so a disk hovering either side of your threshold never mails you a scare and an all-clear every day. And you don't wait for the mail: every machine's card carries its worst disk — the disk's own violet while it has room, amber or red once it hasn't — from the reading Vaier already takes on its rounds — no machine is woken to draw it, and one Vaier hasn't read yet stays blank rather than looking fine. Plus container image-update detection with a one-click Update — pulls the newer image and recreates the container from its own compose file, over SSH — and up/down alerts. Email you can trust: routine bans at the edge are shown, never mailed, so a message from Vaier always means something.
CrowdSec turns the internet's scanners away at the edge — and Vaier shows you who: every blocked address live, with its country and network, pinged red on the fleet map. Two buttons per row: let it back in, or trust it. Everything you've trusted is listed right below, one click to take it back. You're emailed only when it's a credential attack, or when one of your own networks gets caught. The map's other colour is who got let in: a green dot per city an allowed sign-in or request came from, with the count and who's behind it — VPN and LAN traffic has no city to show, so it's kept as a plain, honest count beside the map instead of vanishing — and a request from a full-tunnel phone or laptop, which reaches Vaier wearing the server's own address, is counted there too rather than drawn wherever your server is hosted.
Automated borg backups to one designated backup server, with a self-updating "survival kit" so your archives stay readable even if Vaier itself is gone. An archive with holes in it doesn't stay quiet: the machine tells you which files it lost, and one click makes Vaier read all of them from the next run.
One tree for the whole fleet — browse files and containers, select and transfer across machines, drop files straight into a folder to upload them, step back in time through backup archives, and see who's blocked at the edge right now. Every folder, machine and archive has its own link, so reload, Back and a pasted URL land exactly where you were. Each machine's card says what it can do, how its last backup went, which disk is closest to full, where it stands on Claude sign-in, how many containers want a newer image — open one and update it — and what it last opened, and when, whenever that reach came over the tunnel itself. The tree folds away on a desktop and is gone on a phone, where the cards, the crumbs and ⌘K do the moving. Its map is honest about phones: claim the browser on one and it shares its own position, which always beats a guess at its carrier's address — and a dead tunnel with nothing shared draws nothing, never a stale dot. Open a pin and you also get that machine's trail: where it has actually been these last 30 days, thinning and fading toward the older end so you read the direction at a glance. One trail at a time, the open one, so a fleet of phones stays a map instead of a scribble — and only positions the device reported itself ever join it, because a carrier's whole address block resolves to one point and a journey drawn from those is a line from head office to itself. Forget takes the position, the trail and the claim in one go — even a report already on its way when you press it.
The oauth2-proxy sign-in and the Dex broker screens share Vaier's dark theme — the Google/GitHub hand-off feels like one app, not three.
Every published service resolves under your one wildcard DNS record to the single Vaier server, terminates TLS at Traefik, optionally passes social-login authorization (Google or GitHub via oauth2-proxy, then Vaier's own access check), and is proxied over WireGuard to the container running on a peer. The peers never need a public IP.
An EC2 t3.small or equivalent. Open TCP 22, 80, 443 and UDP 51820. Bring a domain you control, hosted anywhere that can serve a wildcard A record.
# run as your regular user, not root curl -fsSL https://get.docker.com | sh sudo usermod -aG docker $USER # then log out and back in
One script fetches the runtime files Vaier needs — the compose file and the assets it bind-mounts — and scaffolds a .env with three secrets already generated for you. No git clone.
mkdir -p vaier && cd vaier curl -fsSL https://raw.githubusercontent.com/getvaier/vaier/main/install.sh | bash
Make one wildcard record, before first boot, at whatever DNS host your domain lives on — it covers the console, sign-in, and every service you'll ever publish:
# *.yourdomain.com A <this server's public IP>
Then open the .env that step 3 created. Register a Google (and/or GitHub) OAuth client with the callback URL https://dex.yourdomain.com/callback, and drop the ids in — at least one provider is required. Set VAIER_ADMIN_EMAIL to the account that becomes the first admin. Don't recreate the file — it already holds three secrets install.sh generated for you.
VAIER_DOMAIN=yourdomain.com ACME_EMAIL=you@yourdomain.com VAIER_ADMIN_EMAIL=you@gmail.com VAIER_OIDC_GOOGLE_CLIENT_ID=...apps.googleusercontent.com VAIER_OIDC_GOOGLE_CLIENT_SECRET=...
Bring everything up, open https://vaier.yourdomain.com, and sign in with the account you set as VAIER_ADMIN_EMAIL — Vaier seeds it as the first admin, so you land straight in the console. Anyone else who signs in lands as a pending request until you approve them on the Users page.
docker compose up -d # then open https://vaier.yourdomain.com and sign in
You're done patching together Caddy/Traefik configs by hand every time you stand up Plex, a Git server, or yet another self-hosted toy. Vaier is the layer that makes a single Linux box behave like a tiny private cloud.
Approve teammates by their Google or GitHub identity, gate sensitive services by access group, and let everyone find the apps via the launchpad. No spreadsheets of URLs. No passwords to hand out — no "what's the password for X" pings.