Can I apply a DNS directive to all server blocks?

1. Caddy version (caddy version):

$ docker exec caddy-server caddy version
v2.4.1 h1:kAJ0JB5Xk5gPdTH/27S5cyoMGqD5lBAe9yZ8zTjVJa0=

2. How I run Caddy:

a. System environment:

b. Command:

docker run -d -p 80:80 -p 443:443 \
 --name caddy-server \
 --restart unless-stopped \
 --add-host=host.docker.internal:host-gateway \
 --env-file SECRETS.txt \
 -v $PWD/Caddyfile:/etc/caddy/Caddyfile \
 -v data:/data \
 -v config:/config \
 -v $PWD/files:/etc/caddy/files \
 webserver

c. Service/unit/compose file:

Dockerfile

FROM caddy:2.4.1-builder AS builder

RUN xcaddy build \
    --with github.com/caddy-dns/cloudflare \
    --with github.com/greenpau/caddy-auth-jwt \
    --with github.com/greenpau/caddy-auth-portal

FROM caddy:2.4.1

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

d. My complete Caddyfile or JSON config:

www.worriedwolf.com {
        redir https://worriedwolf.com{uri}
        tls {
                dns cloudflare {env.CLOUDFLARE_AUTH_TOKEN}
        }
}

worriedwolf.com {
        reverse_proxy http://192.168.1.110:8000
        tls {
                dns cloudflare {env.CLOUDFLARE_AUTH_TOKEN}
        }
        encode zstd gzip
}

files.worriedwolf.com {
        tls {
                dns cloudflare {env.CLOUDFLARE_AUTH_TOKEN}
        }
        root * /etc/caddy/files
        file_server {
                precompressed zstd br gzip
                browse
        }
        log {
                output stdout
        }
}

qa.worriedwolf.com {
	reverse_proxy http://192.168.1.110:8001
	tls {
		dns cloudflare {env.CLOUDFLARE_AUTH_TOKEN}
	}
	encode zstd gzip
}

3. The problem I’m having:

I proxy through Cloudflare, which means I need to get certificates via DNS. I would prefer to not have to list the tls directive over and over–especially as I’ll be adding more application servers to this file and this will be the same for every block. Is there a way around this? When I look at the docs, I don’t see any indication of where directives can go. If you click all the way through to to Github page for this module, you can see the format (working) that I used, but this is a lot of repetition. The concepts docs seems to describe the global options block as NOT something that can include directives like this.

4. Error messages and/or full log output:

None. Everything functions as expected.

5. What I already tried:

Nothing. I have trouble reading the docs for directives. It seems that they assume you know what can nest under what. For example, the module tls doc doesn’t indicate that it only nests under a server block, though I’ve gleaned as much from examples. The module page for dns.providers.cloudflare doesn’t seem to indicate anything about where it goes either. You can find an example on the github page for the project itself, though.

6. Links to relevant resources:

Please upgrade to v2.4.3!

All directives go inside site blocks. See this page in the docs, which explains the structure:

Module docs are more specifically about JSON config, less-so about Caddyfile. They’re still sometimes relevant though because they often explain how a specific module works, regardless of Caddyfile config.


That said, you have two options. Either use the acme_dns global option which configures the DNS plugin for all your sites, or you can use Caddyfile snippets and import the snippet into each site that you need it in.

The acme_dns approach is appropriate if all your sites will use the configured DNS plugin, and the snippet approach is appropriate if you only need some to use the DNS plugin, and others to use HTTP/TLS-ALPN challenges (the defaults).

1 Like

This answer is perfect. I was looking at the wrong parts of the concept docs. I was convinced there must be some way to add a global directive to options but missed snippets, and the lack of Caddyfile info only added to confusion in general. That will work decently. Thanks.

2 Likes

This topic was automatically closed after 30 days. New replies are no longer allowed.