mvance/unbound was last rebuilt 668 days ago. Replaced with
madnuttah/unbound (14 days): distroless, runs unprivileged as non-root,
listens on 5335 by default — exactly the "upstream behind a blocker"
shape — and publishes clean semver tags. klutchell/unbound is equally
fresh but defaults to port 53 (fighting Pi-hole/AdGuard for it) and its
tag namespace is CI build soup.
The shipped config was worse than the stale image. It was not a
recursive resolver at all:
interface: 0.0.0.0@53
forward-addr: 10.100.0.3@53 # "Local AdGuard" — a hardcoded IP
forward-addr: 9.9.9.9@853
So it listened on 53 (conflicting with any blocker on the same host),
forwarded to Quad9 — surrendering the "nobody sees my queries" property
that is the only reason to run Unbound in front of a blocker — and
pointed at AdGuard, inverting the dependency: AdGuard should point HERE.
Replaced with a drop-in at conf.d/libreportal.conf. The image's own
unbound.conf ends with `include-toplevel: conf.d/*.conf`, so ours ADDS
to a working recursive config the image author maintains rather than
replacing it — upstream keeps owning the parts that change between
Unbound releases. It contributes access-control (private ranges allow,
everything else REFUSE, so this can never become an open resolver for
amplification attacks), DNSSEC hardening, rebinding protection, and
cache sizing suited to a small VPS. Forwarding is included commented
out, with the trade stated rather than silently chosen.
Ports corrected to 5335:5335 — the old mapping assumed an image
listening on 53 internally. Added the libreportal.category/title labels
the app was missing (no traefik labels: it has no web interface).
Install hook copies the drop-in and repairs a stub directory first, the
same trap that kept Nextcloud's nginx from starting.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
56 lines
2.3 KiB
YAML
Executable File
56 lines
2.3 KiB
YAML
Executable File
networks:
|
|
DOCKER_NETWORK_DATA: #LIBREPORTAL|DOCKER_NETWORK_TAG|DOCKER_NETWORK_DATA
|
|
external: true
|
|
|
|
services:
|
|
unbound-service: #LIBREPORTAL|SERVICE_TAG_1|unbound-service
|
|
container_name: unbound-service
|
|
image: madnuttah/unbound:latest #LIBREPORTAL|UNBOUND_VERSION_TAG|latest
|
|
restart: unless-stopped
|
|
hostname: unbound
|
|
# GLUETUN_OFF_BEGIN
|
|
ports:
|
|
- "PORTS_DATA_1" #LIBREPORTAL|PORTS_TAG_1|PORTS_DATA_1
|
|
- "PORTS_DATA_2" #LIBREPORTAL|PORTS_TAG_2|PORTS_DATA_2
|
|
# GLUETUN_OFF_END
|
|
# No traefik labels: Unbound has no web interface, it is a resolver other
|
|
# apps point at. The category/title labels are the ones the portal reads.
|
|
labels:
|
|
libreportal.category: "CATEGORY_DATA" #LIBREPORTAL|CATEGORY_TAG|CATEGORY_DATA
|
|
libreportal.title: "TITLE_DATA" #LIBREPORTAL|TITLE_TAG|TITLE_DATA
|
|
volumes:
|
|
- SOCKET_DATA #LIBREPORTAL|SOCKET_TAG|SOCKET_DATA
|
|
- /etc/ssl/certs:/etc/ssl/certs:ro
|
|
# A drop-in, not a replacement: the image's own unbound.conf carries
|
|
# `include-toplevel: /usr/local/unbound/conf.d/*.conf`, so ours adds to a
|
|
# working recursive config maintained upstream instead of overriding it.
|
|
# (The old image wanted a full config at /opt/unbound/etc/unbound — a
|
|
# different path entirely, which is why this could not be a tag swap.)
|
|
- "./conf.d:/usr/local/unbound/conf.d:ro"
|
|
environment:
|
|
- TZ=TIMEZONE_DATA #LIBREPORTAL|TIMEZONE_TAG|TIMEZONE_DATA
|
|
healthcheck:
|
|
disable: HEALTHCHECK_DATA #LIBREPORTAL|HEALTHCHECK_TAG|HEALTHCHECK_DATA
|
|
# GLUETUN_OFF_BEGIN
|
|
networks:
|
|
DOCKER_NETWORK_DATA: #LIBREPORTAL|DOCKER_NETWORK_TAG|DOCKER_NETWORK_DATA
|
|
ipv4_address: IP_DATA_1 #LIBREPORTAL|IP_TAG_1|IP_DATA_1
|
|
# GLUETUN_OFF_END
|
|
# GLUETUN_ON_BEGIN
|
|
# network_mode: "container:gluetun-service"
|
|
# GLUETUN_ON_END
|
|
|
|
# >>> libreportal-monitoring >>>
|
|
#unbound-exporter:
|
|
# container_name: unbound-exporter
|
|
# image: letsencrypt/unbound-exporter:latest
|
|
# restart: unless-stopped
|
|
# depends_on:
|
|
# - unbound-service
|
|
# command:
|
|
# - "-unbound.host=tcp://unbound-service:8953"
|
|
# - "-web.listen-address=:PORT_INTERNAL_DATA_3" #LIBREPORTAL|PORT_INTERNAL_TAG_3|PORT_INTERNAL_DATA_3
|
|
# networks:
|
|
# DOCKER_NETWORK_DATA: #LIBREPORTAL|DOCKER_NETWORK_TAG|DOCKER_NETWORK_DATA
|
|
# <<< libreportal-monitoring <<<
|