feat(images): add caddy-sablier image for VM scale-to-zero - #303
Open
arunesh-j wants to merge 1 commit into
Open
feat(images): add caddy-sablier image for VM scale-to-zero#303arunesh-j wants to merge 1 commit into
arunesh-j wants to merge 1 commit into
Conversation
The Sablier wake-on-request plugin is a Caddy module: it must be compiled into the binary with xcaddy and cannot be loaded into a stock Caddy at runtime, and upstream publishes no prebuilt Caddy+Sablier binary. This builds one, pinned to Caddy 2.11.3 + sablier-caddy-plugin v1.0.2. The image is a carrier, not a runtime. ZopDay VM pools run Caddy as a host systemd service, so nothing runs this container: the deployer's scale-to-zero component pulls it and copies /usr/bin/caddy out. Docker Hub is used rather than a release asset because Docker is already a baseline component on every pool VM and those VMs already pull public images, so it needs no new registry auth or network path. CADDY_VERSION must stay in lockstep with the deployer's baseline caddy component: both variants report the same version string and differ only by the extra dormant module, which is what lets the component's skip-download gate treat them as interchangeable. The build asserts both invariants the deployer depends on -- the exact version string and the presence of http.handlers.sablier -- so a bad bump fails the build rather than a VM install. The plugin is inert without a sablier directive, making the binary a drop-in replacement for stock Caddy. Verified: builds with the workflow's own invocation (context images/), reports v2.11.3, registers http.handlers.sablier, and the rendered VM Caddyfile passes caddy validate against it.
arunesh-j
force-pushed
the
feat/caddy-sablier-image
branch
from
August 6, 2026 18:46
7bb6da8 to
b8381df
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds
images/caddy-sablier— Caddy with the Sablier scale-to-zero plugin compiled in. Consumed by the ZopDay deployer's newscale-to-zeroVM component (zopnight, separate PR), which stops idle services on a VM pool and starts them again on the next request.Why a custom image
The Sablier wake-on-request plugin is a Caddy module: it has to be compiled into the binary with
xcaddyand cannot be loaded into a stock Caddy at runtime. Upstream publishes no prebuilt "Caddy + Sablier" binary, so we build one.The two alternatives were worse: Caddy's official plugin download service always builds the latest Caddy (so we couldn't pin 2.11.3, see lockstep below) and makes every VM install depend on a third-party service being up; and building on the VM would need a Go toolchain everywhere.
It's a carrier, not a runtime
Nothing runs this container in production. ZopDay VM pools run Caddy as a host systemd service (it binds
:80/:443and reads/etc/caddy), so the component pulls the image and copies the binary out:Docker Hub rather than a GitHub release asset because Docker is already a baseline component on every pool VM and those VMs already pull public images — no new registry auth, no new network path.
Version lockstep (the thing to know when bumping)
CADDY_VERSIONmust match the version the deployer's baselinecaddycomponent installs. Both variants report the same version string and differ only by the extra dormant module — that is exactly what lets the component's skip-download gate treat them as interchangeable. Bumping one without the other makes every prep re-download the binary forever.The build asserts both invariants the deployer depends on, so a bad bump fails here instead of on a VM six steps later:
caddy versionmatches^v<CADDY_VERSION>caddy list-modulescontainshttp.handlers.sablierThe plugin is inert unless a
sablierdirective appears in the Caddyfile, so the binary is a safe drop-in replacement for stock Caddy of the same version.Follows the existing image conventions
images/caddy-sablier/{Dockerfile,README.md}, same layout asdb-init/opentsdbImage Deploymentworkflow, no workflow changescaddy-sablier-image-v<N>→zopdev/caddy-sablier:v<N>+:latestdb-init's structure (Components & Versions, Prerequisites, Build, Usage, File Structure, Features, Publish, Contributing/CoC/License)Tag with the Caddy version rather than an incrementing counter, so the published tag matches what the component requests — it derives the tag from its own
CADDY_VERSION.Verification
Built with the workflow's own invocation (context
images/):Beyond the build, this exact image content was validated end-to-end before opening the PR: the rendered VM Caddyfile (
route { sablier … { names …; dynamic } reverse_proxy … }) passescaddy validateagainst the binary, and a multi-arch build of it ran on a canary VM through a full sleep → wake cycle (idle service stopped, next request served the loading page, then the app).