From c1cf6ab1e5f7f9e66d7daf2279d2061d6e02824c Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Thu, 6 Jan 2022 16:42:29 +0000 Subject: [PATCH] Dockerfile: Split build into multiple stages Currently the Dockerfile has a single RUN directive with all the needed commands in it. This optimizes for image size by not creating too many "layers" (which are only additive). However it means the result that gets cached can basically never be reused, because any change to the source code will need to execute the whole RUN block again. This commit switches to a docker "multi-stage" build, where we have a build image that is separate from the final one that gets published. The build image can be cached locally, and size is no longer a significant concern. This approach allows the single RUN command to be split up into multiple RUN commands that only execute when strictly needed (i.e. when their result is not cached locally). This drastically improves the build time when rebuilding the image after a simple code change, because the build image doesn't have to install all the apt packages, for example. This leads to a nicer developer experience when using docker locally for development and testing. --- Dockerfile | 53 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/Dockerfile b/Dockerfile index 38a3adf..cc9c74c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,13 @@ -FROM debian:buster-slim +FROM debian:buster-slim AS build -ARG BUILD_SERIES=dev -ARG BUILD_ID=0 +RUN set -eu; \ + export DEBIAN_FRONTEND=noninteractive ; \ + apt-get update ; \ + apt-get install -y --no-install-recommends \ + python3 python3-pip python3-setuptools python3-wheel \ + libpython3-dev \ + make build-essential \ + netcat; COPY requirements.txt /opt/snikket-web-portal/requirements.txt COPY build-requirements.txt /opt/snikket-web-portal/build-requirements.txt @@ -11,32 +17,39 @@ COPY babel.cfg /opt/snikket-web-portal/babel.cfg WORKDIR /opt/snikket-web-portal -RUN set -eu; \ - export DEBIAN_FRONTEND=noninteractive ; \ - apt-get update ; \ - apt-get install -y --no-install-recommends \ - python3 python3-pip python3-setuptools python3-wheel \ - libpython3-dev \ - make build-essential \ - netcat \ - ; \ - pip3 install -r requirements.txt; \ +RUN pip3 install -r requirements.txt; \ pip3 install -r build-requirements.txt; \ - make; \ - pip3 uninstall -yr build-requirements.txt; \ - apt-get remove -y build-essential make libpython3-dev; \ - apt-get autoremove -y; \ - pip3 install hypercorn; \ - rm -rf /root/.cache; \ - apt-get clean ; rm -rf /var/lib/apt/lists + make; + + +FROM debian:buster-slim + +ARG BUILD_SERIES=dev +ARG BUILD_ID=0 COPY docker/env.py /etc/snikket-web-portal/env.py + ENV SNIKKET_WEB_PYENV=/etc/snikket-web-portal/env.py ENV SNIKKET_WEB_PROSODY_ENDPOINT=http://127.0.0.1:5280/ HEALTHCHECK CMD nc -zv ${SNIKKET_TWEAK_PORTAL_INTERNAL_HTTP_INTERFACE:-127.0.0.1} ${SNIKKET_TWEAK_PORTAL_INTERNAL_HTTP_PORT:-5765} +RUN set -eu; \ + export DEBIAN_FRONTEND=noninteractive ; \ + apt-get update ; \ + apt-get install -y --no-install-recommends \ + python3 python3-pip python3-setuptools python3-wheel; \ + pip3 install hypercorn; + +WORKDIR /opt/snikket-web-portal + +COPY requirements.txt /opt/snikket-web-portal/requirements.txt +RUN pip3 install -r requirements.txt; + +COPY --from=build /opt/snikket-web-portal/snikket_web/ /opt/snikket-web-portal/snikket_web +COPY babel.cfg /opt/snikket-web-portal/babel.cfg + RUN echo "$BUILD_SERIES $BUILD_ID" > /opt/snikket-web-portal/.app_version ADD docker/entrypoint.sh /entrypoint.sh