Skip to main content

Bundle v2.30 / v2.31 — Deployment Reliability Fixes

· 3 min read

Bundle v2.30 & v2.31 fix three cascading deployment issues discovered during fresh installs on Hetzner Cloud VMs.

Release

v2.31

March 8, 2026

Deployment Reliability

← Back to Blog

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:

StepAction
6Start Frappe, wait for backend API readiness
6bWait for setup container to exit
7Extract Frappe API token
8Force-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-deployment deleted
  • 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.