Repository navigation
chore(build): refresh first-party Alpine runtime bases to 3.24 - #3009
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (6)
🚧 Files skipped from review as they are similar to previous changes (3)
📝 WalkthroughWalkthroughSix Dockerfiles across ChangesAlpine Base Image Standardization
Estimated code review effort🎯 1 (Trivial) | ⏱️ ~2 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request performs a routine maintenance update of the first-party container image base layers. By standardizing on Alpine 3.24, the project mitigates known security advisories associated with older base images while ensuring consistent runtime environments across the operator and utility services. Highlights
New Features🧠 You can now enable Memory (public preview) to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on Gemini (@gemini-code-assist) comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request updates the Alpine base image to version 3.24 across multiple Dockerfiles. The review feedback points out two style guide violations: the update to packages/core/platform/ requires an explicit note in the PR description confirming backward compatibility for migration scripts under the newer tool versions, and the commit/PR title uses an invalid scope (images) which needs to be corrected.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| @@ -1,4 +1,4 @@ | |||
| FROM alpine:3.22 | |||
| FROM alpine:3.24 | |||
There was a problem hiding this comment.
According to the repository style guide for packages/core/platform/, any change to this package must have a corresponding migration update or an explicit note that backward compatibility is preserved.\n\nThe current change updates the Alpine base, which bumps kubectl (1.33 → 1.36) and helm (3.18 → 3.19) versions. While the PR description notes this version skew, it does not explicitly confirm that backward compatibility is preserved for the existing migration scripts under these newer tool versions. Please add an explicit note to the PR description confirming backward compatibility.
References
- Changes to packages/core/platform/ require a corresponding migration update or an explicit note that backward compatibility is preserved. (link)
There was a problem hiding this comment.
The style-guide rule here accepts either a migration update or an explicit backward-compatibility note. This change is a runtime base-image bump — it touches no platform schema, values, or migration-flow logic — so no migration is warranted, and the PR body already carries the note: the "Side effect for platform-migrations" paragraph documents that the base bump floats kubectl 1.33→1.36 and helm 3.18→3.19 (both current stable and in version skew with the control plane for the migration scripts' apply/get/label/helm operations). Backward compatibility is preserved.
| @@ -1,2 +1,2 @@ | |||
| FROM alpine:3.20 | |||
| FROM alpine:3.24 | |||
There was a problem hiding this comment.
The commit and PR title use the scope images, which is not a valid scope according to the repository style guide.\n\nValid scopes are:\n- System: dashboard, platform, cilium, kube-ovn, linstor, fluxcd, cluster-api\n- Apps: postgres, mariadb, redis, kafka, clickhouse, kubernetes, virtual-machine\n- Meta: api, hack, tests, ci, docs\n- Package-specific: any <package-name> matching a directory under packages/\n\nPlease update the commit message and PR title to use a valid scope (e.g., package-specific scopes or platform).
References
- Commit and PR scopes must be valid according to the predefined list of system, apps, meta, or package-specific scopes. (link)
There was a problem hiding this comment.
Good catch — corrected. images isn't in the valid-scope list (.gemini/styleguide.md:40), so I've retitled the PR and amended the commit to chore(build):, which is a valid scope and maps to area/build in the PR labeler. The description is unchanged.
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (4)
packages/core/platform/images/migrations/Dockerfile (1)
1-13: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick winAdd a non-root runtime user for migrations image.
This image has no
USERinstruction, so it runs as root by default. For least privilege, create/use an unprivileged account and runrun-migrations.shunder that user.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/core/platform/images/migrations/Dockerfile` around lines 1 - 13, The Dockerfile runs the migrations container as the root user by default, which violates the least privilege principle. Add a RUN instruction before the ENTRYPOINT to create a new unprivileged user account, then add a USER instruction to switch to that user. Ensure the newly created user has appropriate permissions to execute the run-migrations.sh script and access the /migrations directory. Place the USER instruction after all RUN commands that require root privileges but before the ENTRYPOINT instruction.Source: Linters/SAST tools
packages/system/grafana-operator/images/grafana-dashboards/Dockerfile (1)
1-12: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick winDrop root privileges for the dashboard HTTP container.
The Dockerfile does not set
USER, so the process runs as root. Since darkhttpd listens on an unprivileged port (8080), this should run as a dedicated non-root user.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/system/grafana-operator/images/grafana-dashboards/Dockerfile` around lines 1 - 12, The Dockerfile runs the darkhttpd process as root, which is a security risk. Add a USER directive before the CMD instruction that runs darkhttpd to specify a non-root user. Create a dedicated user in Alpine Linux using RUN apk add and create-user commands, then reference that user in the USER directive. Since darkhttpd listens on port 8080 (an unprivileged port), this process does not require root privileges and should run as a dedicated non-root user for security best practices.Source: Linters/SAST tools
packages/core/installer/images/cozystack-operator/Dockerfile (1)
20-24: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick winSet a non-root user in the final runtime stage.
The final stage (Line 20 onward) has no
USERdirective, socozystack-operatorruns as root. Please add a dedicated low-privilege user/group and switch to it beforeENTRYPOINT.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/core/installer/images/cozystack-operator/Dockerfile` around lines 20 - 24, In the final stage of the Dockerfile (FROM alpine:3.24), the cozystack-operator runs as root because no USER directive is specified. Before the ENTRYPOINT directive that launches /usr/bin/cozystack-operator, add RUN commands to create a dedicated non-root user and group using Alpine's addgroup and adduser utilities, then add a USER directive to switch to that user before the ENTRYPOINT. This ensures the container runs with least privilege instead of as root.packages/apps/mariadb/images/mariadb-backup/Dockerfile (1)
1-3: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick winRun the image as non-root instead of default root.
Line 1 sets the base image, but this runtime stage still has no
USERdirective, so the container runs as root by default. Please add a dedicated unprivileged user/group and switch to it before runtime.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/apps/mariadb/images/mariadb-backup/Dockerfile` around lines 1 - 3, The Dockerfile is missing a USER directive, which means the container runs as root by default. After the RUN apk add --no-cache mariadb-client uuidgen restic line that installs dependencies, add commands to create a dedicated unprivileged user and group (for example, using RUN addgroup and RUN adduser commands), and then add a USER directive specifying this non-root user. This ensures the container runs with minimal privileges rather than as root.Source: Linters/SAST tools
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@packages/apps/mariadb/images/mariadb-backup/Dockerfile`:
- Around line 1-3: The Dockerfile is missing a USER directive, which means the
container runs as root by default. After the RUN apk add --no-cache
mariadb-client uuidgen restic line that installs dependencies, add commands to
create a dedicated unprivileged user and group (for example, using RUN addgroup
and RUN adduser commands), and then add a USER directive specifying this
non-root user. This ensures the container runs with minimal privileges rather
than as root.
In `@packages/core/installer/images/cozystack-operator/Dockerfile`:
- Around line 20-24: In the final stage of the Dockerfile (FROM alpine:3.24),
the cozystack-operator runs as root because no USER directive is specified.
Before the ENTRYPOINT directive that launches /usr/bin/cozystack-operator, add
RUN commands to create a dedicated non-root user and group using Alpine's
addgroup and adduser utilities, then add a USER directive to switch to that user
before the ENTRYPOINT. This ensures the container runs with least privilege
instead of as root.
In `@packages/core/platform/images/migrations/Dockerfile`:
- Around line 1-13: The Dockerfile runs the migrations container as the root
user by default, which violates the least privilege principle. Add a RUN
instruction before the ENTRYPOINT to create a new unprivileged user account,
then add a USER instruction to switch to that user. Ensure the newly created
user has appropriate permissions to execute the run-migrations.sh script and
access the /migrations directory. Place the USER instruction after all RUN
commands that require root privileges but before the ENTRYPOINT instruction.
In `@packages/system/grafana-operator/images/grafana-dashboards/Dockerfile`:
- Around line 1-12: The Dockerfile runs the darkhttpd process as root, which is
a security risk. Add a USER directive before the CMD instruction that runs
darkhttpd to specify a non-root user. Create a dedicated user in Alpine Linux
using RUN apk add and create-user commands, then reference that user in the USER
directive. Since darkhttpd listens on port 8080 (an unprivileged port), this
process does not require root privileges and should run as a dedicated non-root
user for security best practices.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 06b8b8d7-72d6-413d-91ea-bac4ce1baf34
📒 Files selected for processing (6)
packages/apps/mariadb/images/mariadb-backup/Dockerfilepackages/core/installer/images/cozystack-operator/Dockerfilepackages/core/platform/images/migrations/Dockerfilepackages/system/grafana-operator/images/grafana-dashboards/Dockerfilepackages/system/kubeovn-webhook/images/kubeovn-webhook/Dockerfilepackages/system/redis-operator/images/redis-operator/Dockerfile
Moves the pinned Alpine runtime bases of the first-party images forward to alpine:3.24 to clear the published musl / zlib advisories carried by the stale layers: - mariadb-backup: 3.20 -> 3.24 - cozystack-operator: 3.22 -> 3.24 - platform-migrations: 3.22 -> 3.24 - grafana-dashboards: 3.22 -> 3.24 - kubeovn-webhook: 3.21.3 -> 3.24 (also drops the over-specific patch pin in favour of the minor-float convention used elsewhere) - redis-operator: latest -> 3.24 (pins the previously-floating runtime base) These rebuild on the release asset pipeline; the digests pinned in values.yaml are re-pinned there on the next build, matching how the rest of the ~30 first-party images pick up the shared base. Side effect for platform-migrations: its kubectl / helm come from the Alpine repo, so the base bump moves them 1.33 -> 1.36 and 3.18 -> 3.19. Both are current upstream stable and compatible with the management cluster; for the cozystack migration scripts (apply / get / label / helm release ops) the newer kubectl is in skew with the modern control plane. The build-only `alpine AS source` stages (keycloak-operator, objectstorage-controller) are left as-is: their final images are distroless, so no Alpine layer ships. The s3manager base is owned by the separate bucket bump, and kilo's base moves in its own image rebuild. Assisted-By: Claude <[email protected]> Signed-off-by: Aleksei Sviridkin <[email protected]>
ddaea07 to
381edde
Compare
myasnikovdaniil
left a comment
There was a problem hiding this comment.
APPROVE — clean, low-risk base bump. Verified statically + with local builds (no dev10 deploy needed for a runtime-base move).
Base bumps correct. All six runtime FROM alpine:* lines move to 3.24 (mariadb-backup 3.20→, cozystack-operator/migrations/grafana-dashboards 3.22→, kubeovn-webhook 3.21.3→, redis-operator latest→). alpine:3.24 is a real published tag (3.24.0/3.24.1, pushed 2026-06-16).
Scope claims match the diff. The build-only FROM alpine AS source stages (keycloak-operator, objectstorage) are correctly left as-is — their final images are distroless. A repo-wide grep confirms the only remaining old Alpine bases are exactly the ones this PR defers: kilo (#2898) and s3manager (#2887). Nothing missed, nothing moved that shouldn't have.
Package availability confirmed on 3.24. Local docker build of migrations and mariadb-backup both succeed; darkhttpd, ca-certificates, coreutils, mariadb-client, restic, uuidgen all resolve. cozystack-operator and kubeovn-webhook runtime stages install no apk (static binaries) so they're base-version-agnostic.
migrations kubectl 1.36 / helm 3.19 side effect — assessed, safe. Build lands kubectl 1.36.1-r0 and helm 3.19.0-r7. kubectl 1.36 client against ≤1.35 servers is within the supported +1 skew. I audited all 44 migration scripts: only stable verbs (get/apply/create/delete/patch/annotate/label/rollout/api-resources), no deprecated/removed flags, and all --dry-run use the modern =client/=server form. helm stays on 3.x (not 4.x). No raw helm CLI calls in the scripts. No behavior sensitive to the version jump.
CI is fully green including a 1h14m E2E run. LGTM.
What this PR does
Moves the pinned Alpine runtime bases of the first-party images forward to
alpine:3.24, clearing the publishedmusl/zlibadvisories carried by the stale layers.Each runtime
apkset was verified to resolve onalpine:3.24. These images rebuild on the release asset pipeline, which re-pins the digests invalues.yamlon the next build — matching how the rest of the ~30 first-party images pick up the shared base (the issue's "rebuild and run the standard test pipeline").Scope notes:
alpine AS sourcestages (keycloak-operator, objectstorage-controller) are left as-is: their final images are distroless, so no Alpine layer ships.kubectl/helmcome from the Alpine repo, so the base bump moves them1.33 → 1.36and3.18 → 3.19. Both are current upstream stable and in skew with the modern control plane for the migration scripts' operations (apply / get / label / helm release ops).Closes #2902
Release note
Summary by CodeRabbit