From dc7515319f45032d67348fff4cb15bc01a4a75e7 Mon Sep 17 00:00:00 2001 From: MickaelFontes <81414455+MickaelFontes@users.noreply.github.com> Date: Sun, 26 Jan 2025 15:18:17 +0100 Subject: [PATCH 1/4] build: update Dockerfile --- Dockerfile.dev | 45 +++++++++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/Dockerfile.dev b/Dockerfile.dev index 414327d..c658d13 100644 --- a/Dockerfile.dev +++ b/Dockerfile.dev @@ -1,33 +1,46 @@ -# The builder image, used to build the virtual environment -FROM python:3.10 as builder +FROM python:3.10-slim AS builder -RUN pip install poetry +# --- Install Poetry --- +ARG POETRY_VERSION=2.0 -ENV POETRY_NO_INTERACTION=1 \ - POETRY_VIRTUALENVS_IN_PROJECT=1 \ - POETRY_VIRTUALENVS_CREATE=1 \ - POETRY_CACHE_DIR=/tmp/poetry_cache +ENV POETRY_HOME=/opt/poetry +ENV POETRY_NO_INTERACTION=1 +ENV POETRY_VIRTUALENVS_IN_PROJECT=1 +ENV POETRY_VIRTUALENVS_CREATE=1 +ENV PYTHONDONTWRITEBYTECODE=1 +ENV PYTHONUNBUFFERED=1 +# Tell Poetry where to place its cache and virtual environment +ENV POETRY_CACHE_DIR=/opt/.cache + +RUN pip install "poetry==${POETRY_VERSION}" WORKDIR /app -COPY pyproject.toml poetry.lock ./ -RUN touch README.md +# --- Reproduce the environment --- +# You can comment the following two lines if you prefer to manually install +# the dependencies from inside the container. +COPY pyproject.toml poetry.lock /app/ +# Install the dependencies and clear the cache afterwards. +# This may save some MBs. RUN poetry install --without dev --no-root && rm -rf $POETRY_CACHE_DIR -# The runtime image, used to just run the code provided its virtual environment -FROM python:3.10 as runtime +# Now let's build the runtime image from the builder. +# We'll just copy the env and the PATH reference. +FROM python:3.10-slim AS runtime + +ENV VIRTUAL_ENV=/app/.venv +ENV PATH="/app/.venv/bin:$PATH" +ENV HOST=0.0.0.0 -ENV VIRTUAL_ENV=/app/.venv \ - PATH="/app/.venv/bin:$PATH" \ - HOST=0.0.0.0 \ - DASH_DEBUG_MODE=True COPY --from=builder ${VIRTUAL_ENV} ${VIRTUAL_ENV} +WORKDIR /app + COPY assets/ ./assets COPY data/ ./data COPY app.py ./ COPY pages/ ./pages EXPOSE 8080 -CMD ["gunicorn", "-b", ":8080", "-w", "2", "app:server"] +ENTRYPOINT ["gunicorn", "-b", ":8080", "-w", "2", "app:server"] From 96358541144b964ecc28c5789493a6d359e22a2e Mon Sep 17 00:00:00 2001 From: MickaelFontes <81414455+MickaelFontes@users.noreply.github.com> Date: Sun, 26 Jan 2025 17:46:25 +0100 Subject: [PATCH 2/4] fix(docker): :bug: compatibility for `DASH_DEBUG` in Docker behind gunicorn --- app.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app.py b/app.py index 1390e30..7a2e4df 100644 --- a/app.py +++ b/app.py @@ -1,4 +1,5 @@ """Application file for noplp-stats""" +import os import dash import dash_bootstrap_components as dbc @@ -14,7 +15,8 @@ ) server = app.server app.title = "NOPLP stats - Statistiques sur N'oubliez pas les paroles" - +# To still have debug control, behind gunicorn, using DASH_DEBUG environment variable. +app.enable_dev_tools(debug=bool(os.getenv("DASH_DEBUG", False))) app.layout = html.Div( [ From a71580a5f75593e080c0a2ed83d9f190b25fc9c8 Mon Sep 17 00:00:00 2001 From: MickaelFontes <81414455+MickaelFontes@users.noreply.github.com> Date: Sun, 26 Jan 2025 17:46:59 +0100 Subject: [PATCH 3/4] feat(docker): :sparkles: add `HEALTHCHECK` in Dockerfile to try it --- Dockerfile.dev | 93 +++++++++++++++++++++++++------------------------- 1 file changed, 47 insertions(+), 46 deletions(-) diff --git a/Dockerfile.dev b/Dockerfile.dev index c658d13..5d8923e 100644 --- a/Dockerfile.dev +++ b/Dockerfile.dev @@ -1,46 +1,47 @@ -FROM python:3.10-slim AS builder - -# --- Install Poetry --- -ARG POETRY_VERSION=2.0 - -ENV POETRY_HOME=/opt/poetry -ENV POETRY_NO_INTERACTION=1 -ENV POETRY_VIRTUALENVS_IN_PROJECT=1 -ENV POETRY_VIRTUALENVS_CREATE=1 -ENV PYTHONDONTWRITEBYTECODE=1 -ENV PYTHONUNBUFFERED=1 -# Tell Poetry where to place its cache and virtual environment -ENV POETRY_CACHE_DIR=/opt/.cache - -RUN pip install "poetry==${POETRY_VERSION}" - -WORKDIR /app - -# --- Reproduce the environment --- -# You can comment the following two lines if you prefer to manually install -# the dependencies from inside the container. -COPY pyproject.toml poetry.lock /app/ - -# Install the dependencies and clear the cache afterwards. -# This may save some MBs. -RUN poetry install --without dev --no-root && rm -rf $POETRY_CACHE_DIR - -# Now let's build the runtime image from the builder. -# We'll just copy the env and the PATH reference. -FROM python:3.10-slim AS runtime - -ENV VIRTUAL_ENV=/app/.venv -ENV PATH="/app/.venv/bin:$PATH" -ENV HOST=0.0.0.0 - -COPY --from=builder ${VIRTUAL_ENV} ${VIRTUAL_ENV} - -WORKDIR /app - -COPY assets/ ./assets -COPY data/ ./data -COPY app.py ./ -COPY pages/ ./pages - -EXPOSE 8080 -ENTRYPOINT ["gunicorn", "-b", ":8080", "-w", "2", "app:server"] +FROM python:3.10-slim AS builder + +# --- Install Poetry --- +ARG POETRY_VERSION=2.0 + +ENV POETRY_HOME=/opt/poetry +ENV POETRY_NO_INTERACTION=1 +ENV POETRY_VIRTUALENVS_IN_PROJECT=1 +ENV POETRY_VIRTUALENVS_CREATE=1 +ENV PYTHONDONTWRITEBYTECODE=1 +ENV PYTHONUNBUFFERED=1 +# Tell Poetry where to place its cache and virtual environment +ENV POETRY_CACHE_DIR=/opt/.cache + +RUN pip install "poetry==${POETRY_VERSION}" + +WORKDIR /app + +# --- Reproduce the environment --- +# You can comment the following two lines if you prefer to manually install +# the dependencies from inside the container. +COPY pyproject.toml poetry.lock /app/ + +# Install the dependencies and clear the cache afterwards. +# This may save some MBs. +RUN poetry install --without dev --no-root && rm -rf $POETRY_CACHE_DIR + +# Now let's build the runtime image from the builder. +# We'll just copy the env and the PATH reference. +FROM python:3.10-slim AS runtime + +ENV VIRTUAL_ENV=/app/.venv +ENV PATH="/app/.venv/bin:$PATH" +ENV HOST=0.0.0.0 + +COPY --from=builder ${VIRTUAL_ENV} ${VIRTUAL_ENV} + +WORKDIR /app + +COPY assets/ ./assets +COPY data/ ./data +COPY app.py ./ +COPY pages/ ./pages + +EXPOSE 8080 +HEALTHCHECK CMD python -c "import requests; import sys; sys.exit(0) if requests.get('http://127.0.0.1:8080/').status_code == 200 else sys.exit(1);" +ENTRYPOINT ["gunicorn", "-b", ":8080", "-w", "2", "app:server"] From 095f51a0550ef3c180298192579f3b19b87aa40c Mon Sep 17 00:00:00 2001 From: MickaelFontes <81414455+MickaelFontes@users.noreply.github.com> Date: Sun, 26 Jan 2025 18:05:38 +0100 Subject: [PATCH 4/4] fix(app): :rotating_light: fix linting error --- app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app.py b/app.py index 7a2e4df..1b5aabc 100644 --- a/app.py +++ b/app.py @@ -16,7 +16,7 @@ server = app.server app.title = "NOPLP stats - Statistiques sur N'oubliez pas les paroles" # To still have debug control, behind gunicorn, using DASH_DEBUG environment variable. -app.enable_dev_tools(debug=bool(os.getenv("DASH_DEBUG", False))) +app.enable_dev_tools(debug=bool(os.getenv("DASH_DEBUG", None))) app.layout = html.Div( [