Skip to content
Beau Barker edited this page Aug 5, 2025 · 9 revisions

Caddy’s exec module lets you run shell scripts or commands as simple HTTP endpoints, with Caddy handling the response. It’s ideal for lightweight tasks like triggering background jobs or returning basic JSON or text output.

If you want full control over the HTTP response — including status codes, headers, and body content, use CGI instead. It’s better suited for complex or dynamic responses.

Caddy

Make a directory for scripts:

mkdir caddy/scripts

Build the Caddy image with additions:

  • Add the caddy-exec module.
  • Copy our scripts into the image.

caddy/Dockerfile

FROM caddy:2-builder AS builder

RUN xcaddy build \
    --with github.com/abiosoft/caddy-exec

# Final lightweight image
FROM caddy:2

COPY --from=builder /usr/bin/caddy /usr/bin/caddy

# Copy our scripts into the image
COPY ./scripts /scripts

# Copy our Caddyfile into the image
COPY Caddyfile /etc /caddy/Caddyfile

If you want to add bash and jq or another scripting language such as Python, add a line such as this (in the final image part):

RUN apk add --no-cache bash jq

Build the image:

docker compose build caddy

Mount the Scripts for Development

Mount the scripts directory in the Compose override file (which affects development only):

compose.override.yaml

caddy:
  volumes:
    - ./caddy/scripts:/scripts:ro

Add a Route

caddy/Caddyfile

exec /my_route myscript.sh {
  directory /scripts
}

Make sure scripts are executable.

chmod +x caddy/scripts/myscript.sh

Restart Caddy

Lastly, recreate the Caddy container:

docker compose up -d --force-recreate caddy

Writing Scripts

TODO

Clone this wiki locally