Bundle v2.30 / v2.31 — Deployment Reliability Fixes
Bundle v2.30 & v2.31 fix three cascading deployment issues discovered during fresh installs on Hetzner Cloud VMs.
What Was Fixed
Three cascading issues were discovered when deploying bundle v2.29 on a clean Hetzner Cloud VM (77.42.72.243). Each fix builds on the previous one:
1. Token Race Condition (v2.30)
Problem: zynctl.sh Step 7 extracted the Frappe API token from setup container logs before the setup container had finished generating it. This resulted in a stale or empty token, causing ctms-init to fail with 401 UNAUTHORIZED on 13 of 34 DocTypes.
Fix: Added Step 6b — a polling loop that waits for frappe-marley-health-setup-1 to reach exited status before proceeding to token extraction. Polls every 5 seconds with a 10-minute timeout.
2. Missing Item Groups (v2.30)
Problem: ctms-init Stage 4 created Items with item_group="Laboratory" but never created the "Laboratory" Item Group first. Frappe returned 417 EXPECTATION FAILED.
Fix: Added seed_item_groups() to frappe_seed_master_data.py — creates "Laboratory" and "Drug" Item Groups before seeding Items. Stage 4 record count updated from 140 → 142.
3. Stale Docker Image Cache (v2.31)
Problem: During the v2.30 deployment test, Docker reused a locally cached ctms-init:latest (v1.10) instead of pulling the newly published v1.11, so the Item Group fix was never applied.
Fix: zynctl.sh now runs docker compose pull ctms-init before docker compose up ctms-init in both the deploy and update functions.
Deployment Steps Update
The zynctl.sh deploy sequence now includes Step 6b between Frappe startup and token extraction:
| Step | Action |
|---|---|
| 6 | Start Frappe, wait for backend API readiness |
| 6b | Wait for setup container to exit |
| 7 | Extract Frappe API token |
| 8 | Force-pull & run CTMS Init |
Verified On
- Server: 77.42.72.243 (Hetzner Cloud, Rocky Linux 10)
- Full destroy → deploy cycle: All containers removed, all volumes pruned,
/opt/ctms-deploymentdeleted - Result: All 5 ctms-init stages passed, all 10 services healthy, all master data verified via API
Upgrade Path
Download the latest bundle from GitHub Releases:
# On an existing deployment — just update zynctl.sh
cd /opt/ctms-deployment
curl -LO https://github.com/zynomilabs/ctms.devops/releases/download/bundle-v2.31.20260308/zynctl-bundle-2.31.20260308.tar.gz
tar xzf zynctl-bundle-2.31.20260308.tar.gz
cp zynctl-bundle-2.31.20260308/zynctl.sh .
# Pull the fixed ctms-init image
docker pull zynomi/ctms-init:latest
# Re-run provisioning (idempotent — skips existing records)
DC="docker compose -f docker-compose.yml -f docker-compose.prod.yml --env-file .env.production"
$DC --profile init run --rm ctms-init
For fresh deployments, just use the v2.31 bundle — all fixes are included.
For complete documentation, visit our docs site.
