NetBird GitOps Reconciler — PoC Deployment
Ansible playbook that deploys a self-contained stack on VPS-A for end-to-end testing of the NetBird GitOps reconciler.
Stack overview
| Component | Purpose |
|---|---|
| Caddy | TLS termination, reverse proxy |
| NetBird | Management, Signal, Relay, Dashboard, TURN |
| Reconciler | Declarative config → NetBird API reconciler |
| Gitea | Local Git server (optional, off by default) |
All services run as Docker containers on a single VPS, connected via a netbird
Docker bridge network. Caddy handles ACME certificates automatically.
Prerequisites
- SSH access to
46.225.220.61(root, key-based) - DNS A record:
vps-a.networkmonitor.cc→46.225.220.61 rsyncinstalled locally (used to sync reconciler source)- Ansible 2.15+ with
community.generalandansible.posixcollections
Install collections if needed:
ansible-galaxy collection install community.general ansible.posix
Setup
1. Create vault file
cd poc/ansible
cp group_vars/all/vault.yml.example group_vars/all/vault.yml
For the first deploy, leave all values as empty strings — the playbook auto-generates NetBird secrets and a reconciler token.
2. Deploy
cd poc/ansible
ansible-playbook -i inventory.yml playbook.yml
The playbook will:
- Generate secrets (encryption key, TURN password, relay secret, reconciler token)
- Install Docker if not present
- Configure UFW firewall
- Rsync the reconciler source code to VPS-A
- Template all config files
- Build the reconciler Docker image on VPS-A
- Pull NetBird/Gitea images and start all services
- Run health checks and print a summary with generated secrets
Save the generated secrets printed at the end into vault.yml so subsequent
runs are idempotent.
3. Create NetBird admin + API token
- Open
https://vps-a.networkmonitor.ccin a browser - Create the first admin account (embedded IdP — no external OAuth)
- Go to Settings → Personal Access Tokens → Generate
- Copy the token into
vault.ymlasvault_netbird_api_token - Re-run the playbook:
ansible-playbook -i inventory.yml playbook.yml
The reconciler will now start successfully with a valid API token.
4. (Optional) Enable Gitea
To enable Gitea-backed GitOps polling:
- Open
http://vps-a.networkmonitor.cc:3000and complete the install wizard - Create an admin account (user:
blastpilot) - Create org
BlastPilotand reponetbird-gitops - Push
netbird.jsonto the repo - Generate a Gitea API token (Settings → Applications)
- In
vars.yml, setgitea_enabled: "true" - In
vault.yml, fill invault_gitea_tokenandvault_gitea_admin_password - Re-run the playbook
Testing
All commands below assume you have the reconciler token. Replace <TOKEN> with
the value of vault_reconciler_token.
Health check
curl https://vps-a.networkmonitor.cc/reconciler/health
Dry-run reconcile
curl -X POST \
-H "Authorization: Bearer <TOKEN>" \
-H "Content-Type: application/json" \
-d @ansible/files/netbird-seed.json \
'https://vps-a.networkmonitor.cc/reconciler/reconcile?dry_run=true'
Apply reconcile
curl -X POST \
-H "Authorization: Bearer <TOKEN>" \
-H "Content-Type: application/json" \
-d @ansible/files/netbird-seed.json \
'https://vps-a.networkmonitor.cc/reconciler/reconcile'
Export current state
curl -H "Authorization: Bearer <TOKEN>" \
'https://vps-a.networkmonitor.cc/reconciler/export'
Enroll a peer
Use a setup key from the reconcile response (created_keys field):
sudo netbird up --management-url https://vps-a.networkmonitor.cc --setup-key <KEY>
Teardown
Remove all containers and volumes:
ssh root@46.225.220.61 "cd /opt/netbird-poc && docker compose down -v"
File structure
poc/
ansible/
inventory.yml # VPS-A host definition
playbook.yml # Main deployment playbook
.gitignore # Excludes vault.yml
group_vars/
all/
vars.yml # Non-secret config (versions, ports, etc.)
vault.yml.example # Secret template — copy to vault.yml
templates/
docker-compose.yml.j2 # All services (NetBird + Gitea + Reconciler)
management.json.j2 # NetBird management config
Caddyfile.j2 # Caddy reverse proxy with reconciler route
dashboard.env.j2 # NetBird dashboard env
relay.env.j2 # NetBird relay env
turnserver.conf.j2 # TURN server config
reconciler.env.j2 # Reconciler env
files/
netbird-seed.json # Example desired state for testing
README.md # This file