Add unified config system (issue #24)

Introduce timetracker/config.py with a single config() helper that resolves
settings from a fixed priority chain: NAME__FILE (opt-in secret) -> env var
-> .env -> settings.ini -> in-code default. Supports type casting
(bool/list/int/Path), file-based secrets with .strip(), and required_in_prod
validation.

Migrate settings.py off the previous ad-hoc idioms:
- DEBUG via config() (PROD kept as deprecated alias)
- SECRET_KEY required in prod, supports SECRET_KEY__FILE
- APP_URL derives ALLOWED_HOSTS and CSRF_TRUSTED_ORIGINS (kept separate,
  each independently overridable); ALLOWED_HOSTS is now configurable
- TZ and DATA_DIR via config()

Fix DATA_DIR inconsistency: entrypoint.sh now reads DATA_DIR (was hardcoded)
so the bash bootstrap and Django agree on the database directory.

Document the container/entrypoint-only flags (PUID/PGID/
CREATE_DEFAULT_SUPERUSER/STAGING/LOAD_SAMPLE_DATA) as bash concerns.

Update deployment configs to set APP_URL (and DEBUG), add docs/configuration.md,
settings.ini.example, regrouped .env.example, CLAUDE.md, and tests.

https://claude.ai/code/session_01FFn8BiGrQpEJarC8xGse8s
This commit is contained in:
Claude
2026-06-14 19:51:29 +00:00
parent 2e9e6b4fcf
commit d8558eca89
14 changed files with 653 additions and 46 deletions
+11 -3
View File
@@ -1,8 +1,16 @@
#!/bin/bash
set -euo pipefail
# Container-bootstrap configuration. These variables are consumed only by this
# entrypoint, NOT by Django (see timetracker/config.py for the app settings):
# PUID/PGID — uid/gid the container process runs as
# DATA_DIR — writable dir for the SQLite database (kept in
# sync with Django via the same env var + default)
# CREATE_DEFAULT_SUPERUSER — create an admin/admin user on first start
# STAGING / LOAD_SAMPLE_DATA — staging-only data bootstrap (see below)
PUID=${PUID:-1000}
PGID=${PGID:-100}
DATA_DIR=${DATA_DIR:-/home/timetracker/app/data}
USERHOME=$(grep timetracker /etc/passwd | cut -d ":" -f6)
usermod -d "/root" timetracker
@@ -10,11 +18,11 @@ groupmod -o -g "$PGID" timetracker
usermod -o -u "$PUID" timetracker
usermod -d "${USERHOME}" timetracker
mkdir -p /home/timetracker/app/data /var/log/supervisor
mkdir -p "$DATA_DIR" /var/log/supervisor
chmod 755 /home/timetracker/app
chmod 755 /home/timetracker/app/.venv
chown "$PUID:$PGID" /home/timetracker/app/data
chown "$PUID:$PGID" "$DATA_DIR"
chown "$PUID:$PGID" /var/log/supervisor
python manage.py migrate
@@ -49,6 +57,6 @@ if not User.objects.filter(username='admin').exists():
"
fi
chown -R "$PUID:$PGID" /home/timetracker/app/data
chown -R "$PUID:$PGID" "$DATA_DIR"
exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisor.conf