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]

Reply via email to