Skip to content

Commit

Permalink
perf: use COPY --link to increase Docker cache hit frequency (#1073)
Browse files Browse the repository at this point in the history
The --link flag is a feature of Docker BuildKit which tells Docker to
treat the COPY'd layer independently of previous layers, enabling more
aggressive build caching. For more details, see this Docker blog post [1].

When using COPY --link to copy files from a stage that does not contain
/etc/passwd, we must --chown with $APP_USER_ID rather than app.
Otherwise, the build would fail with "unknown user id".

[1] https://www.docker.com/blog/image-rebase-and-improved-remote-cache-support-in-new-buildkit/
  • Loading branch information
kdmccormick committed Jun 5, 2024
1 parent 5db5e79 commit cf6ac56
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 8 deletions.
1 change: 1 addition & 0 deletions changelog.d/20240531_094930_kyle_assets_link.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- [Improvement] Made Docker cache hits more frequent during the openedx image build via BuildKit's `COPY --link` feature (by @kdmccormick).
22 changes: 14 additions & 8 deletions tutor/templates/build/openedx/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -152,14 +152,20 @@ RUN if [ "$APP_USER_ID" = 0 ]; then echo "app user may not be root" && false; fi
RUN useradd --no-log-init --home-dir /openedx --create-home --shell /bin/bash --uid ${APP_USER_ID} app
USER ${APP_USER_ID}

# Note:
# For directories from other stages, we prefer 'COPY --link' to plain 'COPY' because it copies
# without regard to files from previous layers, providing significant caching benefits. However,
# since Linux's username->userid mapping is stored in a file (/etc/passwd), it means that we must
# --chown with an integer user id ($APP_USER_ID) rather the a username (app).

# https://hub.docker.com/r/powerman/dockerize/tags
COPY --link --from=docker.io/powerman/dockerize:0.19.0 /usr/local/bin/dockerize /usr/local/bin/dockerize
COPY --chown=app:app --from=edx-platform / /openedx/edx-platform
COPY --chown=app:app --from=python /opt/pyenv /opt/pyenv
COPY --chown=app:app --from=python-requirements /openedx/venv /openedx/venv
COPY --chown=app:app --from=python-requirements /mnt /mnt
COPY --chown=app:app --from=nodejs-requirements /openedx/nodeenv /openedx/nodeenv
COPY --chown=app:app --from=nodejs-requirements /openedx/edx-platform/node_modules /openedx/node_modules
COPY --link --chown=$APP_USER_ID:$APP_USER_ID --from=edx-platform / /openedx/edx-platform
COPY --link --chown=$APP_USER_ID:$APP_USER_ID --from=python /opt/pyenv /opt/pyenv
COPY --link --chown=$APP_USER_ID:$APP_USER_ID --from=python-requirements /openedx/venv /openedx/venv
COPY --link --chown=$APP_USER_ID:$APP_USER_ID --from=python-requirements /mnt /mnt
COPY --link --chown=$APP_USER_ID:$APP_USER_ID --from=nodejs-requirements /openedx/nodeenv /openedx/nodeenv
COPY --link --chown=$APP_USER_ID:$APP_USER_ID --from=nodejs-requirements /openedx/edx-platform/node_modules /openedx/node_modules

# Symlink node_modules such that we can bind-mount the edx-platform repository
RUN ln -s /openedx/node_modules /openedx/edx-platform/node_modules
Expand All @@ -174,7 +180,7 @@ WORKDIR /openedx/edx-platform

{# Install auto-mounted directories as Python packages. #}
{% for name in iter_mounted_directories(MOUNTS, "openedx") %}
COPY --from=mnt-{{ name }} --chown=app:app / /mnt/{{ name }}
COPY --link --chown=$APP_USER_ID:$APP_USER_ID --from=mnt-{{ name }} / /mnt/{{ name }}
RUN pip install -e "/mnt/{{ name }}"
{% endfor %}

Expand Down Expand Up @@ -269,7 +275,7 @@ RUN --mount=type=cache,target=/openedx/.cache/pip,sharing=shared \

{# Re-install mounted requirements, otherwise they will be superseded by upstream reqs #}
{% for name in iter_mounted_directories(MOUNTS, "openedx") %}
COPY --from=mnt-{{ name }} --chown=app:app / /mnt/{{ name }}
COPY --link --chown=$APP_USER_ID:$APP_USER_ID --from=mnt-{{ name }} / /mnt/{{ name }}
RUN pip install -e "/mnt/{{ name }}"
{% endfor %}

Expand Down

0 comments on commit cf6ac56

Please sign in to comment.