From 70de7b1b8f74222ebf5665f36b4bf5baaf413157 Mon Sep 17 00:00:00 2001 From: Pasha Sviderski Date: Thu, 1 Oct 2026 09:25:39 +1000 Subject: [PATCH] feat(caddy): add healthcheck to default Caddy spec and Compose deployment in docs --- pkg/client/caddy.go | 21 +++++++++++-- .../3-concepts/2-ingress/3-managing-caddy.md | 31 ++++++++++++++----- 2 files changed, 42 insertions(+), 10 deletions(-) diff --git a/pkg/client/caddy.go b/pkg/client/caddy.go index 4f903cdf..cfbe2480 100644 --- a/pkg/client/caddy.go +++ b/pkg/client/caddy.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "regexp" + "time" "github.com/Masterminds/semver" "github.com/distribution/reference" @@ -66,6 +67,7 @@ func (c *CaddyClient) Config(ctx context.Context, opts CaddyConfigOptions) (api. // CaddyDeploymentOptions configures a Caddy reverse proxy deployment. type CaddyDeploymentOptions struct { // Image defaults to the latest stable 2.x.x official Caddy image. + // Custom images must include curl and start Caddy with /etc/caddy/Caddyfile. Image string // Config contains an optional global Caddyfile. Config string @@ -91,17 +93,32 @@ func (c *CaddyClient) NewDeployment(ctx context.Context, opts CaddyDeploymentOpt spec := api.ServiceSpec{ Container: api.ContainerSpec{ - Command: []string{"caddy", "run", "-c", "/config/Caddyfile"}, Env: map[string]string{ "CADDY_ADMIN": "unix//run/caddy/admin.sock", }, + Healthcheck: &api.HealthcheckSpec{ + Test: []string{ + "CMD", + "curl", "-fsS", + "-o", "/dev/null", + "--unix-socket", "/run/caddy/admin.sock", + "http://localhost/config/", + }, + Interval: 30 * time.Second, + Timeout: 5 * time.Second, + Retries: 3, + StartPeriod: 10 * time.Second, + StartInterval: 1 * time.Second, + }, Image: image, VolumeMounts: []api.VolumeMount{ { VolumeName: "data", - ContainerPath: "/config", + ContainerPath: "/etc/caddy", + ReadOnly: true, }, { + // Keep local TLS assets persistent while Caddy uses the default file system storage. VolumeName: "data", ContainerPath: "/data", }, diff --git a/website/docs/3-concepts/2-ingress/3-managing-caddy.md b/website/docs/3-concepts/2-ingress/3-managing-caddy.md index 3c206c72..90fb4e35 100644 --- a/website/docs/3-concepts/2-ingress/3-managing-caddy.md +++ b/website/docs/3-concepts/2-ingress/3-managing-caddy.md @@ -34,7 +34,7 @@ uc caddy deploy Deploy a specific version or custom image: ```shell -uc caddy deploy --image caddybuilds/caddy-cloudflare:2.10.2 +uc caddy deploy --image caddybuilds/caddy-cloudflare:2.11.4 ``` Deploy only to a specific machine or a subset of machines (comma-separated list): @@ -80,19 +80,27 @@ config that uses the DNS challenge with Cloudflare to obtain a wildcard TLS cert ```yaml services: caddy: - image: caddybuilds/caddy-cloudflare:2.10.2 - command: caddy run -c /config/Caddyfile + image: caddybuilds/caddy-cloudflare:2.11.4 environment: # unix// is not a typo. Caddy uses network/address format, not a unix:// URL. CADDY_ADMIN: unix//run/caddy/admin.sock env_file: # Contains CLOUDFLARE_API_TOKEN=xxxxx - .env.secrets + healthcheck: + test: curl -fsS -o /dev/null --unix-socket /run/caddy/admin.sock http://localhost/config/ + interval: 30s + timeout: 5s + retries: 3 + start_period: 10s + start_interval: 1s volumes: + - /var/lib/uncloud/caddy:/etc/caddy:ro + # Persists TLS certificates and other assets when using Caddy's default local storage. - /var/lib/uncloud/caddy:/data - - /var/lib/uncloud/caddy:/config - /run/uncloud/caddy:/run/caddy - # Required by caddy.storage.uncloud module. Remove this mount if Uncloud cluster storage is not used for Caddy. + # Required by the Uncloud cluster storage module (https://github.com/unlabs-dev/caddy-uncloud). + # Remove this mount if cluster storage is not used for Caddy. # Mount the directory, not the socket file, so Caddy sees a replacement socket after the daemon restarts. - /run/uncloud/api:/run/uncloud/api:ro x-ports: @@ -142,9 +150,16 @@ internal.example.com { :::info note -The specified `command`, `environment`, `volumes`, and `x-ports` properties are essential for Caddy to function -correctly in the Uncloud cluster. Do not change the source paths of the volume mounts as the Uncloud daemon relies on -them to communicate with Caddy and update its configuration. +The specified `environment`, `volumes`, and `x-ports` properties are essential for Caddy to function correctly in the +Uncloud cluster. Do not change the source paths of the volume mounts as the Uncloud daemon relies on them to communicate +with Caddy and update its configuration. + +The image must include `curl` for the healthcheck and start Caddy with `/etc/caddy/Caddyfile`. Images based on the +official [Caddy image](https://hub.docker.com/_/caddy) do both by default. + +Keep the `/data` mount while using Caddy's default local storage so TLS certificates survive container updates. You can +remove this mount when using the [Uncloud storage module](https://github.com/unlabs-dev/caddy-uncloud) with +`storage uncloud` in your global Caddy config. :::