I am new to multistage builds and using chown -R appuser:appuser /app
# Copy the virtual environment
COPY --from=builder --chown=appuser:appuser ${VIRTUAL_ENV} ${VIRTUAL_ENV}
# Copy application code
COPY --from=builder --chown=appuser:appuser /app /app
vs
# Copy the virtual environment
COPY --from=builder ${VIRTUAL_ENV} ${VIRTUAL_ENV}
# Copy application code
COPY --from=builder /app /app
RUN chown -R appuser:appuser /app
There is a difference of 4GB. am i missing something here? The first approach uses close to 16GB while the second only uses 20GB
The difference in disk usage between the two methods you mentioned is due to the way Docker handles filesystem layers and permissions changes. In Docker, each RUN
, COPY
, ADD
(etc.) command creates a new layer. Changing file permissions with a separate RUN chown
command leads to an additional layer that essentially duplicates the data but with different permissions. This can double the size impact of the files and directories whose permissions were changed, which is likely why you see an additional 4GB in the first method.
To break it down better, let’s look at both methods you used.
First Approach (Inline chown
with COPY):
--chown=appuser:appuser
directly in the COPY
command, Docker applies the ownership change at the time of copying the files into the image. This means the files are written to the image with the final ownership already set, which avoids creating additional layers.Second Approach (Separate chown
command):
RUN chown -R appuser:appuser /app
command. This creates at least two layers: one for the copied files and another for the permission changes.I hope this helps.