Deploy QRcodes on VRSCTEST
Purpose: Build and deploy the Verus Identity QR Creator on the VRSCTEST testnet, accessible via https://qrcodes.vrsctest.buildwithdreams.com.
Why: The QR Creator generates Verus identity QR codes (i.e., self-sovereign identity documents). It is a Node.js/TypeScript web application that proxies Verus daemon calls for signing and verification workflows.
Chain: VRSCTEST testnet Network: net-vrsctest (10.200.0.0/24) QR Creator: 10.200.0.13:3000 URL: https://qrcodes.vrsctest.buildwithdreams.com
Prerequisites
- VRSCTEST daemon running (
08b-start-vrsctest.ymlcomplete,docker pshealthy) - HITL approval obtained
verus-identity-update-qr-creator-mainrepo will be cloned on BWD (if not already present)
IP Addressing Convention
All chains use the same final-octet convention within their /24 Docker network:
| Role | IP |
|---|---|
| Daemon | .11 |
| RPC server | .12 |
| QR Creator | .13 |
VRSC mainnet and VRSCTEST use identical octets on their respective networks — no IP conflict between them.
Port Binding
| Service | Internal port | External host port |
|---|---|---|
| VRSCTEST QR Creator | 3000 | None (Docker network only) |
The QR Creator has no host port binding — it is reachable only from within net-vrsctest. Caddy (which is connected to both net-vrsc-blue and net-vrsctest) proxies all external HTTPS traffic to it over the Docker network.
This avoids a port conflict with the mainnet QR Creator, which already binds 127.0.0.1:3000 on the same host.
Architecture
Caddy is dual-homed. After running
37-qrcodes-caddy-network.yml, the Caddy container (mains_blue_caddy-caddy-1) is connected to bothnet-vrsc-blueandnet-vrsctestsimultaneously. This is the mechanism that allows a single Caddy instance to route traffic to upstreams on either network based on the requested domain name.
Internet
│
▼
Caddy (mains_blue_caddy-caddy-1)
├─ net-vrsc-blue: 10.201.0.10 (existing)
└─ net-vrsctest: auto-assigned (added by playbook 37)
│
▼
qrcodes.vrsctest.buildwithdreams.com
│
▼
QR Creator container (dev200_qr-qr-1)
at 10.200.0.13:3000 (net-vrsctest only)
Procedure
Step 1 — Clone repository
Delegate: ansible-playbook -i inventory.ini playbooks/34-qrcodes-clone.yml
This playbook:
- Clones
VerusCoin/verus-identity-update-qr-creator-mainto~/verus-identity-update-qr-creator-main - Is idempotent — skips if already present; does
git pullto update
Step 2 — Build Docker image
Delegate: ansible-playbook -i inventory.ini playbooks/35-qrcodes-build.yml
-e qrcodes_rebuild=true (force clean build, bypass Docker cache)
This playbook:
- Builds
buildwithdreams/verus-qr-creator:vrsctest(and tagslatest) - Uses multi-stage Docker build:
node:20-alpinebuilder →node:20-alpineruntime - Runs
yarn install --immutable && yarn buildinside the builder stage - Skips if image exists and
qrcodes_rebuildis not set
Use
-e qrcodes_rebuild=truewhen the source has changed or the image is stale.
Step 3 — Deploy container
Delegate: ansible-playbook -i inventory.ini playbooks/36-qrcodes-deploy.yml
This playbook:
- Removes any existing container (
dev200_qr-qr-1) - Writes
docker-compose.ymltargetingnet-vrsctestat IP10.200.0.13 - Runs
docker compose up -d --force-recreate - Waits for container to appear in
docker ps
Step 4 — Connect Caddy to net-vrsctest
Delegate: ansible-playbook -i inventory.ini playbooks/37-qrcodes-caddy-network.yml
This playbook:
- Verifies Caddy container (
mains_blue_caddy-caddy-1) is running - Runs
docker network connect net-vrsctest <container>to attach Caddy to the VRSCTEST network - Caddy is already on
net-vrsc-blue— after this it is multi-homed on both networks - Is idempotent — skips if already connected
Caddy must be on
net-vrsctestto be able to reach10.200.0.13:3000.
Step 5 — Add Caddy route
Delegate: ansible-playbook -i inventory.ini playbooks/38-qrcodes-caddy-route.yml
This playbook:
- Pre-flight check — verifies Caddy is connected to
net-vrsctestbefore touching anything; aborts if missing - Appends
qrcodes.vrsctest.buildwithdreams.comroute block to the Caddyfile usingblockinfile - Runs
caddy fmt --overwriteto format the file cleanly (no more Caddy warnings) - Validates the Caddyfile before reloading (aborts if invalid)
- Runs
docker exec caddy caddy reloadto apply the new route - Health check — hits the upstream from inside the Caddy container; warns if the QR Creator is unreachable
- Is idempotent — safe to re-run; skips all changes if route already present
Step 6 — Verify
Check the deployed URL:
curl -I https://qrcodes.vrsctest.buildwithdreams.com
Expected: HTTP/2 200 from the QR Creator’s Express server.
To verify container health from the server:
ssh <host> "docker ps | grep qr"
ssh <host> "curl -s http://10.200.0.13:3000/ | head"
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
502 Bad Gateway | Caddy not yet connected to net-vrsctest | Run 37-qrcodes-caddy-network.yml |
Connection refused | QR Creator container not running, or not reachable from Caddy | Run 36-qrcodes-deploy.yml; check docker logs dev200_qr-qr-1; verify with docker exec mains_blue_caddy-caddy-1 wget -q -O - --timeout=5 http://10.200.0.13:3000/ |
curl: (6) Could not resolve host | DNS not propagated | Wait 5-10 minutes for Let’s Encrypt DNS propagation |
| Container keeps restarting | Health check failing | docker logs dev200_qr-qr-1; rebuild with -e qrcodes_rebuild=true |
| Route not responding | Caddyfile stale | Run 38-qrcodes-caddy-route.yml again to reload |
Container restart loop:
docker rm -f dev200_qr-qr-1
# Then re-run Step 3
Rollback
To remove the QR Creator container:
ssh bwd "docker rm -f dev200_qr-qr-1"
To remove the Caddy route (disables the domain only, container keeps running): The route block is managed by playbook 38. To remove it cleanly, edit ~/caddy/Caddyfile and remove the qrcodes.vrsctest.buildwithdreams.com block, then reload:
ssh bwd "docker exec mains_blue_caddy-caddy-1 caddy reload --config /config/caddy/Caddyfile"
To detach Caddy from net-vrsctest:
ssh bwd "docker network disconnect net-vrsctest mains_blue_caddy-caddy-1"
Relevant Playbooks
| # | Playbook | Purpose |
|---|---|---|
34 | 34-qrcodes-clone.yml | Clone repo |
35 | 35-qrcodes-build.yml | Build Docker image |
36 | 36-qrcodes-deploy.yml | Deploy container on net-vrsctest at 10.200.0.13 |
37 | 37-qrcodes-caddy-network.yml | Attach Caddy to net-vrsctest |
38 | 38-qrcodes-caddy-route.yml | Add HTTPS route in Caddy |
08b | 08b-start-vrsctest.yml | Start VRSCTEST daemon (prereq) |
History
- 2026-04-28 — Created. Follows the same IP-numbering convention as VRSC mainnet (
10.201.0.13→10.200.0.13), with a dedicated Caddy route onqrcodes.vrsctest.buildwithdreams.com.