diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 3e5b9c5..c5097e0 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -11,13 +11,20 @@ updates: github-actions: patterns: ["*"] - # Tracks the pinned image tags in docker-compose.yml directly (GA since - # Feb 2025) and opens a PR when n8n/Baserow/Postgres/Caddy cut a new - # release. - - package-ecosystem: "docker" + # Tracks the pinned image tags in docker-compose.yml. Dependabot's `docker` + # ecosystem only reads Dockerfiles; compose files need the separate + # `docker-compose` ecosystem (GA Feb 2025). With `docker` here no image PR + # ever opened and the pins fell behind. + - package-ecosystem: "docker-compose" directory: "/" schedule: interval: "weekly" groups: - docker: + docker-compose: patterns: ["*"] + update-types: ["minor", "patch"] + ignore: + # A Postgres major needs pg_upgrade or a dump/restore on the existing + # volume; as a plain tag bump it would leave users' stacks unable to boot. + - dependency-name: "postgres" + update-types: ["version-update:semver-major"] diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index 3d0d225..7e25c59 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -19,7 +19,28 @@ concurrency: # scanner (confirmed against its own issue tracker), so claiming IaC # coverage here would be inaccurate. jobs: + # Scans whatever docker-compose.yml pins. A hardcoded copy of the tags here + # drifted from the compose file, so a Dependabot image bump went unscanned. + images: + runs-on: ubuntu-latest + permissions: + contents: read + outputs: + matrix: ${{ steps.matrix.outputs.matrix }} + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + + - name: List pinned images + id: matrix + run: | + cp .env.example .env + matrix=$(docker compose config --images 2>/dev/null | sort -u \ + | jq -R -s -c 'split("\n") | map(select(length > 0)) | map({image: ., name: (split("/") | last | split(":") | first)})') + echo "$matrix" + echo "matrix=$matrix" >> "$GITHUB_OUTPUT" + trivy: + needs: images runs-on: ubuntu-latest permissions: contents: read @@ -27,15 +48,7 @@ jobs: strategy: fail-fast: false matrix: - include: - - name: n8n - image: n8nio/n8n:2.35.7 - - name: baserow - image: baserow/baserow:2.3.3 - - name: postgres - image: postgres:15.19-alpine3.24 - - name: caddy - image: caddy:2.11.4-alpine + include: ${{ fromJSON(needs.images.outputs.matrix) }} steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 diff --git a/Makefile b/Makefile index 067f7c5..2fbe32d 100644 --- a/Makefile +++ b/Makefile @@ -57,7 +57,7 @@ backup-test: bash scripts/backup-drill.sh security-scan: - @for img in n8nio/n8n:2.35.7 baserow/baserow:2.3.3 postgres:15.19-alpine3.24 caddy:2.11.4-alpine; do \ + @for img in $$(docker compose config --images 2>/dev/null | sort -u); do \ echo "--- $$img ---"; \ trivy image --severity CRITICAL,HIGH --ignore-unfixed "$$img"; \ done diff --git a/README.md b/README.md index e229d80..94ae947 100644 --- a/README.md +++ b/README.md @@ -32,10 +32,10 @@ Caddy terminates TLS and proxies to n8n and Baserow over `proxy-network`. Neithe | Service | Image | Purpose | Default URL | |------------|-----------------------------------|-------------------------------------|-----------------------------------| -| n8n | `n8nio/n8n:2.35.7` | Workflow automation | `https://n8n.yourdomain.com` | -| Baserow | `baserow/baserow:2.3.3` | No-code database / spreadsheet UI | `https://baserow.yourdomain.com` | +| n8n | `n8nio/n8n:2.44.4` | Workflow automation | `https://n8n.yourdomain.com` | +| Baserow | `baserow/baserow:2.4.1` | No-code database / spreadsheet UI | `https://baserow.yourdomain.com` | | PostgreSQL | `postgres:15.19-alpine3.24` | Shared database backend | Internal only | -| Caddy | `caddy:2.11.4-alpine` | Reverse proxy + automatic TLS | Handles 80/443 | +| Caddy | `caddy:2.11.7-alpine` | Reverse proxy + automatic TLS | Handles 80/443 | All four are version-pinned rather than `:latest` — [Dependabot](.github/dependabot.yml) opens a PR when a new release lands, so upgrades are reviewed, not silent. See [Updating Services](docs/updating-services.md). diff --git a/docker-compose.yml b/docker-compose.yml index 43e25b8..f915703 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -45,7 +45,7 @@ services: - backend-network n8n: - image: n8nio/n8n:2.35.7 + image: n8nio/n8n:2.44.4 restart: unless-stopped depends_on: postgres: @@ -92,7 +92,7 @@ services: - backend-network baserow: - image: baserow/baserow:2.3.3 + image: baserow/baserow:2.4.1 restart: unless-stopped depends_on: postgres: @@ -143,7 +143,7 @@ services: - backend-network caddy: - image: caddy:2.11.4-alpine + image: caddy:2.11.7-alpine restart: unless-stopped ports: - "80:80" diff --git a/scripts/wait-for-healthy.sh b/scripts/wait-for-healthy.sh index b2beeb7..bd9867c 100755 --- a/scripts/wait-for-healthy.sh +++ b/scripts/wait-for-healthy.sh @@ -11,7 +11,7 @@ set -e # resource contention during first-boot migrations. # # Also deliberately does NOT `docker compose exec` into n8n/Baserow to run -# their own healthcheck command: baserow/baserow:2.3.3 has no `wget` binary +# their own healthcheck command: baserow/baserow (checked on 2.3.3; re-check after a bump) has no `wget` binary # anywhere in $PATH at all (confirmed at the OCI runtime level, not a shell # quirk) — docker-compose.yml's own `wget`-based HEALTHCHECK for that # service has never actually been able to run. Instead this curls each