- GET /health/ready (Electrum connected, header < 1800s, scheduler heartbeat < 30s) is the container healthcheck; the scheduler beats on every tick and draw-wait iteration - GET /admin/electrum and an Electrum indicator in /admin (server, header age, last rotation) - GET /admin/audit-log: before_id, event_type, round_id, user_id, from, to; the panel gets filters - registration writes user_registered in its transaction - the app's own logs also go to stdout; uvicorn trusts X-Forwarded-For from Caddy's fixed address only, so the access log shows the client's IP Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
26 lines
1.2 KiB
Docker
26 lines
1.2 KiB
Docker
# B-91 (SEC-51, SEC-52): base image pinned by digest, dependencies installed from a
|
|
# hash-checked lock file, process running as a non-root user.
|
|
# To update: `docker buildx imagetools inspect python:3.12-slim` for the digest, and
|
|
# `pip-compile --generate-hashes --strip-extras -o requirements.lock pyproject.toml` for the lock.
|
|
FROM python:3.12-slim@sha256:a6e34c598f2467ed0e9a8d349809fcd8b5c603269512df273a0bb1784edc11b1
|
|
|
|
WORKDIR /app
|
|
|
|
COPY requirements.lock ./
|
|
RUN pip install --no-cache-dir --require-hashes --no-deps -r requirements.lock
|
|
|
|
COPY pyproject.toml ./
|
|
COPY app ./app
|
|
COPY migrations ./migrations
|
|
COPY alembic.ini ./
|
|
COPY scripts ./scripts
|
|
|
|
RUN pip install --no-cache-dir --no-deps . \
|
|
&& useradd --uid 1000 --no-create-home --shell /usr/sbin/nologin app
|
|
USER 1000:1000
|
|
|
|
EXPOSE 8123
|
|
|
|
# umask 077: the database, its WAL files and the logs are created readable by the app user only.
|
|
CMD ["/bin/sh", "-c", "umask 077; test -f \"$MASTER_KEY_PATH\" || { echo \"ERROR: master key not found at $MASTER_KEY_PATH -- run: docker compose run --rm app python scripts/generate_master_key.py\" >&2; exit 1; }; alembic upgrade head && exec uvicorn app.main:app --host 0.0.0.0 --port 8123 --proxy-headers --forwarded-allow-ips \"${FORWARDED_ALLOW_IPS:-127.0.0.1}\""]
|