From bc2ea773021f102f361c8b79f7f0813ec759878c Mon Sep 17 00:00:00 2001 From: Idir Chikhoune Date: Thu, 5 Mar 2026 12:54:37 +0100 Subject: [PATCH 1/7] feature Ok, .env modification needed --- packaging/container/Containerfile | 8 +++++++- src/settings/base.py | 7 +++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/packaging/container/Containerfile b/packaging/container/Containerfile index 448a6ed17..64dd966a3 100644 --- a/packaging/container/Containerfile +++ b/packaging/container/Containerfile @@ -17,4 +17,10 @@ RUN uv sync --all-extras --frozen WORKDIR /app -ENTRYPOINT ["/bin/bash", "-c"] +ENTRYPOINT ["/bin/bash", "-c", "\ +if [ -z \"$DJANGO_SECRET_KEY\" ]; then \ +export DJANGO_SECRET_KEY=$(python -c 'from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())'); \ +echo \"Generated DJANGO_SECRET_KEY=$DJANGO_SECRET_KEY\"; \ +fi; \ +exec \"$@\" \ +", "--"] diff --git a/src/settings/base.py b/src/settings/base.py index ed5b978d7..8e4f0639e 100644 --- a/src/settings/base.py +++ b/src/settings/base.py @@ -5,7 +5,7 @@ from celery import signals import dj_database_url from .logs_loguru import configure_logging - +from django.core.management.utils import get_random_secret_key BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # Also add ../../apps to python path @@ -119,7 +119,10 @@ USE_I18N = True USE_L10N = True USE_TZ = True -SECRET_KEY = os.environ.get("SECRET_KEY", '(*0&74%ihg0ui+400+@%2pe92_c)x@w2m%6s(jhs^)dc$&&g93') + +### SECRET KEY ### +SECRET_KEY = os.environ.get("DJANGO_SECRET_KEY", get_random_secret_key()) + LOGIN_REDIRECT_URL = '/' LOGOUT_REDIRECT_URL = '/' From bc898acb143a080787a00c7255248fbc2d85402a Mon Sep 17 00:00:00 2001 From: Idir Chikhoune Date: Thu, 5 Mar 2026 14:13:54 +0100 Subject: [PATCH 2/7] debug infinite key regenration --- .env_sample | 2 -- docker-compose.yml | 11 +++++++++-- packaging/container/Containerfile | 12 ++++-------- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/.env_sample b/.env_sample index 6bd01cfbd..d02097600 100644 --- a/.env_sample +++ b/.env_sample @@ -1,5 +1,3 @@ -SECRET_KEY=change-this-secret - # For local setup and debug DEBUG=True diff --git a/docker-compose.yml b/docker-compose.yml index 46c1783de..32ec9719b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -26,9 +26,16 @@ services: context: . dockerfile: packaging/container/Containerfile # NOTE: We use watchmedo to reload gunicorn nicely, Uvicorn + Gunicorn reloads don't work well - command: ["python manage.py migrate --no-input && python manage.py collectstatic --no-input && cd /app/src && watchmedo auto-restart -p '*.py' --recursive -- python3 ./gunicorn_run.py"] + command: > + bash -c "python manage.py migrate --no-input && + python manage.py collectstatic --no-input && + cd /app/src && + uv run watchmedo auto-restart -p '*.py' --recursive -- python3 ./gunicorn_run.py" + environment: - DATABASE_URL=postgres://${DB_USERNAME}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME} + # NOTE: Do not modify "DJANGO_SECRET_KEY", it is created automatically. + - DJANGO_SECRET_KEY= env_file: .env volumes: - .:/app:delegated @@ -241,4 +248,4 @@ services: logging: options: max-size: "20m" - max-file: "5" + max-file: "5" \ No newline at end of file diff --git a/packaging/container/Containerfile b/packaging/container/Containerfile index 64dd966a3..1da86dbc2 100644 --- a/packaging/container/Containerfile +++ b/packaging/container/Containerfile @@ -15,12 +15,8 @@ COPY uv.lock ./ # Install dependencies RUN uv sync --all-extras --frozen - WORKDIR /app -ENTRYPOINT ["/bin/bash", "-c", "\ -if [ -z \"$DJANGO_SECRET_KEY\" ]; then \ -export DJANGO_SECRET_KEY=$(python -c 'from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())'); \ -echo \"Generated DJANGO_SECRET_KEY=$DJANGO_SECRET_KEY\"; \ -fi; \ -exec \"$@\" \ -", "--"] +# Copier l'entrypoint +COPY packaging/container/entrypoint.sh /entrypoint.sh +RUN chmod +x /entrypoint.sh +ENTRYPOINT ["/entrypoint.sh"] From f370200ed70f5570be41e37783001b49a8e10f9d Mon Sep 17 00:00:00 2001 From: Idir Chikhoune Date: Thu, 5 Mar 2026 14:18:37 +0100 Subject: [PATCH 3/7] remove echo secret key --- packaging/container/entrypoint.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 packaging/container/entrypoint.sh diff --git a/packaging/container/entrypoint.sh b/packaging/container/entrypoint.sh new file mode 100644 index 000000000..5765dcf27 --- /dev/null +++ b/packaging/container/entrypoint.sh @@ -0,0 +1,10 @@ +#!/bin/bash +set -e + +# Générer la clé Django si elle n'existe pas +if [ -z "$DJANGO_SECRET_KEY" ]; then + export DJANGO_SECRET_KEY=$(python -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())") +fi + +# Exécuter la commande passée au conteneur (migrate, collectstatic, watchmedo…) +exec "$@" From cf303823be4976e17167252823168d4eb63be4c5 Mon Sep 17 00:00:00 2001 From: Idir Chikhoune Date: Thu, 5 Mar 2026 15:55:43 +0100 Subject: [PATCH 4/7] secret key in .env/ production ready --- docker-compose.yml | 12 +++++------- packaging/container/entrypoint.sh | 29 ++++++++++++++++++++++++----- 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 32ec9719b..d448240b8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -26,16 +26,14 @@ services: context: . dockerfile: packaging/container/Containerfile # NOTE: We use watchmedo to reload gunicorn nicely, Uvicorn + Gunicorn reloads don't work well - command: > - bash -c "python manage.py migrate --no-input && - python manage.py collectstatic --no-input && - cd /app/src && - uv run watchmedo auto-restart -p '*.py' --recursive -- python3 ./gunicorn_run.py" - + command: + - bash + - -c + - "cd /app/src && watchmedo auto-restart -p '*.py' --recursive -- python3 ./gunicorn_run.py" + environment: - DATABASE_URL=postgres://${DB_USERNAME}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME} # NOTE: Do not modify "DJANGO_SECRET_KEY", it is created automatically. - - DJANGO_SECRET_KEY= env_file: .env volumes: - .:/app:delegated diff --git a/packaging/container/entrypoint.sh b/packaging/container/entrypoint.sh index 5765dcf27..6d27ffb1c 100644 --- a/packaging/container/entrypoint.sh +++ b/packaging/container/entrypoint.sh @@ -1,10 +1,29 @@ -#!/bin/bash -set -e +#!/usr/bin/env bash +set -euo pipefail -# Générer la clé Django si elle n'existe pas -if [ -z "$DJANGO_SECRET_KEY" ]; then +ENV_FILE=/app/.env +TMP_FILE=${ENV_FILE}.tmp + +if [ -z "${DJANGO_SECRET_KEY:-}" ]; then + if [ -f "$ENV_FILE" ]; then + existing=$(grep -E '^DJANGO_SECRET_KEY=' "$ENV_FILE" | tail -n1 | sed 's/^DJANGO_SECRET_KEY=//') + else + existing="" + fi + + if [ -n "${existing:-}" ]; then + export DJANGO_SECRET_KEY="$existing" + else export DJANGO_SECRET_KEY=$(python -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())") + # persist: remove old DJANGO_SECRET_KEY lines and append the new one + if [ -f "$ENV_FILE" ]; then + grep -v -E '^DJANGO_SECRET_KEY=' "$ENV_FILE" > "$TMP_FILE" || true + else + : > "$TMP_FILE" + fi + printf "%s\n" "DJANGO_SECRET_KEY=$DJANGO_SECRET_KEY" >> "$TMP_FILE" + mv "$TMP_FILE" "$ENV_FILE" + fi fi -# Exécuter la commande passée au conteneur (migrate, collectstatic, watchmedo…) exec "$@" From 4c69494b69ae6ad26ebef6882ac27969d445bc20 Mon Sep 17 00:00:00 2001 From: Idir Chikhoune Date: Thu, 5 Mar 2026 16:02:29 +0100 Subject: [PATCH 5/7] remove comment --- docker-compose.yml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index d448240b8..5c923e374 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -26,14 +26,9 @@ services: context: . dockerfile: packaging/container/Containerfile # NOTE: We use watchmedo to reload gunicorn nicely, Uvicorn + Gunicorn reloads don't work well - command: - - bash - - -c - - "cd /app/src && watchmedo auto-restart -p '*.py' --recursive -- python3 ./gunicorn_run.py" - + command: ["python manage.py migrate --no-input && python manage.py collectstatic --no-input && cd /app/src && watchmedo auto-restart -p '*.py' --recursive -- python3 ./gunicorn_run.py"] environment: - DATABASE_URL=postgres://${DB_USERNAME}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME} - # NOTE: Do not modify "DJANGO_SECRET_KEY", it is created automatically. env_file: .env volumes: - .:/app:delegated From e434e6ec1cc4dcee08272233491be597c1ffda46 Mon Sep 17 00:00:00 2001 From: Idir Chikhoune Date: Thu, 5 Mar 2026 16:05:57 +0100 Subject: [PATCH 6/7] remove comment --- docker-compose.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 5c923e374..68f6ac899 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -26,7 +26,11 @@ services: context: . dockerfile: packaging/container/Containerfile # NOTE: We use watchmedo to reload gunicorn nicely, Uvicorn + Gunicorn reloads don't work well - command: ["python manage.py migrate --no-input && python manage.py collectstatic --no-input && cd /app/src && watchmedo auto-restart -p '*.py' --recursive -- python3 ./gunicorn_run.py"] + command: + - bash + - -c + - "cd /app/src && watchmedo auto-restart -p '*.py' --recursive -- python3 ./gunicorn_run.py" + environment: - DATABASE_URL=postgres://${DB_USERNAME}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME} env_file: .env From bc584c771552646d71a83604a9b22274f0ea25bc Mon Sep 17 00:00:00 2001 From: Idir Chikhoune Date: Thu, 5 Mar 2026 16:22:02 +0100 Subject: [PATCH 7/7] debug secret key, written inside of simple quote --- packaging/container/entrypoint.sh | 42 ++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/packaging/container/entrypoint.sh b/packaging/container/entrypoint.sh index 6d27ffb1c..a1ad98c9f 100644 --- a/packaging/container/entrypoint.sh +++ b/packaging/container/entrypoint.sh @@ -2,27 +2,45 @@ set -euo pipefail ENV_FILE=/app/.env -TMP_FILE=${ENV_FILE}.tmp +TMP_FILE="${ENV_FILE}.tmp" -if [ -z "${DJANGO_SECRET_KEY:-}" ]; then - if [ -f "$ENV_FILE" ]; then - existing=$(grep -E '^DJANGO_SECRET_KEY=' "$ENV_FILE" | tail -n1 | sed 's/^DJANGO_SECRET_KEY=//') - else - existing="" - fi +# read existing DJANGO_SECRET_KEY from .env (raw value after =) +existing="" +if [ -f "$ENV_FILE" ]; then + existing=$(grep -E '^DJANGO_SECRET_KEY=' "$ENV_FILE" | tail -n1 | sed -E 's/^DJANGO_SECRET_KEY=//') +fi - if [ -n "${existing:-}" ]; then - export DJANGO_SECRET_KEY="$existing" +# if variable is already provided by environment, persist it if absent from .env +if [ -n "${DJANGO_SECRET_KEY:-}" ]; then + KEY="$DJANGO_SECRET_KEY" + if [ -z "$existing" ]; then + esc=$(printf '%s' "$KEY" | sed "s/'/'\\\\''/g") + if [ -f "$ENV_FILE" ]; then + grep -v -E '^DJANGO_SECRET_KEY=' "$ENV_FILE" > "$TMP_FILE" || true + else + : > "$TMP_FILE" + fi + printf "DJANGO_SECRET_KEY='%s'\n" "$esc" >> "$TMP_FILE" + mv "$TMP_FILE" "$ENV_FILE" + fi + export DJANGO_SECRET_KEY="$KEY" +else + if [ -n "$existing" ]; then + # remove surrounding quotes if present + KEY=$(printf '%s' "$existing" | sed -E "s/^'(.*)'$/\1/; s/^\"(.*)\"$/\1/") + export DJANGO_SECRET_KEY="$KEY" else - export DJANGO_SECRET_KEY=$(python -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())") - # persist: remove old DJANGO_SECRET_KEY lines and append the new one + # generate, persist and export + KEY=$(python -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())") + esc=$(printf '%s' "$KEY" | sed "s/'/'\\\\''/g") if [ -f "$ENV_FILE" ]; then grep -v -E '^DJANGO_SECRET_KEY=' "$ENV_FILE" > "$TMP_FILE" || true else : > "$TMP_FILE" fi - printf "%s\n" "DJANGO_SECRET_KEY=$DJANGO_SECRET_KEY" >> "$TMP_FILE" + printf "DJANGO_SECRET_KEY='%s'\n" "$esc" >> "$TMP_FILE" mv "$TMP_FILE" "$ENV_FILE" + export DJANGO_SECRET_KEY="$KEY" fi fi