From 1acc89c486e284e64f963edb0628d0fff2c7c2e2 Mon Sep 17 00:00:00 2001 From: ZdenekSrotyr Date: Tue, 21 Apr 2026 16:54:18 +0200 Subject: [PATCH] fix(ci): move bind-mount of /data to separate overlay, fix CI smoke test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The CI smoke test failed because docker-compose.prod.yml forced a bind mount to /data on the host — which doesn't exist on GitHub runners. Split the bind mount into docker-compose.host-mount.yml, which is only composed by the VM startup script (/data exists there, mounted from the persistent disk). CI continues to use the default named volume. Module startup script + auto-upgrade cron now compose all three: -f docker-compose.yml -f docker-compose.prod.yml -f docker-compose.host-mount.yml --- docker-compose.host-mount.yml | 21 +++++++++++++++++++ docker-compose.prod.yml | 20 ++++-------------- .../customer-instance/startup-script.sh.tpl | 13 ++++++++---- 3 files changed, 34 insertions(+), 20 deletions(-) create mode 100644 docker-compose.host-mount.yml diff --git a/docker-compose.host-mount.yml b/docker-compose.host-mount.yml new file mode 100644 index 0000000..4ab2820 --- /dev/null +++ b/docker-compose.host-mount.yml @@ -0,0 +1,21 @@ +# Bind-mount overlay — replaces the `data` named volume with a bind mount +# to /data on the host. +# +# Use this when /data is a persistent disk mounted by the VM startup script, +# so Agnes data lives on the PD (not on the boot disk's Docker volume). +# +# Usage (combined with docker-compose.prod.yml): +# docker compose \ +# -f docker-compose.yml \ +# -f docker-compose.prod.yml \ +# -f docker-compose.host-mount.yml \ +# up -d +# +# Do NOT use this overlay in CI — /data does not exist on GitHub runners. +volumes: + data: + driver: local + driver_opts: + type: none + o: bind + device: /data diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 614acb5..3fab1da 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -1,9 +1,9 @@ -# Production override — uses pre-built GHCR image instead of local build, -# and binds the `data` volume to /data on the host (so persistent-disk mounts -# at /data are used by all services). -# +# Production override — uses pre-built GHCR image instead of local build. # Usage: docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d # Override tag: AGNES_TAG=stable-2026.04.3 docker compose -f ... up -d +# +# For persistent-disk-backed /data on GCE, compose this overlay with +# docker-compose.host-mount.yml — which binds the `data` named volume to /data. services: app: image: ghcr.io/keboola/agnes-the-ai-analyst:${AGNES_TAG:-stable} @@ -19,15 +19,3 @@ services: image: ghcr.io/keboola/agnes-the-ai-analyst:${AGNES_TAG:-stable} session-collector: image: ghcr.io/keboola/agnes-the-ai-analyst:${AGNES_TAG:-stable} - -# Override the `data` named volume to bind-mount /data from the host. -# This ensures a persistent disk mounted at /data (by Terraform startup -# script) is the actual backing store, not a Docker-managed volume on the -# boot disk. -volumes: - data: - driver: local - driver_opts: - type: none - o: bind - device: /data diff --git a/infra/modules/customer-instance/startup-script.sh.tpl b/infra/modules/customer-instance/startup-script.sh.tpl index 39247eb..3ffd2fb 100644 --- a/infra/modules/customer-instance/startup-script.sh.tpl +++ b/infra/modules/customer-instance/startup-script.sh.tpl @@ -46,6 +46,8 @@ cd "$APP_DIR" # Fetch minimal docker-compose from public repo (main branch — stable) curl -fsSL "https://raw.githubusercontent.com/keboola/agnes-the-ai-analyst/main/docker-compose.yml" -o docker-compose.yml curl -fsSL "https://raw.githubusercontent.com/keboola/agnes-the-ai-analyst/main/docker-compose.prod.yml" -o docker-compose.prod.yml +# Overlay which binds `data` volume to host /data (persistent disk mounted above) +curl -fsSL "https://raw.githubusercontent.com/keboola/agnes-the-ai-analyst/main/docker-compose.host-mount.yml" -o docker-compose.host-mount.yml # TLS overlay (Caddy + Let's Encrypt) — jen pokud potřeba if [ "$TLS_MODE" = "caddy" ] && [ -n "$DOMAIN" ]; then @@ -79,8 +81,10 @@ if [ "$TLS_MODE" = "caddy" ] && [ -n "$DOMAIN" ]; then COMPOSE_PROFILES_ARG="--profile tls" fi -docker compose -f docker-compose.yml -f docker-compose.prod.yml $COMPOSE_PROFILES_ARG pull -docker compose -f docker-compose.yml -f docker-compose.prod.yml $COMPOSE_PROFILES_ARG up -d +COMPOSE_FILES="-f docker-compose.yml -f docker-compose.prod.yml -f docker-compose.host-mount.yml" + +docker compose $COMPOSE_FILES $COMPOSE_PROFILES_ARG pull +docker compose $COMPOSE_FILES $COMPOSE_PROFILES_ARG up -d # --- 6. Auto-upgrade via cron (pullne nový tag každých 5 min) --- if [ "$UPGRADE_MODE" = "auto" ]; then @@ -89,12 +93,13 @@ if [ "$UPGRADE_MODE" = "auto" ]; then # Spouští se z cronu — pullne nový image, pokud je, a restartne containers. set -euo pipefail cd /opt/agnes +COMPOSE_FILES="-f docker-compose.yml -f docker-compose.prod.yml -f docker-compose.host-mount.yml" BEFORE=$(docker images --no-trunc --format '{{.Digest}}' ghcr.io/keboola/agnes-the-ai-analyst:$${AGNES_TAG:-stable} | head -1) -docker compose -f docker-compose.yml -f docker-compose.prod.yml pull >/dev/null 2>&1 +docker compose $COMPOSE_FILES pull >/dev/null 2>&1 AFTER=$(docker images --no-trunc --format '{{.Digest}}' ghcr.io/keboola/agnes-the-ai-analyst:$${AGNES_TAG:-stable} | head -1) if [ "$BEFORE" != "$AFTER" ]; then echo "$(date): new image digest — recreating containers" - docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d + docker compose $COMPOSE_FILES up -d docker image prune -f >/dev/null 2>&1 fi SCRIPTEOF