klesh opened a new pull request, #9301: URL: https://github.com/apache/devlake/pull/9301
### Summary `chgrp -R 0 /app && chmod -R g=u /app` runs as a final layer in `devlake-base`, after python packages, the uv binary, the python plugins and the server binary have already been written by earlier layers. Overlayfs has to copy every file it mutates into the new layer, so the published image carries a second full copy of `/app`: **186.5 MB of the 516.6 MB total**, measured on `apache/devlake:v1.0.3-beta19`. This applies the ownership where the files are created instead, so no second copy is written. | Change | Why | |---|---| | `useradd … -G 0` | the user has to belong to group 0 to `chgrp` its own files to group 0; the primary group stays `devlake`, so the runtime GID does not change | | pip and uv installs folded into one `RUN`, ending with `chgrp/chmod /app/.local` | they share `/app/.local`; normalising it in a later layer would copy it up again | | `… build.sh && chgrp -R 0 /app/python && chmod -R g=u /app/python` | same for the venvs the plugin build creates | | `mkdir logs && chgrp 0 logs && chmod g=u logs` | `/app/logs` is the only writable path the app needs at startup | | `COPY --chown=0:0` for `lake` and `resources` | they are read-only at runtime; the modes they already have (755 binary, 644 docs) are enough for a random UID in group 0 | | `mkdir -p -m 0775 /app/bin/plugins` | the sideload mount point, and the only directory created in the final stage | Resulting ownership and modes are identical to the old recursive pass (`devlake:root`, 775 directories / 664 files), which is what the OpenShift arbitrary-UID support added in #8657 relies on. ### Verification I could not build the full image locally: this machine has no `buildx`, and the legacy builder rejects `FROM --platform=$BUILDPLATFORM` in the earlier stage before it reaches these. So: **1. Mechanism, with a replica image.** Same instructions, 40 MB of payload: the old ordering produces a 41.9 MB content layer plus a 42.0 MB duplicate; the new ordering produces a single 42.0 MB layer. Ownership and modes are identical (`devlake:root 775/664`). **2. The real `base` stage, built from a trimmed copy of the Dockerfile** (`--target base`, builder stage removed): ``` layers 24 -> 23 (the separate chgrp layer is gone) /app/logs devlake:root 775 /app/python devlake:root 775 /app/.local devlake:root 775 /app devlake:devlake 755 ``` **3. The arbitrary-UID contract still holds.** Running as `-u 1000120000:0` (what OpenShift does): ``` /app/logs writable /app/python readable, /app/.local/bin/uv executable ``` `id` inside the image reports `gid=1010(devlake) groups=1010(devlake),0(root)` — the primary GID is unchanged; group 0 is supplementary, which is what lets the user `chgrp`. **Expected size:** the published beta19 image spends 186.5 MB of its 516.6 MB on that one layer. Folding the chgrp into the layers that create the files removes it, so the image should land around **330 MB**. That number is arithmetic from the published manifest, not a local measurement — the final stage can only be built by CI. ### Does this close any open issues? Refs #9276. ### Other Information `config-ui/Dockerfile` has the same late `chgrp -R` pattern over nginx and `/run`. It is worth the same treatment, but those trees are far smaller and messing with nginx permissions deserves its own PR. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
