42 lines
1.8 KiB
Docker
42 lines
1.8 KiB
Docker
# broker-control — internal control sidecar (spec §29)
|
|
#
|
|
# PID-namespace OWNER: the broker joins THIS container's PID namespace
|
|
# (compose `pid: "service:mosquitto-control"` on the mosquitto service).
|
|
# Owning the namespace means the sidecar survives broker restarts — it
|
|
# was previously the other way around and the kernel killed the sidecar
|
|
# whenever the broker exited. tini runs as PID 1: it forwards signals to
|
|
# python and reaps the broker's zombies (the broker re-parents to tini
|
|
# when its container entrypoint forks).
|
|
#
|
|
# Responsibilities (deliberately minimal, spec §29):
|
|
# - validate staged configuration (mosquitto -c <staged> --test-config)
|
|
# - activate a configuration revision (atomic rename into place)
|
|
# - signal config reload (mosquitto_signal -p <broker-pid> config-reload)
|
|
# - signal broker restart (SIGTERM; Docker policy revives the broker)
|
|
# - check broker process state
|
|
|
|
FROM eclipse-mosquitto:2.1.2-alpine
|
|
|
|
# Same image as the broker → --test-config validates with the exact
|
|
# broker binary that will load the config.
|
|
|
|
# The base image ships NO Python. control.py is stdlib-only, so the
|
|
# distro package is sufficient (no pip, no venv needed).
|
|
# tini: minimal init as PID 1 — signal forwarding + zombie reaping.
|
|
RUN apk add --no-cache python3 tini
|
|
|
|
COPY control.py /app/control.py
|
|
|
|
# The base image has no USER directive, so this sidecar runs as root.
|
|
# Deliberate: it writes /mosquitto/config (owned by uid 1883 in the fresh
|
|
# volume) and signals the broker via the shared PID namespace. The API
|
|
# is token-guarded, internal-network-only, and no docker.sock is mounted
|
|
# (spec §29).
|
|
|
|
# Clear the CMD inherited from the base image — its default CMD
|
|
# (`mosquitto -c ...`) would otherwise be appended to our entrypoint.
|
|
CMD []
|
|
|
|
EXPOSE 8090
|
|
|
|
ENTRYPOINT ["/sbin/tini", "--", "python3", "/app/control.py"] |