diff --git a/.github/workflows/image-audit.yml b/.github/workflows/image-audit.yml index 9fe2bde227..8b43c30fe8 100644 --- a/.github/workflows/image-audit.yml +++ b/.github/workflows/image-audit.yml @@ -2,17 +2,18 @@ name: Image audit # bun audit sees only the npm dependencies. This scan reads the published panel # image: its Debian packages, the Go binaries of the bundled tools (Docker CLI, -# rclone, Railpack, pack) and the npm packages inside it. It fails on critical -# and high findings that already have a fix; .trivyignore.yaml lists the ones -# still waiting for a tool release. GitHub notifies the person who last changed -# the cron line when a scheduled run fails. +# rclone, Railpack, pack) and the npm packages inside it. It also reads the +# pinned Traefik, Postgres and Redis images that run next to the panel and on +# servers. It fails on critical and high findings that already have a fix; +# .trivyignore.yaml lists the ones still waiting for a release. GitHub notifies +# the person who last changed the cron line when a scheduled run fails. on: schedule: - cron: "53 5 * * 1" workflow_dispatch: inputs: image: - description: Image to scan + description: Panel image to scan type: string default: ghcr.io/agenthits/dokploy:agenthits-dev @@ -27,18 +28,46 @@ env: jobs: scan: - name: image audit + name: image audit (${{ matrix.name }}) runs-on: ubuntu-24.04 timeout-minutes: 20 + strategy: + fail-fast: false + matrix: + # component-versions-sync.test.ts keeps the Traefik, Postgres and Redis + # tags equal to PINNED_VERSIONS. + include: + - name: panel + image: ghcr.io/agenthits/dokploy:agenthits-dev + - name: traefik + image: traefik:v3.7.16 + - name: postgres + image: postgres:18.6 + # gosu only switches to the postgres user when the container + # starts. postgres:18.6 still ships gosu 1.19, built with Go 1.24.6; + # its 26 Go stdlib advisories would each need an entry in + # .trivyignore.yaml. gosu 1.20 came out on 2026-10-25, so the skip + # ends with the date below and the scan reports gosu again. + skip-files: usr/local/bin/gosu + skip-until: "2026-11-27" + - name: redis + image: redis:8.10.2 steps: - uses: actions/checkout@v7 with: persist-credentials: false - name: Scan image env: - IMAGE: ${{ inputs.image || 'ghcr.io/agenthits/dokploy:agenthits-dev' }} + IMAGE: ${{ matrix.name == 'panel' && inputs.image || matrix.image }} + SKIP_FILES: ${{ matrix.skip-files }} + SKIP_UNTIL: ${{ matrix.skip-until }} run: | + skip=() + if [ -n "$SKIP_FILES" ] && [[ "$(date -u +%F)" < "$SKIP_UNTIL" ]]; then + skip=(--skip-files "$SKIP_FILES") + fi docker run --rm -v "$PWD:/src:ro" -w /src "$TRIVY_IMAGE" image \ - --image-src remote --scanners vuln --severity CRITICAL,HIGH \ - --ignore-unfixed --ignorefile .trivyignore.yaml --exit-code 1 \ - --no-progress "$IMAGE" + --image-src remote --platform linux/amd64 --scanners vuln \ + --severity CRITICAL,HIGH --ignore-unfixed \ + --ignorefile .trivyignore.yaml --exit-code 1 --no-progress \ + "${skip[@]}" "$IMAGE" diff --git a/.trivyignore.yaml b/.trivyignore.yaml index f38e7226d8..177b4f864a 100644 --- a/.trivyignore.yaml +++ b/.trivyignore.yaml @@ -1,4 +1,5 @@ -# Fixable findings in bundled tools whose latest release still carries them. +# Fixable findings in bundled tools and pinned images whose latest release +# still carries them. # Each entry expires, so the image audit fails again and the tool gets checked # for a new release. vulnerabilities: @@ -19,3 +20,8 @@ vulnerabilities: - usr/libexec/docker/cli-plugins/docker-buildx statement: buildx 0.38.1, the latest release, uses moby/go-archive 0.2.0. expired_at: 2026-11-27 + - id: CVE-2026-116587 + paths: + - usr/local/bin/traefik + statement: Traefik 3.7.16, the latest release, uses go-jose 4.1.5; the fix is in 4.1.6. + expired_at: 2026-11-27 diff --git a/CLAUDE.md b/CLAUDE.md index 87744d8a95..99cad9b28e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -27,4 +27,4 @@ One GitHub release `agenthits-vX.Y.Z` covers a batch of work, not a single PR (o - The one-day age is `minimumReleaseAge` in `bunfig.toml` and `MIN_RELEASE_AGE` in the workflow; change both together. - A commit pushed to the branch of the open PR stops its daily rebuild until the PR is merged or closed. - `.github/workflows/dependency-audit.yml` runs `bun audit` every Monday for advisories published between updates. -- `bun audit` does not see the image. Trivy scans the published `agenthits-dev` image every Monday (`.github/workflows/image-audit.yml`) and the image a PR builds (`bun-migration-docker-check.yml`). Both fail on critical and high findings that have a fix in Debian packages, in the Go binaries of the bundled tools (Docker CLI, rclone, Railpack, pack) or in npm packages inside the image. `.trivyignore.yaml` holds findings whose latest tool release still carries them; each entry expires, so the audit fails again and the tool gets rechecked. Trivy is pinned by digest in both workflows; move them together. +- `bun audit` does not see the image. Trivy scans the published `agenthits-dev` image and the pinned Traefik, Postgres and Redis images every Monday (`.github/workflows/image-audit.yml`), and the image a PR builds (`bun-migration-docker-check.yml`). Both fail on critical and high findings that have a fix in Debian packages, in the Go binaries of the bundled tools (Docker CLI, rclone, Railpack, pack) or in npm packages inside the image. `.trivyignore.yaml` holds findings whose latest tool release still carries them; each entry expires, so the audit fails again and the tool gets rechecked. Trivy is pinned by digest in both workflows; move them together. diff --git a/apps/dokploy/__test__/server/component-versions-sync.test.ts b/apps/dokploy/__test__/server/component-versions-sync.test.ts index d1148c7a5b..ca0997a107 100644 --- a/apps/dokploy/__test__/server/component-versions-sync.test.ts +++ b/apps/dokploy/__test__/server/component-versions-sync.test.ts @@ -121,6 +121,22 @@ describe("CI workflow", () => { }); }); +describe("image audit workflow", () => { + const audit = read(".github/workflows/image-audit.yml"); + + it("scans the pinned Traefik", () => { + expect(pinIn(audit, /image: traefik:v(\S+)/)).toBe(PINNED_VERSIONS.traefik); + }); + it("scans the pinned Postgres", () => { + expect(pinIn(audit, /image: postgres:(\S+)/)).toBe( + PINNED_VERSIONS.postgres, + ); + }); + it("scans the pinned Redis", () => { + expect(pinIn(audit, /image: redis:(\S+)/)).toBe(PINNED_VERSIONS.redis); + }); +}); + describe("application Railpack picker", () => { const picker = read( "apps/dokploy/components/dashboard/application/build/show.tsx", diff --git a/docs/agenthits-install.md b/docs/agenthits-install.md index 113e2f906e..b5abb0f381 100644 --- a/docs/agenthits-install.md +++ b/docs/agenthits-install.md @@ -48,7 +48,7 @@ Installer сам определяет систему: ```text Dokploy: ghcr.io/agenthits/dokploy:agenthits-dev -Traefik: traefik:v3.7.14 +Traefik: traefik:v3.7.16 Postgres: postgres:18.6 Redis: redis:8.10.2 ``` diff --git a/docs/server-components-update.md b/docs/server-components-update.md index 4aa4201e50..3a66769282 100644 --- a/docs/server-components-update.md +++ b/docs/server-components-update.md @@ -6,6 +6,7 @@ - установщик панели `install-agenthits.sh` (значения по умолчанию, плюс Nixpacks, Railpack, pack и RClone на хосте панели); - образ панели `Dockerfile` (Docker, RClone, Railpack, pack); - CI `.github/workflows/pull-request.yml` (Nixpacks, Railpack); +- еженедельный аудит образов `.github/workflows/image-audit.yml` (Traefik, Postgres, Redis); - список версий Railpack в форме приложения (значение по умолчанию и список). Тест `apps/dokploy/__test__/server/component-versions-sync.test.ts` сверяет каждый из этих файлов с `PINNED_VERSIONS` и падает при расхождении. @@ -16,7 +17,7 @@ |---|---|---| | Node.js (базовый образ панели и CI) | 26.12.1 | `node:26.12.1-bookworm-slim`, последний релиз; ветка 26 — LTS с 2026-10-28 | | Docker Engine | 29.9.2 | docker-ce для noble и resolute, amd64 и arm64; в образе панели только docker-ce-cli для bookworm | -| Traefik | 3.7.14 | последний стабильный релиз (GitHub), образ `traefik:v3.7.14` | +| Traefik | 3.7.16 | последний стабильный релиз (GitHub), образ `traefik:v3.7.16` | | Postgres (база панели) | 18.6 | `postgres:18.6`, более новых тегов 18.x нет | | Redis (база панели) | 8.10.2 | `redis:8.10.2`, более новых тегов 8.10.x нет | | Nixpacks | 1.41.0 | последний релиз | @@ -39,7 +40,7 @@ Postgres и Redis относятся к базе панели. На сервер ## Как поменять версию 1. Поменять значение в `PINNED_VERSIONS` (`component-versions.ts`). Для Traefik также можно переопределить переменной окружения `TRAEFIK_VERSION`, но для одинаковой установки этого делать не стоит. -2. Поменять то же значение в `install-agenthits.sh` (значения по умолчанию), `Dockerfile` (ARG) и `.github/workflows/pull-request.yml`. Если тест не проходит, какой-то файл остался со старым значением. +2. Поменять то же значение в `install-agenthits.sh` (значения по умолчанию), `Dockerfile` (ARG), `.github/workflows/pull-request.yml` и `.github/workflows/image-audit.yml`. Если тест не проходит, какой-то файл остался со старым значением. 3. Выпустить панель обычным путём: PR, merge, образ. 4. На каждом сервере нажать Components → Update. diff --git a/docs/server-hardening.md b/docs/server-hardening.md index 21254213fb..366de31a2a 100644 --- a/docs/server-hardening.md +++ b/docs/server-hardening.md @@ -12,7 +12,7 @@ | `--harden` | все три | Все три флага сразу. | | — | `DOKPLOY_SERVER_HARDENING=ssh,ufw,fail2ban` | То же самое панель применяет к новым серверам в «Setup Server». Если задан флаг установки, переменная выставляется автоматически. | -Версия Traefik для серверов берётся из установщика: `TRAEFIK_IMAGE`, сейчас `traefik:v3.7.14`. Тест `apps/dokploy/__test__/server/component-versions-sync.test.ts` падает, если версия по умолчанию в панели расходится с установщиком. +Версия Traefik для серверов берётся из установщика: `TRAEFIK_IMAGE`, сейчас `traefik:v3.7.16`. Тест `apps/dokploy/__test__/server/component-versions-sync.test.ts` падает, если версия по умолчанию в панели расходится с установщиком. Флаги усиления принимают только `install` и `harden`. `install-agenthits.sh update` обновляет панель и её стек, но не меняет SSH, UFW и Fail2Ban. diff --git a/install-agenthits.sh b/install-agenthits.sh index fc38f9427e..a460a9d900 100755 --- a/install-agenthits.sh +++ b/install-agenthits.sh @@ -4,7 +4,7 @@ set -euo pipefail DOKPLOY_IMAGE="${DOKPLOY_IMAGE:-ghcr.io/agenthits/dokploy:agenthits-dev}" DOKPLOY_RELEASE_TAG="${DOKPLOY_RELEASE_TAG:-agenthits-dev}" DOKPLOY_OFFICIAL_VERSION="${DOKPLOY_OFFICIAL_VERSION:-v0.29.8}" -TRAEFIK_IMAGE="${TRAEFIK_IMAGE:-traefik:v3.7.14}" +TRAEFIK_IMAGE="${TRAEFIK_IMAGE:-traefik:v3.7.16}" POSTGRES_IMAGE="${POSTGRES_IMAGE:-postgres:18.6}" REDIS_IMAGE="${REDIS_IMAGE:-redis:8.10.2}" POSTGRES_DATA_TARGET="${POSTGRES_DATA_TARGET:-}" diff --git a/packages/server/src/setup/component-versions.ts b/packages/server/src/setup/component-versions.ts index 5830f4cc99..c74e6b9f7a 100644 --- a/packages/server/src/setup/component-versions.ts +++ b/packages/server/src/setup/component-versions.ts @@ -5,7 +5,7 @@ export const PINNED_VERSIONS = { node: "26.12.1", docker: "29.9.2", - traefik: "3.7.14", + traefik: "3.7.16", postgres: "18.6", redis: "8.10.2", nixpacks: "1.41.0",