FROM python:3.11-slim # Fail fast and log straight to stdout, so `docker-compose logs` is useful. ENV PYTHONDONTWRITEBYTECODE=1 \ PYTHONUNBUFFERED=1 WORKDIR /app # Dependencies first: this layer is cached and only rebuilt when # requirements.txt changes, not on every code change. COPY expenses_manager/requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # Copy the Django project itself, not the repository root, so that /app is # the directory holding manage.py. The previous version copied the repo root # into /app/expenses_manager, which left manage.py and wsgi.py one level # deeper than the gunicorn command expected. COPY expenses_manager/ . # Collect static files at build time so the running container never needs to # write to its own filesystem. SECRET_KEY is required by settings.py when # DEBUG is False, but collectstatic never uses it, so a throwaway value is # enough — the real one comes from the environment at runtime. RUN SECRET_KEY=build-time-placeholder \ DEBUG=False \ ALLOWED_HOSTS=localhost \ python manage.py collectstatic --noinput EXPOSE 8000 CMD ["gunicorn", "expenses_manager.wsgi:application", "--bind", "0.0.0.0:8000"]