From bae051e5589259bb70bced8aa641ee7651967719 Mon Sep 17 00:00:00 2001 From: Matteo Vitali Date: Mon, 26 Aug 2024 10:14:50 +0200 Subject: [PATCH 1/5] Improve Dockerfile Use VIRTUAL_ENV into Dockerfile instead of user system path Improve local image size optimization --- {{cookiecutter.project_dirname}}/Dockerfile | 27 ++++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/{{cookiecutter.project_dirname}}/Dockerfile b/{{cookiecutter.project_dirname}}/Dockerfile index 0158fef..95bcdc5 100644 --- a/{{cookiecutter.project_dirname}}/Dockerfile +++ b/{{cookiecutter.project_dirname}}/Dockerfile @@ -3,23 +3,31 @@ FROM python:3.12-slim-bookworm AS base LABEL company="20tab" project="{{ cookiecutter.project_slug }}" service="backend" stage="base" ARG DEBIAN_FRONTEND=noninteractive ARG USER=appuser -ENV APPUSER=$USER LANG=C.UTF-8 LC_ALL=C.UTF-8 PYTHONUNBUFFERED=1 PYTHONDONTWRITEBYTECODE=1 WORKDIR=/app +ENV APPUSER=$USER \ + LANG=C.UTF-8 \ + LC_ALL=C.UTF-8 \ + PYTHONUNBUFFERED=1 \ + PYTHONDONTWRITEBYTECODE=1 \ + VIRTUAL_ENV=/opt/venv \ + WORKDIR=/app WORKDIR $WORKDIR RUN useradd --skel /dev/null --create-home $APPUSER RUN chown $APPUSER:$APPUSER $WORKDIR -ENV PATH="/home/${APPUSER}/.local/bin:${PATH}" -ARG PACKAGES_PATH=/home/${APPUSER}/.local/lib/python3.12/site-packages +ENV PATH="${VIRTUAL_ENV}/bin:${PATH}" +ARG PACKAGES_PATH=${VIRTUAL_ENV}/lib/python3.12/site-packages RUN apt-get update \ && apt-get install --assume-yes --no-install-recommends \ libpq5 \ && rm -rf /var/lib/apt/lists/* COPY --chown=$APPUSER ./requirements/base.txt requirements/base.txt +RUN python3 -m venv $VIRTUAL_ENV \ + && chown -R $APPUSER:$APPUSER $VIRTUAL_ENV RUN apt-get update \ && apt-get install --assume-yes --no-install-recommends \ gcc \ libc6-dev \ libpq-dev \ - && su $APPUSER -c "python3 -m pip install --user --no-cache-dir -r requirements/base.txt" \ + && su $APPUSER -c "python3 -m pip install --no-cache-dir -r requirements/base.txt" \ && find ${PACKAGES_PATH} -regex '^.*/locale/.*/*.\(mo\|po\)$' -not -path '*/en*' -not -path '*/it*' -delete || true \ && apt-get purge --assume-yes --auto-remove \ gcc \ @@ -27,7 +35,7 @@ RUN apt-get update \ libpq-dev \ && rm -rf /var/lib/apt/lists/* COPY --chown=$APPUSER ./requirements/common.txt requirements/common.txt -RUN su $APPUSER -c "python3 -m pip install --user --no-cache-dir -r requirements/common.txt" \ +RUN su $APPUSER -c "python3 -m pip install --no-cache-dir -r requirements/common.txt" \ && find ${PACKAGES_PATH} -regex '^.*/locale/.*/*.\(mo\|po\)$' -not -path '*/en*' -not -path '*/it*' -delete || true FROM base AS test @@ -36,7 +44,7 @@ LABEL company="20tab" project="{{ cookiecutter.project_slug }}" service="backend ENV DJANGO_CONFIGURATION=Testing USER $APPUSER COPY --chown=$APPUSER ./requirements/test.txt requirements/test.txt -RUN python3 -m pip install --user --no-cache-dir -r requirements/test.txt +RUN python3 -m pip install --no-cache-dir -r requirements/test.txt COPY --chown=$APPUSER . . CMD ./scripts/test.sh @@ -45,9 +53,9 @@ FROM base AS remote LABEL company="20tab" project="{{ cookiecutter.project_slug }}" service="backend" stage="remote" ENV DJANGO_CONFIGURATION=Remote INTERNAL_SERVICE_PORT={{ cookiecutter.internal_service_port }} USER $APPUSER -ARG PACKAGES_PATH=/home/${APPUSER}/.local/lib/python3.12/site-packages +ARG PACKAGES_PATH=${VIRTUAL_ENV}/lib/python3.12/site-packages COPY --chown=$APPUSER ./requirements/remote.txt requirements/remote.txt -RUN python3 -m pip install --user --no-cache-dir -r requirements/remote.txt \ +RUN python3 -m pip install --no-cache-dir -r requirements/remote.txt \ && find ${PACKAGES_PATH}/boto*/data/* -maxdepth 0 -type d -not -name s3* -exec rm -rf {} \; || true COPY --chown=$APPUSER . . RUN DJANGO_SECRET_KEY=build python3 -m manage collectstatic --clear --link --noinput @@ -71,7 +79,8 @@ RUN apt-get update \ postgresql-client USER $APPUSER COPY --chown=$APPUSER ./requirements/local.txt requirements/local.txt -RUN python3 -m pip install --user --no-cache-dir -r requirements/local.txt +RUN python3 -m pip install --no-cache-dir -r requirements/local.txt \ + && find ${PACKAGES_PATH} -regex '^.*/locale/.*/*.\(mo\|po\)$' -not -path '*/en*' -not -path '*/it*' -delete || true COPY --chown=$APPUSER . . RUN DJANGO_SECRET_KEY=build python3 -m manage collectstatic --clear --link --noinput ENTRYPOINT ["./scripts/entrypoint.sh"] From dc75d4b3e4e97a571f6c7912d3c59137cc4d3948 Mon Sep 17 00:00:00 2001 From: Matteo Vitali Date: Mon, 26 Aug 2024 10:20:26 +0200 Subject: [PATCH 2/5] Fix .dockerignore Remove `k8s` and add `terraform` directory from dockerignore --- {{cookiecutter.project_dirname}}/.dockerignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_dirname}}/.dockerignore b/{{cookiecutter.project_dirname}}/.dockerignore index 1d51ac1..83cdda8 100644 --- a/{{cookiecutter.project_dirname}}/.dockerignore +++ b/{{cookiecutter.project_dirname}}/.dockerignore @@ -9,9 +9,9 @@ data docker-compose* Dockerfile* htmlcov -k8s Makefile media media_test requirements/*.in static +terraform From ac433dcf43eb44deb4af551b761bbd49845570aa Mon Sep 17 00:00:00 2001 From: Matteo Vitali Date: Tue, 3 Sep 2024 14:40:13 +0200 Subject: [PATCH 3/5] Remove unused piptools --- {{cookiecutter.project_dirname}}/requirements/local.in | 1 - 1 file changed, 1 deletion(-) diff --git a/{{cookiecutter.project_dirname}}/requirements/local.in b/{{cookiecutter.project_dirname}}/requirements/local.in index 2cb0bd9..074041a 100644 --- a/{{cookiecutter.project_dirname}}/requirements/local.in +++ b/{{cookiecutter.project_dirname}}/requirements/local.in @@ -3,7 +3,6 @@ django-debug-toolbar~=4.2.0 django-extensions~=3.2.0 graphviz~=0.20.0 ipython~=8.20.0 -pip-tools~=7.3.0 pre-commit~=3.6.0 pydot~=2.0.0 python-dotenv~=1.0.0 From 29d07828311323f77caa46b8a8a67a0db0cbab62 Mon Sep 17 00:00:00 2001 From: Matteo Vitali Date: Tue, 3 Sep 2024 14:44:54 +0200 Subject: [PATCH 4/5] Separate clean image Dockerfile layers --- {{cookiecutter.project_dirname}}/Dockerfile | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/{{cookiecutter.project_dirname}}/Dockerfile b/{{cookiecutter.project_dirname}}/Dockerfile index 95bcdc5..c3c129c 100644 --- a/{{cookiecutter.project_dirname}}/Dockerfile +++ b/{{cookiecutter.project_dirname}}/Dockerfile @@ -28,15 +28,14 @@ RUN apt-get update \ libc6-dev \ libpq-dev \ && su $APPUSER -c "python3 -m pip install --no-cache-dir -r requirements/base.txt" \ - && find ${PACKAGES_PATH} -regex '^.*/locale/.*/*.\(mo\|po\)$' -not -path '*/en*' -not -path '*/it*' -delete || true \ && apt-get purge --assume-yes --auto-remove \ gcc \ libc6-dev \ libpq-dev \ && rm -rf /var/lib/apt/lists/* COPY --chown=$APPUSER ./requirements/common.txt requirements/common.txt -RUN su $APPUSER -c "python3 -m pip install --no-cache-dir -r requirements/common.txt" \ - && find ${PACKAGES_PATH} -regex '^.*/locale/.*/*.\(mo\|po\)$' -not -path '*/en*' -not -path '*/it*' -delete || true +RUN su $APPUSER -c "python3 -m pip install --no-cache-dir -r requirements/common.txt" +RUN find ${PACKAGES_PATH} -regex '^.*/locale/.*/*.\(mo\|po\)$' -not -path '*/en*' -not -path '*/it*' -delete || true FROM base AS test @@ -55,8 +54,8 @@ ENV DJANGO_CONFIGURATION=Remote INTERNAL_SERVICE_PORT={{ cookiecutter.internal_s USER $APPUSER ARG PACKAGES_PATH=${VIRTUAL_ENV}/lib/python3.12/site-packages COPY --chown=$APPUSER ./requirements/remote.txt requirements/remote.txt -RUN python3 -m pip install --no-cache-dir -r requirements/remote.txt \ - && find ${PACKAGES_PATH}/boto*/data/* -maxdepth 0 -type d -not -name s3* -exec rm -rf {} \; || true +RUN python3 -m pip install --no-cache-dir -r requirements/remote.txt +RUN find ${PACKAGES_PATH}/boto*/data/* -maxdepth 0 -type d -not -name s3* -exec rm -rf {} \; || true COPY --chown=$APPUSER . . RUN DJANGO_SECRET_KEY=build python3 -m manage collectstatic --clear --link --noinput ENTRYPOINT ["./scripts/entrypoint.sh"] @@ -66,6 +65,7 @@ FROM base AS local LABEL company="20tab" project="{{ cookiecutter.project_slug }}" service="backend" stage="local" ENV DJANGO_CONFIGURATION=Local INTERNAL_SERVICE_PORT={{ cookiecutter.internal_service_port }} +ARG PACKAGES_PATH=${VIRTUAL_ENV}/lib/python3.12/site-packages RUN apt-get update \ && apt-get install --assume-yes --no-install-recommends \ curl \ @@ -79,8 +79,8 @@ RUN apt-get update \ postgresql-client USER $APPUSER COPY --chown=$APPUSER ./requirements/local.txt requirements/local.txt -RUN python3 -m pip install --no-cache-dir -r requirements/local.txt \ - && find ${PACKAGES_PATH} -regex '^.*/locale/.*/*.\(mo\|po\)$' -not -path '*/en*' -not -path '*/it*' -delete || true +RUN python3 -m pip install --no-cache-dir -r requirements/local.txt +RUN find ${PACKAGES_PATH} -regex '^.*/locale/.*/*.\(mo\|po\)$' -not -path '*/en*' -not -path '*/it*' -delete || true COPY --chown=$APPUSER . . RUN DJANGO_SECRET_KEY=build python3 -m manage collectstatic --clear --link --noinput ENTRYPOINT ["./scripts/entrypoint.sh"] From 1633b3c691cc61dc33e5ee58ab5ef536385f6bdf Mon Sep 17 00:00:00 2001 From: Matteo Vitali Date: Sun, 15 Sep 2024 19:13:01 +0200 Subject: [PATCH 5/5] Fix clean layers --- {{cookiecutter.project_dirname}}/Dockerfile | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/{{cookiecutter.project_dirname}}/Dockerfile b/{{cookiecutter.project_dirname}}/Dockerfile index c3c129c..e06dae1 100644 --- a/{{cookiecutter.project_dirname}}/Dockerfile +++ b/{{cookiecutter.project_dirname}}/Dockerfile @@ -34,8 +34,8 @@ RUN apt-get update \ libpq-dev \ && rm -rf /var/lib/apt/lists/* COPY --chown=$APPUSER ./requirements/common.txt requirements/common.txt -RUN su $APPUSER -c "python3 -m pip install --no-cache-dir -r requirements/common.txt" -RUN find ${PACKAGES_PATH} -regex '^.*/locale/.*/*.\(mo\|po\)$' -not -path '*/en*' -not -path '*/it*' -delete || true +RUN su $APPUSER -c "python3 -m pip install --no-cache-dir -r requirements/common.txt" \ + && (find ${PACKAGES_PATH} -regex '^.*/locale/.*/*.\(mo\|po\)$' -not -path '*/en*' -not -path '*/it*' -delete || true) FROM base AS test @@ -54,8 +54,8 @@ ENV DJANGO_CONFIGURATION=Remote INTERNAL_SERVICE_PORT={{ cookiecutter.internal_s USER $APPUSER ARG PACKAGES_PATH=${VIRTUAL_ENV}/lib/python3.12/site-packages COPY --chown=$APPUSER ./requirements/remote.txt requirements/remote.txt -RUN python3 -m pip install --no-cache-dir -r requirements/remote.txt -RUN find ${PACKAGES_PATH}/boto*/data/* -maxdepth 0 -type d -not -name s3* -exec rm -rf {} \; || true +RUN python3 -m pip install --no-cache-dir -r requirements/remote.txt \ + && (find ${PACKAGES_PATH}/boto*/data/* -maxdepth 0 -type d -not -name s3* -exec rm -rf {} \; || true) COPY --chown=$APPUSER . . RUN DJANGO_SECRET_KEY=build python3 -m manage collectstatic --clear --link --noinput ENTRYPOINT ["./scripts/entrypoint.sh"] @@ -79,8 +79,8 @@ RUN apt-get update \ postgresql-client USER $APPUSER COPY --chown=$APPUSER ./requirements/local.txt requirements/local.txt -RUN python3 -m pip install --no-cache-dir -r requirements/local.txt -RUN find ${PACKAGES_PATH} -regex '^.*/locale/.*/*.\(mo\|po\)$' -not -path '*/en*' -not -path '*/it*' -delete || true +RUN python3 -m pip install --no-cache-dir -r requirements/local.txt \ + && (find ${PACKAGES_PATH} -regex '^.*/locale/.*/*.\(mo\|po\)$' -not -path '*/en*' -not -path '*/it*' -delete || true) COPY --chown=$APPUSER . . RUN DJANGO_SECRET_KEY=build python3 -m manage collectstatic --clear --link --noinput ENTRYPOINT ["./scripts/entrypoint.sh"]