forked from ungleich-public/ungleich-user
Without DATABASE_HOST the app uses SQLite, which defaulted to /app/db.sqlite3: inside the image, not writable by uid 10001, and unusable with a read-only root filesystem. The image now has a /data directory owned by the app user, declared as a volume, and SQLITE_PATH defaults to /data/db.sqlite3. A fresh named volume mounted there is writable. Checked with docker run --read-only: migrations, the app, and a restart all keep the database.
50 lines
1.6 KiB
Docker
50 lines
1.6 KiB
Docker
# syntax=docker/dockerfile:1
|
|
#
|
|
# Production image for the ungleich account webapp.
|
|
# All configuration comes from environment variables: see docker.md and
|
|
# .env.example.
|
|
#
|
|
# docker build -t ungleich-user .
|
|
# docker run --env-file .env -p 8000:8000 ungleich-user
|
|
#
|
|
# Database migrations are not run on start; run them once per release:
|
|
# docker run --env-file .env ungleich-user python manage.py migrate_locked
|
|
|
|
FROM python:3.15-slim-trixie
|
|
|
|
ENV PYTHONDONTWRITEBYTECODE=1 \
|
|
PYTHONUNBUFFERED=1 \
|
|
PIP_NO_CACHE_DIR=1 \
|
|
PIP_DISABLE_PIP_VERSION_CHECK=1
|
|
|
|
# Security updates for the base image. No sshd or compiler is installed:
|
|
# every Python dependency ships as a pure Python or binary wheel.
|
|
RUN apt-get update \
|
|
&& apt-get upgrade -y --no-install-recommends \
|
|
&& rm -rf /var/lib/apt/lists/* \
|
|
&& useradd --system --uid 10001 --no-create-home --home-dir /app app \
|
|
&& mkdir /data && chown 10001 /data
|
|
|
|
# Only used without DATABASE_HOST: SQLite lives on a volume mounted at
|
|
# /data (owned by the app user, so a fresh named volume is writable).
|
|
ENV SQLITE_PATH=/data/db.sqlite3
|
|
VOLUME /data
|
|
|
|
WORKDIR /app
|
|
|
|
COPY requirements.txt .
|
|
RUN pip install -r requirements.txt
|
|
|
|
COPY manage.py gunicorn.conf.py ./
|
|
COPY dal ./dal
|
|
|
|
# Settings need the required variables to load; these placeholders exist
|
|
# only for this one command and are not part of the image's environment.
|
|
RUN SECRET_KEY=build LDAPSERVER=ldap://build LDAP_ADMIN_DN=build \
|
|
LDAP_ADMIN_PASSWORD=build EMAIL_FROM_ADDRESS=build@example.com \
|
|
python manage.py collectstatic --noinput -v0
|
|
|
|
USER 10001
|
|
EXPOSE 8000
|
|
|
|
CMD ["gunicorn", "dal.wsgi:application"]
|