Kako radi deploy verb (Coolify mod)?¶
TL;DR
Dvofazni Coolify deploy: Phase 1 sync-uje Infisical+Coolify za
SVE servise (image_tag + secrets), Phase 2 deploy-uje jedan po
jedan servis. Prije svake mutacije drži distributed lock na Coolify
UUID. Default failure_policy: soft (per-service fail ne aborta
pipeline); opt-in strict za fail-closed.
Dvofazni tok¶
deploy (Phase 1 — sync ALL):
za svaki services[i]:
akviziraj lock[coolify_uuid_i]
sync secrets (Infisical → Coolify env)
sync image_tag (Infisical folder ili direkt env var)
otpusti lock
deploy (Phase 2 — deploy per service):
za svaki services[i]:
akviziraj lock[coolify_uuid_i]
Coolify redeploy sa novim image_tag
Coolify health check (--wait po defaultu)
otpusti lock
Zašto dvofazno: Phase 1 garantuje da su SVI dependencies synced-ani prije nego Phase 2 krene da deploy-uje. Ako servis A zavisi od servisa B, B-ov novi tag je već u Coolify env-u kad A počne.
image_tag sync (ključna konfiguracija)¶
services.<name>.deploy.image_tag u services.json kontroliše kuda
se image_tag piše:
deploy:
image_tag:
var_name: IMAGE_TAG # default
sync:
coolify_env: false # default: ne piši direkt u Coolify env
infisical:
folder: /production # piši u ovaj Infisical folder
sync.coolify_env: true(opt-in): piše image_tag direktno u Coolify env kao<var_name>=<tag>. Zahtijeva deploy se ne iz Infisical-a.sync.infisical.folder: piše u Infisical secret folder; zatim Coolify čita iz Infisical-a (eksternog agenta).- Nema
sync: silent no-op. Coolify čita${IMAGE_TAG}iz eksternog izvora (vanci/).
Coolify docker_compose_raw koristi ${IMAGE_TAG} (ili var_name)
da pull-uje tačnu sliku.
Lock kontrakt (load-bearing)¶
Svaka Coolify mutacija drži ci/lock/:
- F35 — dvofazni lock (Phase 1 lock, Phase 2 lock, između otpusti)
- F38 — deploy/mobile folder split
- F40 — acquire budget (timeout)
Bez locka dva paralelna pipeline-a mogu međusobno prepisati
secrets. Detalji: ci/lock/CLAUDE.md.
Failure policy¶
soft(default): per-service fail ne aborta pipeline. Notify verb i dalje javlja (sa status=failed). Cleanup se izvršava.strict(opt-in): prvi fail aborta ceo deploy. Exit code ≠ 0. Za servise gdje half-deployed state nije prihvatljiv.
Step-by-step (šta CI radi)¶
- Učitaj
ci-state.json(koji servisi, koji tagovi, koji env). - Akviziraj globalni Phase-1 lock.
- Phase 1 — sync loop: za svaki servis:
- Akviziraj per-UUID lock.
- Sync secrets u Coolify env (ako
deploy.secrets.infisical.folder). - Sync image_tag (ako
deploy.image_tag.sync). - Otpusti lock.
- Otpusti Phase-1 lock.
- Akviziraj globalni Phase-2 lock.
- Phase 2 — deploy loop: za svaki servis:
- Akviziraj per-UUID lock.
- Pokreni Coolify redeploy sa novim
IMAGE_TAG. - Čekaj health check (
--wait;HEALTH_CHECKMake var za custom). - Zapiši status u
ci-state.json. - Otpusti lock.
- Otpusti Phase-2 lock.
Failure modes¶
- Coolify 401/403 →
VendorAuthError(exit 2). Token loš, NE retry. - Lock timeout (F40 prekoračen) →
ci/lockexit 1. Drugi pipeline drži lock; čekaj ili eskaliraj. - Coolify 5xx → soft fail + retry logika; strict aborta.
- Image pull fail (registar nedostupan) → 5xx tretman.
Vidi i¶
v7.md§2 "Kako radi"01-bump.md— štabumpzapisuje u state03-release/01-two-patterns.md— release invariant +--envci/verbs/deploy.py— implementacijaci/verbs/CLAUDE.md— svi verbs + failure policyci/coolify/CLAUDE.md— Coolify API klijentci/lock/CLAUDE.md— distributed lock