Add proper email notifications
This commit is contained in:
62
Containerfile
Normal file
62
Containerfile
Normal file
@@ -0,0 +1,62 @@
|
||||
# hamprint -- single-container image (plan.md §10).
|
||||
#
|
||||
# Runs Gunicorn plus the two periodic jobs (process_submissions every 30 s,
|
||||
# cleanup_stale every 5 min) in the same process group. No sidecars.
|
||||
#
|
||||
# Build: podman build -t hamprint:latest .
|
||||
# Run: podman run --rm -p 8000:8000 --env-file .env hamprint:latest
|
||||
#
|
||||
# In production the host typically mounts a volume at /app/media so uploaded
|
||||
# STLs survive container restarts; the database connection comes from
|
||||
# DATABASE_URL (Postgres in prod, SQLite if you really want).
|
||||
|
||||
FROM docker.io/library/python:3.14-slim
|
||||
|
||||
ENV PYTHONDONTWRITEBYTECODE=1 \
|
||||
PYTHONUNBUFFERED=1 \
|
||||
PIP_DISABLE_PIP_VERSION_CHECK=1 \
|
||||
PIP_NO_CACHE_DIR=1 \
|
||||
DJANGO_SETTINGS_MODULE=hamprint.settings.prod
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# System packages python:3.14-slim doesn't ship:
|
||||
# tini -- PID 1 for clean signal forwarding to gunicorn + the loops
|
||||
# libgomp1 -- numpy/numpy-stl runtime on some kernels
|
||||
# curl -- handy for healthchecks if compose.yaml grows one
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends tini curl libgomp1 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Python deps as their own layer so app-code edits don't invalidate the wheel
|
||||
# cache. psycopg[binary] is added explicitly because requirements.txt is
|
||||
# kept Postgres-driver-agnostic for the host-venv (SQLite) path.
|
||||
COPY requirements.txt .
|
||||
RUN pip install -r requirements.txt 'psycopg[binary]'
|
||||
|
||||
# Application code (.dockerignore excludes .venv, .git, db.sqlite3, demo/, etc).
|
||||
COPY . .
|
||||
|
||||
# Build Tailwind CSS, gather everything under STATIC_ROOT for WhiteNoise, then
|
||||
# drop the ~120 MB Tailwind CLI download so it doesn't ride along. The source
|
||||
# .css lives at assets/tailwind.source.css (per TAILWIND_CLI_SRC_CSS in
|
||||
# settings/base.py); only the CLI binary cache is purged.
|
||||
RUN python manage.py tailwind build --force \
|
||||
&& python manage.py collectstatic --noinput \
|
||||
&& rm -rf /app/.django_tailwind_cli
|
||||
|
||||
# Default writable dirs. Mount a volume at /app/media in prod for persistence.
|
||||
RUN mkdir -p /app/media /app/staticfiles
|
||||
|
||||
# Drop privileges. uid 1000 maps cleanly to the typical host user in rootless
|
||||
# podman, so a bind-mounted media volume stays writable without extra fuss.
|
||||
RUN useradd -m -u 1000 app \
|
||||
&& chown -R app:app /app
|
||||
USER app
|
||||
|
||||
EXPOSE 8000
|
||||
|
||||
# tini reaps zombies + forwards SIGTERM to all children, so when the orchestrator
|
||||
# stops the container both Gunicorn AND the two background loops get the signal.
|
||||
ENTRYPOINT ["/usr/bin/tini", "--"]
|
||||
CMD ["bash", "entrypoint.sh"]
|
||||
Reference in New Issue
Block a user