Skip to content

Added copa to the images build#247

Draft
bluvulture wants to merge 29 commits into
5.xfrom
image_copa
Draft

Added copa to the images build#247
bluvulture wants to merge 29 commits into
5.xfrom
image_copa

Conversation

@bluvulture

@bluvulture bluvulture commented May 26, 2026

Copy link
Copy Markdown
Contributor

This pull request updates the release.yml workflow to add automated vulnerability scanning and patching to the Docker image build process, and refines how images are published and cleaned up. The main improvements are the integration of Trivy for vulnerability scanning, Copa for patching OS-level vulnerabilities, and enhanced image management during the build and publish steps.

Security automation and image build improvements:

  • Vulnerability scanning and patching:

    • Trivy is now installed and used to scan built Docker images for OS-level vulnerabilities, and Copa is used to automatically patch any fixable vulnerabilities before publishing. [1] [2]
    • If vulnerabilities are patched, the original image is replaced with the patched version and all tags are applied to the updated image.
  • Build environment enhancements:

    • The workflow now installs Trivy and Copa as part of the setup, and starts a BuildKit daemon in a container to support image patching.
    • The BuildKit daemon is reliably stopped at the end of the workflow to ensure cleanup.

Publishing and workflow behavior:

  • Publishing control:

    • The default for the publish input is changed from true to false, making image publishing opt-in for manual workflow dispatches.
  • Image management and cleanup:

    • After building and optionally patching images, all tags are applied, images are pushed if publishing is enabled, and then all images are removed locally to save disk space. [1] [2]

Other workflow refinements:

  • Removed a redundant apt-get update call from the build step, as it is now handled during tool installation.

Changed publishing process to publish only patched images
Copilot AI review requested due to automatic review settings May 26, 2026 09:52

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the Docker image release workflow to introduce an automated “scan + patch” stage (Trivy + Copa) before pushing images to registries, aiming to publish images after OS-level vulnerability remediation.

Changes:

  • Defaults manual (workflow_dispatch) runs to not publish images unless explicitly enabled.
  • Installs Trivy and Copa in the workflow, and starts a BuildKit daemon to support Copa patching.
  • Changes the build/publish flow to build locally, scan + patch the image, then tag and push all tags manually.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .github/workflows/release.yml
Comment thread .github/workflows/release.yml Outdated
Comment on lines +63 to +71
sudo apt-get install -y wget apt-transport-https gnupg lsb-release
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | gpg --dearmor | sudo tee /usr/share/keyrings/trivy.gpg > /dev/null
echo "deb [signed-by=/usr/share/keyrings/trivy.gpg] https://aquasecurity.github.io/trivy-repo/deb generic main" | sudo tee /etc/apt/sources.list.d/trivy.list
sudo apt-get update
sudo apt-get install -y trivy

