feat(docker): custom Caddy image with the Gandi DNS-01 plugin
Compiles caddy-dns/gandi v1.1.0 into Caddy v2.11.4 via xcaddy so mesh/LAN-only
hosts (no public A-record) can issue certs via ACME DNS-01. Pinned per ADR-011/014.
The M4a attempt failed for two reasons, both addressed here:
- built on a Hetzner IP -> Google's Go module proxy 403s those ranges. The
Makefile target is documented to build on ubongo, then push to Forgejo.
- older libdns/gandi sent Gandi's deprecated Apikey header. v1.1.0 sends the
PAT as Authorization: Bearer to api.gandi.net/v5/livedns.
make caddy-image / caddy-image-push mirror the molecule-image targets.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
293c1f88d8
commit
d407aeabb2
2 changed files with 39 additions and 1 deletions
22
.docker/caddy-gandi/Dockerfile
Normal file
22
.docker/caddy-gandi/Dockerfile
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
# syntax=docker/dockerfile:1
|
||||
# Custom Caddy image: vanilla Caddy + the Gandi DNS-01 plugin (ADR-024).
|
||||
#
|
||||
# WHY: mesh/LAN-only services have no public A-record, so they cannot satisfy ACME
|
||||
# HTTP-01; they need DNS-01 against Gandi (the M1 *.<domain> wildcard strategy).
|
||||
# Caddy's official image ships no third-party DNS plugins, so we compile one in.
|
||||
#
|
||||
# WHERE to build: on ubongo (the control node) — NOT on askari/Hetzner. Google's Go
|
||||
# module proxy 403s Hetzner IP ranges, which broke the original on-host build (M4a).
|
||||
# Build here, push the pinned tag/digest to the Forgejo registry, pull on askari.
|
||||
#
|
||||
# Versions pinned (ADR-011/ADR-014). caddy-dns/gandi v1.1.0 -> libdns/gandi v1.1.0,
|
||||
# which authenticates with a Gandi Personal Access Token via "Authorization: Bearer"
|
||||
# against https://api.gandi.net/v5/livedns (the legacy Apikey scheme is gone — using
|
||||
# a PAT in the old Apikey slot 403s, which is what sank the M4a attempt).
|
||||
# verified: caddy-dns/gandi v1.1.0 sends the PAT as Bearer · WebFetch libdns/gandi
|
||||
# client.go @master (go.mod requires v1.1.0) · 2026-06-15
|
||||
FROM caddy:2.11.4-builder AS build
|
||||
RUN xcaddy build v2.11.4 --with github.com/caddy-dns/gandi@v1.1.0
|
||||
|
||||
FROM caddy:2.11.4
|
||||
COPY --from=build /usr/bin/caddy /usr/bin/caddy
|
||||
18
Makefile
18
Makefile
|
|
@ -19,6 +19,10 @@ TF := terraform
|
|||
TF_ENV ?= staging
|
||||
MOLECULE_IMAGE := forgejo.nyumbani.baobab.band/sjat/molecule-debian13:latest
|
||||
MOLECULE_DOCKERFILE := .docker/molecule-debian13/Dockerfile
|
||||
# Custom Caddy + Gandi DNS-01 plugin (ADR-024). Build on ubongo, NOT askari/Hetzner
|
||||
# (the Go module proxy 403s Hetzner IPs); push the pinned tag to the Forgejo registry.
|
||||
CADDY_IMAGE := forgejo.nyumbani.baobab.band/sjat/caddy-gandi:2.11.4
|
||||
CADDY_DOCKERFILE := .docker/caddy-gandi/Dockerfile
|
||||
|
||||
# For TF_ENV=offsite, source the Hetzner token from the vault into the environment
|
||||
# (rbw must be unlocked). Read in-memory; never written to a tfvars file (CLAUDE.md).
|
||||
|
|
@ -33,7 +37,7 @@ endif
|
|||
.PHONY: help setup collections lint test test-all check deploy encrypt decrypt \
|
||||
edit-vault check-vault new-role \
|
||||
tf-init tf-plan tf-apply tf-output tf-inventory tf-inventory-offsite \
|
||||
molecule-image molecule-image-push
|
||||
molecule-image molecule-image-push caddy-image caddy-image-push
|
||||
|
||||
help:
|
||||
@echo ""
|
||||
|
|
@ -63,6 +67,8 @@ help:
|
|||
@echo ""
|
||||
@echo " make molecule-image Build the Molecule test image locally"
|
||||
@echo " make molecule-image-push Push the test image to the Forgejo registry"
|
||||
@echo " make caddy-image Build the custom Caddy + Gandi DNS-01 image (run on ubongo)"
|
||||
@echo " make caddy-image-push Push the Caddy image to the Forgejo registry"
|
||||
@echo ""
|
||||
|
||||
# ── Environment setup ─────────────────────────────────────────────────────────
|
||||
|
|
@ -143,6 +149,16 @@ molecule-image:
|
|||
molecule-image-push: molecule-image
|
||||
docker push $(MOLECULE_IMAGE)
|
||||
|
||||
# ── Custom Caddy image (Gandi DNS-01 plugin, ADR-024) ─────────────────────────
|
||||
# DNS-01 (wildcard / mesh-LAN-only certs) needs the caddy-dns/gandi plugin compiled
|
||||
# in via xcaddy. Build on ubongo — Google's Go module proxy 403s Hetzner IPs.
|
||||
|
||||
caddy-image:
|
||||
docker build -t $(CADDY_IMAGE) -f $(CADDY_DOCKERFILE) .docker/caddy-gandi
|
||||
|
||||
caddy-image-push: caddy-image
|
||||
docker push $(CADDY_IMAGE)
|
||||
|
||||
# ── Terraform ─────────────────────────────────────────────────────────────────
|
||||
|
||||
tf-init:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue