Self-hosted DNS & reverse proxy management panel — built for homelab. Orchestrate Nginx Proxy Manager, Traefik, Zoraxy, Cloudflare, Pi-hole, AdGuard Home, and more from one unified interface.
Quick Start · Features · Screenshots · Providers · Docs · MCP
Why Vauxtra?
Publishing a new self-hosted app usually means touching three tools: a DNS record in Cloudflare or Pi-hole, a proxy host in Nginx Proxy Manager or Traefik, maybe a Cloudflare Tunnel route — and then remembering to keep them in sync. Vauxtra turns that into one service record: pick a hostname, a target and the providers that should publish it, and Vauxtra pushes, monitors and reconciles every piece for you.
- One form, every provider — DNS, reverse proxy and tunnel configured together, with preflight checks and dry-run.
- Keeps itself honest — health checks, drift detection, auto-reconcile and certificate expiry alerts.
- Bring your own stack — Vauxtra drives the tools you already run; it never replaces them.
Features
Screenshots
Screenshots follow your GitHub theme: switch between light and dark mode to see both UI themes.
Architecture
┌─────────────────────────────────────────────────────────┐
│ Vauxtra │
│ │
│ React 19 + TypeScript + Vite (SPA) │
│ │ │
│ FastAPI + SQLite (WAL) │
│ │ │
│ ┌──────┴────────────────────────┐ │
│ │ Providers │ │
│ │ NPM Zoraxy Traefik │ │
│ │ Cloudflare DNS CF Tunnel │ │
│ │ Pi-hole AdGuard Technitium │ │
│ │ PowerDNS deSEC │ │
│ └───────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
│
MCP Server (FastMCP) — client and automation integration
Vauxtra is an orchestrator: it does not run a reverse proxy or DNS server itself — it configures the ones you already have running.
Quick Start (Docker)
Pull the pre-built image from GitHub Container Registry:
docker run -d \
--name vauxtra \
-p 127.0.0.1:8888:8888 \
-v vauxtra_data:/app/data \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
ghcr.io/ptitzgeg-on-git/vauxtra:latest
The port is published on the loopback: the panel holds provider credentials and has none of its own until you complete the setup wizard. Once you have,
-p 8888:8888reaches it from the LAN — behind a reverse proxy, preferably.
The Docker socket is only needed for container discovery, and mounting it is a real grant:
:roapplies to the socket file, not to the Docker API, so whoever reaches it can start a privileged container and is root on the host. Drop the-v /var/run/docker.sockline if you do not use the Docker features — the rest of Vauxtra is unaffected and the Docker screens answer "daemon unavailable" — or front it with a read-only socket proxy.
Or use Docker Compose:
# docker-compose.yml
services:
vauxtra:
image: ghcr.io/ptitzgeg-on-git/vauxtra:latest
ports:
# Loopback by default; VAUXTRA_BIND=0.0.0.0 publishes on every interface.
- "${VAUXTRA_BIND:-127.0.0.1}:8888:8888"
volumes:
- ./data:/app/data
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- TZ=${TZ:-UTC}
restart: unless-stopped
docker compose up -d
Then open http://localhost:8888 in your browser.
The data/ directory stores the SQLite database and the auto-generated secret key.
Build from source? Clone the repo and run
docker compose up --build -d.
Configuration
All configuration is via environment variables. Copy .env.example to .env and fill in your values.
⚠️ Important: Do not change
SECRET_KEYafter adding providers. All stored credentials are encrypted with this key.
Forgot your password? If set via
.env, edit the file. If set via the Setup wizard, use Settings → Security → Change Password while logged in. Locked out entirely, clear both rows and restart:sqlite3 data/vauxtra.db "DELETE FROM settings WHERE key IN ('app_password_hash','auth_mode');"
auth_modeis what tells a deliberately passwordless install apart from one whose hash went missing. Deleting the hash on its own leaves the second state, and Vauxtra then refuses every request rather than falling back to anonymous admin — which is the point of it, and why it has to go too.
Documentation Map
- End-user quick start and feature overview: README.md
- End-user operations and API usage: docs/HOWTO.md
- Production deployment checklist and recipes: docs/DEPLOYMENT.md
- Troubleshooting and known failure patterns: docs/TROUBLESHOOTING.md
- Supported providers, evaluated candidates, writing your own: docs/PROVIDERS.md
- Integration lab against real provider containers: lab/README.md
- Security policy and reporting: SECURITY.md
- MCP server setup for compatible clients: vauxtra_mcp/README.md
Provider Setup
Nginx Proxy Manager
- In NPM, go to Users and create a dedicated API user (or use admin credentials).
- In Vauxtra, add a provider: type =
npm, URL =http://your-npm:81. - Test connection.
Traefik
Traefik is read-only in Vauxtra (it configures itself via Docker labels or config files).
- Expose the Traefik dashboard API at e.g.
http://traefik:8080. - In Vauxtra, add a provider: type =
traefik, URL =http://traefik:8080. - Use Sync → Import to import existing routes.
Zoraxy
Zoraxy has a single admin account and no API keys: Vauxtra logs in with the same credentials you use in the browser. Keep the management port reachable from the LAN or VPN only.
- Note the management URL, e.g.
http://zoraxy:8000, and the admin username/password (leave both empty for an instance started with-noauth). - In Vauxtra, add a provider: type =
zoraxy, URL =http://zoraxy:8000. - Test connection, then Sync → Import to pick up existing host rules.
Vauxtra manages host rules only (no virtual directories, no TCP/UDP stream proxies) and one upstream per rule; extra load-balanced upstreams are left untouched. Zoraxy terminates TLS globally, so there is no per-host "force SSL" switch.
Cloudflare DNS
- Create a Cloudflare API token with Zone → DNS → Edit permission for your zones.
- In Vauxtra, add a provider: type =
cloudflare, API token =<your-token>.
Cloudflare Tunnel
- Create a tunnel in the Cloudflare dashboard and copy the Tunnel ID (UUID).
- Create an API token with:
Account -> Cloudflare Tunnel -> EditZone -> DNS -> Edit
- Copy your Cloudflare Account ID.
- In Vauxtra, add a provider: type =
cloudflare_tunnel, with Account ID, API token, and Tunnel ID. - When creating a service, set expose mode to Tunnel.
Pi-hole / AdGuard Home
- Retrieve the API password from your Pi-hole or AdGuard Home admin panel.
- In Vauxtra, add a provider of the appropriate type with URL and credentials.
- For Pi-hole, use the base URL (e.g.
http://piholeorhttp://localhost:18081), not/admin.
PowerDNS Authoritative
- Enable the API in
pdns.conf:api=yes,api-key=<key>,webserver=yes, and awebserver-allow-fromthat includes Vauxtra. The API listens on:8081by default. - In Vauxtra, add a provider: type =
powerdns, URL =http://your-pdns:8081, server id =localhost(the stock value), API key =<key>. - The record has to fall inside a zone the server hosts — create the zone in PowerDNS first. Vauxtra picks the longest zone that contains the name.
deSEC
- Create a free account at desec.io and generate a token in Token management. A token limited to your domain is enough.
- In Vauxtra, add a provider: type =
desec, token =<token>. Leave the URL empty unless you run your own deSEC instance. - The domain field is optional: leave it blank to let Vauxtra pick the matching domain out of your account, or set it to pin every record to one domain.
MCP Integration
Vauxtra ships an MCP (Model Context Protocol) server package that exposes core operations as tools. Connect it to any MCP-compatible client.
Setup
- Create an API key in Vauxtra: Settings → API Keys → New Key.
- Note the generated key (shown once at creation).
The MCP server runs on the host (next to your MCP client), not inside the Vauxtra Docker image. Clone this repo and
pip install -r vauxtra_mcp/requirements.txton the machine that will launch the client. The server reaches Vauxtra over HTTP usingVAUXTRA_URL+VAUXTRA_API_KEY.
Example MCP client config
Add an equivalent server block to your MCP client configuration:
{
"mcpServers": {
"vauxtra": {
"command": "python",
"args": ["-m", "vauxtra_mcp.server"],
"cwd": "/path/to/vauxtra",
"env": {
"VAUXTRA_URL": "http://localhost:8888",
"VAUXTRA_API_KEY": "vx_your_key_here"
}
}
}
}
Available MCP tools
See docs/HOWTO.md for the full list. Summary:
Services — list_services, get_service, create_service, update_service, set_service_labels, delete_service, toggle_service, sync_services_from_providers, import_services_from_sync
Templates — list_templates, get_template, create_template, delete_template, apply_template
Operations — run_preflight, dry_run_push, push_service, check_drift, reconcile_service
Providers — list_providers, get_provider_types, create_provider, update_provider, delete_provider, test_provider, get_provider_health, get_all_providers_health, get_tunnel_health
Docker — list_docker_endpoints, discover_docker_containers, import_docker_containers
Monitoring — get_health, get_logs, get_stats, get_certificates, get_certificate_expiry, check_all_services
API Reference
When DEBUG=true is set, the full interactive API documentation is available at:
http://localhost:8888/api/docs
All endpoints accept Authorization: Bearer <api_key> in addition to session cookies.
Development Setup
Backend
# Requires Python 3.13+
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
# Run with auto-reload
uvicorn app.main:app --reload --port 8888
Frontend
cd frontend
npm install
npm run dev # Dev server on :5173 with API proxy to :8888
npm run build # Production build to frontend/dist/
npm run lint # ESLint
Running both together
The frontend dev server (npm run dev) proxies /api/* to the FastAPI backend at :8888. Run both in separate terminals.
Docker build
docker compose up --build
The Dockerfile uses a multi-stage build: Node 26 for the frontend, Python 3.14-slim for the final image.
Contributing
See CONTRIBUTING.md for:
- Local dev setup
- Conventional Commits guide
- How to add a DNS or proxy provider
- How to add an MCP tool
- PR checklist
Translating Vauxtra
The UI is fully internationalized. To add or improve a translation:
- Duplicate
frontend/src/locales/en.json - Name it with the ISO 639-1 code (e.g.
ko.json) - Add the language to
SUPPORTED_LANGUAGESinfrontend/src/i18n/index.tsx - Open a PR — no backend change needed
Upgrading
Vauxtra follows a rolling release model on the latest Docker tag:
docker compose pull
docker compose up -d
The database is automatically migrated on startup. No manual steps required.
License
MIT — see LICENSE.