| 1234567891011121314151617181920212223242526272829303132333435363738 |
- # syntax=docker/dockerfile:1.7
- #
- # IRDB scheduler sidecar image (SEC_REVIEW F22).
- #
- # Replaces the previous `image: alpine:3` + `apk add curl tini` at
- # container start: the floating tag pulled whatever Alpine shipped on
- # any given restart, and the runtime apk fetch made every restart
- # trust-on-first-use against the apk mirror. A package-mirror compromise
- # (or typosquat) would have given root in the scheduler — which holds
- # INTERNAL_JOB_TOKEN and can call /internal/jobs/* — on every restart.
- #
- # Now: pinned digest, pinned apk versions, all dependency installation
- # happens once at build time. Restart cost is just `docker run` of the
- # already-built local image.
- FROM alpine:3.21@sha256:48b0309ca019d89d40f670aa1bc06e426dc0931948452e8491e3d65087abc07d
- # Pinned via `apk policy` against the same digest above (alpine 3.21
- # main + community at build time of this Dockerfile). Bump these
- # explicitly when the base image is bumped — the build will fail loudly
- # if the version is no longer available, which is the desired signal.
- RUN apk add --no-cache \
- curl=8.14.1-r2 \
- tini=0.19.0-r3 \
- ca-certificates=20260413-r0
- # Bake the canonical schedule into the image. Operators who want a
- # different cadence can still bind-mount their own crontab over
- # /etc/crontabs/root in compose.
- COPY scheduler.crontab /etc/crontabs/root
- # crond runs as root by default in busybox; that is fine — the
- # container has no persistent volume, no network exposure, and only
- # the INTERNAL_JOB_TOKEN env var as state. Dropping privileges here
- # would mean granting CAP_SETUID-or-similar so crond can read
- # /etc/crontabs/root as a non-root user, which is a worse trade.
- ENTRYPOINT ["/sbin/tini", "--"]
- CMD ["crond", "-f", "-L", "/dev/stdout"]
|