dockerdocker-machine

Docker build increases image size with chown


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


Solution

  • 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.

    1. First Approach (Inline chown with COPY):

      • When you use --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.
    2. Second Approach (Separate chown command):

      • In this approach, files are first copied with the default root ownership and then the ownership is changed in a separate step using the 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.