# Install Copa
COPA_VERSION=$(curl -s https://api.github.com/repos/project-copacetic/copacetic/releases/latest | jq -r '.tag_name' | sed 's/^v//')
curl -fsSL -o copa.tar.gz "https://github.com/project-copacetic/copacetic/releases/download/v${COPA_VERSION}/copa_${COPA_VERSION}_linux_$(dpkg --print-architecture).tar.gz"
Comment thread .github/workflows/release.yml Outdated
-p 127.0.0.1:8888:8888/tcp \
--name buildkitd \
--entrypoint buildkitd \
moby/buildkit:latest \
Comment thread .github/workflows/release.yml Outdated
Comment thread .github/workflows/release.yml Outdated
Comment on lines +69 to +74
# Install Copa
COPA_VERSION=$(curl -s https://api.github.com/repos/project-copacetic/copacetic/releases/latest | jq -r '.tag_name' | sed 's/^v//')
curl -fsSL -o copa.tar.gz "https://github.com/project-copacetic/copacetic/releases/download/v${COPA_VERSION}/copa_${COPA_VERSION}_linux_$(dpkg --print-architecture).tar.gz"
tar -xzf copa.tar.gz copa
sudo mv copa /usr/local/bin/copa
rm copa.tar.gz
Copilot AI review requested due to automatic review settings May 26, 2026 13:45

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 3 comments.

Comment thread .github/workflows/release.yml
Comment thread .github/workflows/release.yml Outdated
Comment on lines +62 to +71
sudo apt-get update
sudo apt-get install -y wget apt-transport-https gnupg lsb-release
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | gpg --dearmor | sudo tee /usr/share/keyrings/trivy.gpg > /dev/null
echo "deb [signed-by=/usr/share/keyrings/trivy.gpg] https://aquasecurity.github.io/trivy-repo/deb generic main" | sudo tee /etc/apt/sources.list.d/trivy.list
sudo apt-get update
sudo apt-get install -y trivy

# Install Copa
COPA_VERSION=$(curl -s https://api.github.com/repos/project-copacetic/copacetic/releases/latest | jq -r '.tag_name' | sed 's/^v//')
curl -fsSL -o copa.tar.gz "https://github.com/project-copacetic/copacetic/releases/download/v${COPA_VERSION}/copa_${COPA_VERSION}_linux_$(dpkg --print-architecture).tar.gz"
Comment thread .github/workflows/release.yml Outdated
sudo apt-get install -y trivy

# Install Copa
COPA_VERSION=$(curl -s https://api.github.com/repos/project-copacetic/copacetic/releases/latest | jq -r '.tag_name' | sed 's/^v//')
Copilot AI review requested due to automatic review settings May 26, 2026 14:06

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 5 comments.

Comment thread .github/workflows/release.yml Outdated
Comment on lines +62 to +71
sudo apt-get update
sudo apt-get install -y wget apt-transport-https gnupg lsb-release
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | gpg --dearmor | sudo tee /usr/share/keyrings/trivy.gpg > /dev/null
echo "deb [signed-by=/usr/share/keyrings/trivy.gpg] https://aquasecurity.github.io/trivy-repo/deb generic main" | sudo tee /etc/apt/sources.list.d/trivy.list
sudo apt-get update
sudo apt-get install -y trivy

# Install Copa
COPA_VERSION=$(curl -s https://api.github.com/repos/project-copacetic/copacetic/releases/latest | jq -r '.tag_name' | sed 's/^v//')
curl -fsSL -o copa.tar.gz "https://github.com/project-copacetic/copacetic/releases/download/v${COPA_VERSION}/copa_${COPA_VERSION}_linux_$(dpkg --print-architecture).tar.gz"
Comment thread .github/workflows/release.yml
Comment thread .github/workflows/release.yml Outdated
Comment on lines +71 to +74
curl -fsSL -o copa.tar.gz "https://github.com/project-copacetic/copacetic/releases/download/v${COPA_VERSION}/copa_${COPA_VERSION}_linux_$(dpkg --print-architecture).tar.gz"
tar -xzf copa.tar.gz copa
sudo mv copa /usr/local/bin/copa
rm copa.tar.gz
Comment thread .github/workflows/release.yml
Comment thread .github/workflows/release.yml
Copilot AI review requested due to automatic review settings May 26, 2026 14:37

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 4 comments.

Comment thread .github/workflows/release.yml Outdated
Comment thread .github/workflows/release.yml Outdated
Comment thread .github/workflows/release.yml Outdated
Comment thread .github/workflows/release.yml Outdated
Copilot AI review requested due to automatic review settings May 26, 2026 15:15

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 4 comments.

Comment thread .github/workflows/release.yml Outdated
Comment thread .github/workflows/release.yml Outdated
Comment thread .github/workflows/release.yml
Comment thread .github/workflows/release.yml Outdated
Copilot AI review requested due to automatic review settings May 26, 2026 15:46

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 6 comments.

Comment thread .github/workflows/release.yml
Comment thread .github/workflows/release.yml Outdated
Comment thread .github/workflows/release.yml Outdated
Comment thread .github/workflows/release.yml Outdated
Comment thread .github/workflows/release.yml
Comment thread .github/workflows/release.yml Outdated
v4.2 was released and the matrix was not updated yet.

The 5.x entry with an empty version-override had no practical effect:
every other rolling-branch entry pairs a plain-only row (hardened: false
with a vN-dev version-override) with a stable release row. The plain 5.x
with no override duplicated the dev row without providing the dev version,
so jobs ran against the branch tip but tagged their images without a
meaningful version string. Removing it keeps the pattern consistent.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

Comment on lines +66 to +67
- name: Install Copa and Trivy
run: |
Comment on lines +92 to +93
- name: Start buildkit daemon
run: |
Comment thread .github/workflows/release.yml Outdated
# Post-patch vulnerability gate, run on the hardened image only.
# The plain image is intentionally ungated. A failure here aborts the
# step before any push, so nothing ships for this variant.
FAIL_SEVERITY="$FAIL_ON_SEVERITY"
Comment thread .github/workflows/release.yml Outdated
Comment on lines +182 to +185
# Build and load the plain image locally. The plain image is
# published as-is under the unsuffixed tags; it is never patched.
PLAIN_IMAGE="${IMAGE_NAME}:${TAG}"
docker build --load \
Comment thread README.md
For our stable release tags we publish each image in two flavors so you can choose your trade-off:

- **plain** (default, unsuffixed) – the image exactly as built from the Dockerfile, e.g. `php8.5-debug-v5`.
- **hardened** (`-hardened` suffix) – the same image with known OS-level CVEs patched in via [Copacetic (Copa)](https://github.com/project-copacetic/copacetic), e.g. `php8.5-debug-v5-hardened`. Every hardened image is scanned with [Trivy](https://github.com/aquasecurity/trivy) and must pass a `CRITICAL,HIGH` vulnerability gate before it's published.
The single "Configure and build images" step was doing four unrelated
things: building, patching, gating, and pushing. At ~200 lines it was
hard to follow and made it impossible to skip Copa/Trivy work on jobs
that do not need it.

Split into three steps:

  "Build plain images" -- builds every image variant and writes per-
  variant state (plain_image.txt, plain_tags.txt, base_tag.txt,
  version.txt, tag.txt) to .docker-state/<variant>/ for later steps to
  consume. PHP_SUB_VERSION is now fetched once before the loop instead
  of once per variant.

  "Scan, patch, and gate hardened images" -- reads the state files,
  runs Copa and Trivy for hardened: true jobs only. Reduces post-patch
  Trivy from three invocations to two: one JSON scan (artifact + gate
  source) and one table scan (human display). The gate now reads the
  existing JSON via jq instead of running a third scan with --exit-code.
  Writes hardened_image.txt and hardened_tags.txt for the next step.

  "Tag, push, and aggregate" -- reads state for all variants, applies
  tags, pushes in parallel, aggregates logical tags, and cleans up per
  variant to keep disk usage bounded across the loop.

Also fixes VERSION_MAJOR extraction: the old VERSION replacement
substitution stripped every digit after a dot (e.g. v5.10 became v5.1
instead of v5). Using parameter expansion strips only the last component.
The regex guarding the block is also tightened so the unescaped dot no
longer matches any character.
Copilot AI review requested due to automatic review settings June 19, 2026 09:44
Previously the "Install Copa and Trivy" and "Start buildkit daemon"
steps ran on all 28 matrix jobs, even those with hardened: false that
never call copa or trivy. Each wasted ~30-60s installing packages and
starting a container that would never be used.

Adding if: matrix.build.hardened to both steps skips them on plain-only
jobs. The "Stop buildkit daemon" step is also guarded the same way
since there is nothing to stop when buildkitd was never started.
The filename passed to grep contains dots, which grep treats as
wildcards in regex mode. With grep -F (fixed string), the match is
literal, so copa_0.14.1_linux_amd64.tar.gz cannot accidentally match
copa_0X14Y1_linux_amd64.tar.gz or any other near-miss in the checksums
file.
When PUSH is false (workflow_dispatch without publish: true) the
aggregated_tags.txt file is never written. Without this option the
upload-artifact action would error on the missing file even though the
step is correctly gated to only run when publishing. Ignore silences
that spurious failure without masking genuine upload problems.
@berfinyuksel berfinyuksel requested a review from brusch June 19, 2026 09:47

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

Comment on lines +183 to +186
env:
ARCH_TAG: ${{ contains(matrix.runner, 'arm') && 'arm64' || 'amd64' }}
FAIL_ON_SEVERITY: ${{ inputs.fail_on_severity || 'CRITICAL,HIGH' }}
TRIVY_DB_REPOSITORY: ${{ env.TRIVY_DB_REPOSITORY }}
Comment on lines +9 to +10
Today, for every matrix build marked `imagePatch: true` (the stable releases:
`v1.6`, `v2.3`, `v3.8`, `v4.1`, `v5.1`), the release workflow scans the freshly
@berfinyuksel berfinyuksel marked this pull request as ready for review June 19, 2026 10:22
@berfinyuksel berfinyuksel self-requested a review as a code owner June 19, 2026 10:22
Copilot AI review requested due to automatic review settings June 19, 2026 10:22
@berfinyuksel berfinyuksel marked this pull request as draft June 19, 2026 10:24

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

Comment thread .github/workflows/release.yml Outdated
Comment on lines +190 to +193
set -eux
mkdir -p trivy-reports

GHCR_TAG="ghcr.io/pimcore/pimcore:${TAG}"
GHCR_TAG_DETAILED="ghcr.io/pimcore/pimcore:${TAG_DETAILED}"
read -r -a imageVariants < .docker-state/variants.txt
Comment on lines +9 to +10
Today, for every matrix build marked `imagePatch: true` (the stable releases:
`v1.6`, `v2.3`, `v3.8`, `v4.1`, `v5.1`), the release workflow scans the freshly
berfinyuksel and others added 3 commits June 19, 2026 12:31
variants.txt was written space-separated with echo "${imageVariants[*]}"
and read back with read -r -a. Switch to one-variant-per-line with
printf '%s\n' to match the newline-separated format used by every other
state file, and use mapfile -t consistently at all three read sites.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The 2>&1 redirect swallowed jq stderr, so a malformed or missing
REPORT_JSON would cause jq to exit non-zero and silently skip the gate,
potentially allowing a broken hardened image to ship. Keep stdout
redirected to /dev/null (output is unused) but let stderr surface so
any jq error aborts the step.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Both images were removed explicitly before the loop, then removed again
inside the loop because ALL_TAGS already contains them as its first
entries (from plain_tags.txt and hardened_tags.txt). The redundant
pre-loop rmi calls are harmless due to || true but confusing. Remove
them and let the single loop cover everything.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 19, 2026 10:31

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

Comment thread .github/workflows/release.yml
- { tag: 'v3.8', php: '8.3', distro: bookworm, version-override: "", latest-tag: true, hardened: true }
- { tag: '3.x', php: '8.2', distro: bookworm, version-override: "v3-dev", latest-tag: false, hardened: false }
- { tag: '3.x', php: '8.3', distro: bookworm, version-override: "v3-dev", latest-tag: false, hardened: false }
- { tag: 'v4.2', php: '8.4', distro: bookworm, version-override: "", latest-tag: true, hardened: true }
Comment on lines +9 to +12
Today, for every matrix build marked `imagePatch: true` (the stable releases:
`v1.6`, `v2.3`, `v3.8`, `v4.1`, `v5.1`), the release workflow scans the freshly
built image with Trivy, patches OS-level CVEs with Copa, and then **replaces the
plain image in place** under the same tags (`release.yml` lines ~191–219). The
berfinyuksel and others added 2 commits June 19, 2026 12:38
copa patch -t was passed "${BASE_TAG}-${VERSION}-hardened-${ARCH_TAG}"
(e.g. php8.5-v5-dev-hardened-amd64), so Copa produced an image named
php8.5-v5-dev-hardened-amd64:latest. The subsequent docker image inspect
"${HARDENED_IMAGE}" looked for pimcore/pimcore:php8.5-v5-dev-hardened-amd64
and always failed even on a successful patch.

Pass "${HARDENED_IMAGE}" directly — it already carries the full
${IMAGE_NAME}: prefix — so Copa tags its output consistently with what
the rest of the step expects.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The matrix was bumped from v4.1 to v4.2 in a prior commit; the design
doc still referenced v4.1 in the stable-release list.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 19, 2026 10:39

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

Comment on lines +84 to +86
# Verify checksum before extracting
EXPECTED_SHA=$(grep -F "copa_${COPA_VERSION}_linux_${COPA_ARCH}.tar.gz" copacetic_checksums.txt | awk '{print $1}')
ACTUAL_SHA=$(sha256sum copa.tar.gz | awk '{print $1}')
Comment on lines +82 to +83
curl -fsSL -o copa.tar.gz "https://github.com/project-copacetic/copacetic/releases/download/v${COPA_VERSION}/copa_${COPA_VERSION}_linux_${COPA_ARCH}.tar.gz"
curl -fsSL -o copacetic_checksums.txt "https://github.com/project-copacetic/copacetic/releases/download/v${COPA_VERSION}/copacetic_checksums.txt"
Comment on lines +321 to +324
# Clean up per variant to reclaim disk space before the next variant.
# ALL_TAGS already includes PLAIN_IMAGE and HARDENED_IMAGE as their
# first entries, so a single loop covers everything.
for additional_tag in "${ALL_TAGS[@]}"; do
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants