fix(gancio): pre-start config-init sidecar prevents restart loop
Gancio refuses to start when its DB has tables but the data volume has no
config.json ("Non empty db! Please move your current db elsewhere than retry"),
which produces an infinite restart loop. This hit production tenants bnkops
and trbh (>1200 restart cycles each) — proximate cause was a missing
config.json in changemakerlite_gancio-data with the DB fully populated.
Add gancio-config-init alpine sidecar that runs on every `up`:
- no-op when config.json exists
- regenerates from .env when missing (1000:1000 ownership)
- gancio service now depends on its service_completed_successfully
Also harden verify_gancio_config in upgrade.sh to error loudly when
multiple gancio-data volumes match (silent head -1 could pick the wrong
one after a compose project rename).
This commit is contained in:
parent
3f6102cf6d
commit
a82e95946b
@ -976,6 +976,39 @@ services:
|
|||||||
retries: 10
|
retries: 10
|
||||||
start_period: 30s
|
start_period: 30s
|
||||||
|
|
||||||
|
# Gancio Config Init — Writes /home/node/data/config.json from .env if missing.
|
||||||
|
# Gancio refuses to start when its DB has tables but the data volume has no
|
||||||
|
# config.json ("Non empty db! Please move your current db elsewhere than retry"),
|
||||||
|
# which causes an infinite restart loop. This sidecar runs on every `up` and is
|
||||||
|
# a no-op when config.json is already present. See docker-compose.yml for the
|
||||||
|
# full rationale; the two files must stay in parity per scripts/validate-compose-parity.sh.
|
||||||
|
gancio-config-init:
|
||||||
|
image: ${GITEA_REGISTRY:-gitea.bnkops.com/admin}/alpine:3
|
||||||
|
container_name: gancio-config-init
|
||||||
|
restart: "no"
|
||||||
|
volumes:
|
||||||
|
- gancio-data:/data
|
||||||
|
environment:
|
||||||
|
- GANCIO_BASE_URL=${GANCIO_BASE_URL:-https://events.cmlite.org}
|
||||||
|
- V2_POSTGRES_USER=${V2_POSTGRES_USER:-changemaker}
|
||||||
|
- V2_POSTGRES_PASSWORD=${V2_POSTGRES_PASSWORD:?V2_POSTGRES_PASSWORD must be set in .env}
|
||||||
|
entrypoint: ["sh", "-c"]
|
||||||
|
command:
|
||||||
|
- |
|
||||||
|
set -e
|
||||||
|
if [ -s /data/config.json ]; then
|
||||||
|
echo "Gancio config.json present — skipping"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
echo "Gancio config.json missing — regenerating from .env"
|
||||||
|
printf '{"baseurl":"%s","server":{"host":"0.0.0.0","port":13120},"db":{"dialect":"postgres","host":"changemaker-v2-postgres","port":5432,"database":"gancio","username":"%s","password":"%s"}}' \
|
||||||
|
"$$GANCIO_BASE_URL" "$$V2_POSTGRES_USER" "$$V2_POSTGRES_PASSWORD" > /data/config.json
|
||||||
|
chown 1000:1000 /data/config.json
|
||||||
|
echo "Gancio config.json regenerated"
|
||||||
|
logging: *default-logging
|
||||||
|
networks:
|
||||||
|
- changemaker-lite
|
||||||
|
|
||||||
# Gancio — Event management platform (uses shared PostgreSQL)
|
# Gancio — Event management platform (uses shared PostgreSQL)
|
||||||
gancio:
|
gancio:
|
||||||
image: ${GITEA_REGISTRY:-gitea.bnkops.com/admin}/gancio:1.28.2
|
image: ${GITEA_REGISTRY:-gitea.bnkops.com/admin}/gancio:1.28.2
|
||||||
@ -984,6 +1017,8 @@ services:
|
|||||||
depends_on:
|
depends_on:
|
||||||
v2-postgres:
|
v2-postgres:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
|
gancio-config-init:
|
||||||
|
condition: service_completed_successfully
|
||||||
ports:
|
ports:
|
||||||
- "127.0.0.1:${GANCIO_PORT:-8092}:13120"
|
- "127.0.0.1:${GANCIO_PORT:-8092}:13120"
|
||||||
healthcheck:
|
healthcheck:
|
||||||
|
|||||||
@ -998,6 +998,40 @@ services:
|
|||||||
start_period: 30s
|
start_period: 30s
|
||||||
|
|
||||||
# Gancio — Event management platform (uses shared PostgreSQL)
|
# Gancio — Event management platform (uses shared PostgreSQL)
|
||||||
|
# Gancio Config Init — Writes /home/node/data/config.json from .env if missing.
|
||||||
|
# Gancio refuses to start when its DB has tables but the data volume has no
|
||||||
|
# config.json ("Non empty db! Please move your current db elsewhere than retry"),
|
||||||
|
# which causes an infinite restart loop. This sidecar runs on every `up` and is
|
||||||
|
# a no-op when config.json is already present. Reversible: removing this
|
||||||
|
# service has no effect on healthy stacks; it only matters when the volume
|
||||||
|
# loses config.json (volume rename, partial restore, manual volume rm, etc.).
|
||||||
|
gancio-config-init:
|
||||||
|
image: alpine:3
|
||||||
|
container_name: gancio-config-init
|
||||||
|
restart: "no"
|
||||||
|
volumes:
|
||||||
|
- gancio-data:/data
|
||||||
|
environment:
|
||||||
|
- GANCIO_BASE_URL=${GANCIO_BASE_URL:-https://events.cmlite.org}
|
||||||
|
- V2_POSTGRES_USER=${V2_POSTGRES_USER:-changemaker}
|
||||||
|
- V2_POSTGRES_PASSWORD=${V2_POSTGRES_PASSWORD:?V2_POSTGRES_PASSWORD must be set in .env}
|
||||||
|
entrypoint: ["sh", "-c"]
|
||||||
|
command:
|
||||||
|
- |
|
||||||
|
set -e
|
||||||
|
if [ -s /data/config.json ]; then
|
||||||
|
echo "Gancio config.json present — skipping"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
echo "Gancio config.json missing — regenerating from .env"
|
||||||
|
printf '{"baseurl":"%s","server":{"host":"0.0.0.0","port":13120},"db":{"dialect":"postgres","host":"changemaker-v2-postgres","port":5432,"database":"gancio","username":"%s","password":"%s"}}' \
|
||||||
|
"$$GANCIO_BASE_URL" "$$V2_POSTGRES_USER" "$$V2_POSTGRES_PASSWORD" > /data/config.json
|
||||||
|
chown 1000:1000 /data/config.json
|
||||||
|
echo "Gancio config.json regenerated"
|
||||||
|
logging: *default-logging
|
||||||
|
networks:
|
||||||
|
- changemaker-lite
|
||||||
|
|
||||||
gancio:
|
gancio:
|
||||||
image: cisti/gancio:1.28.2
|
image: cisti/gancio:1.28.2
|
||||||
container_name: gancio-changemaker
|
container_name: gancio-changemaker
|
||||||
@ -1005,6 +1039,8 @@ services:
|
|||||||
depends_on:
|
depends_on:
|
||||||
v2-postgres:
|
v2-postgres:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
|
gancio-config-init:
|
||||||
|
condition: service_completed_successfully
|
||||||
ports:
|
ports:
|
||||||
- "127.0.0.1:${GANCIO_PORT:-8092}:13120"
|
- "127.0.0.1:${GANCIO_PORT:-8092}:13120"
|
||||||
healthcheck:
|
healthcheck:
|
||||||
|
|||||||
@ -188,11 +188,22 @@ restore_user_paths() {
|
|||||||
# "Non empty db! Please move your current db elsewhere than retry."
|
# "Non empty db! Please move your current db elsewhere than retry."
|
||||||
# This regenerates config.json from .env vars when missing.
|
# This regenerates config.json from .env vars when missing.
|
||||||
verify_gancio_config() {
|
verify_gancio_config() {
|
||||||
local gancio_volume
|
# Note: as of the gancio-config-init sidecar in docker-compose{,prod}.yml,
|
||||||
gancio_volume="$(docker volume ls --format '{{.Name}}' | grep 'gancio-data' | head -1 || true)"
|
# config.json is regenerated automatically on every `up`. This function is
|
||||||
if [[ -z "$gancio_volume" ]]; then
|
# kept as belt-and-braces for the upgrade flow specifically (e.g. so the
|
||||||
|
# check happens before the compose-up rather than at compose-up time, and
|
||||||
|
# so operators see explicit log output during upgrade).
|
||||||
|
local matches
|
||||||
|
matches="$(docker volume ls --format '{{.Name}}' | grep 'gancio-data' || true)"
|
||||||
|
local count
|
||||||
|
count=$(printf '%s\n' "$matches" | grep -c '.' || true)
|
||||||
|
if [[ "$count" -eq 0 ]]; then
|
||||||
return # No gancio volume exists yet; first run will handle it
|
return # No gancio volume exists yet; first run will handle it
|
||||||
fi
|
fi
|
||||||
|
if [[ "$count" -gt 1 ]]; then
|
||||||
|
error "Multiple gancio-data volumes found — refusing to guess. Resolve manually:\n$matches"
|
||||||
|
fi
|
||||||
|
local gancio_volume="$matches"
|
||||||
|
|
||||||
# Check if config.json exists and is non-empty
|
# Check if config.json exists and is non-empty
|
||||||
if docker run --rm -v "${gancio_volume}:/data" alpine test -s /data/config.json 2>/dev/null; then
|
if docker run --rm -v "${gancio_volume}:/data" alpine test -s /data/config.json 2>/dev/null; then
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user