Maintaining Caddy files with multiple domains

1. The problem I’m having:

Currently at my job, we have one Caddyfile for our reverse proxy, as well as a Caddyfile for the application servers. We support many domains from multiple customers. With more customers coming in, it is now becoming hard to maintain so many domains.

I’ve attached example Caddyfile of both reverse proxy and application servers. I’m just wondering if this is the correct way, of there is a best practice around this.

2. Error messages and/or full log output:

No errors.

3. Caddy version:

v2.8.4

4. How I installed and ran Caddy:

Running binaries from github

a. System environment:

Debian 12

b. Command:

No special command.

c. Service/unit/compose file:

No special unit.

d. My complete Caddy config:

example.com, another.com, more.com, simple.com, customer.com, beta.customer.com, anotherexample.com, morexamples.com, supernice.com, amazing.com, thisisterrible.com {
   tls {
        dns cloudflare EXAMPLE_KEY
    }

    reverse_proxy node1:80 node2:80 node3:80
}

And then, inside the application servers (node1, node2, node3), looks like this:

specific.com, another.com, beta.customer.com {
    root * /sites/normal/public
    encode gzip

    php_fastcgi unix//var/run/php/php-fpm.sock {
        env THEME "default-dark"
        capture_stderr
    }
}

example.com, more.com, simple.com, customer.com, anotherexample.com, morexamples.com, supernice.com, amazing.com, thisisterrible.com {
    root * /sites/beta/public
    encode gzip

    php_fastcgi unix//var/run/php/php-fpm.sock {
        env THEME "beta"
        capture_stderr
    }
}

5. Links to relevant resources:

No links.

You’re probably looking for On-Demand TLS. Automatic HTTPS — Caddy Documentation

Are you sure you need different config per customer domain? Can’t you just do that mapping in your PHP app itself? You can look at $_SERVER['HTTP_HOST'] to see the domain requested and then do setenv() or whatever based on that (via a DB lookup or from a config file).

1 Like

Yes, this is it! Thank you. Does this work with the cloudflare DNS plugin/plugin?

As for the setenv(), I will make that suggestion to the engineering team.

Well, you shouldn’t need the DNS challenge at all. If your customers are pointing their domains to your server (ideally with a CNAME, not A records, because then it lets you change your own domain’s A record and all the customer domains follow without customer domains needing to also change), then the ACME HTTP challenge should work just fine, no need for the ACME DNS challenge. In fact, using DNS challenge for domains that aren’t in your control doesn’t make sense.

1 Like

We use the Cloudflare’s API to generate Origin certificates from Caddy with the plugin.

From my point of view, I think using snippets, variables/placeholders and multiple .caddy files helps maintain a larger set up.

Instead of multiple domains in one block, have multiple caddy files, one per customer, site or other logical separations.

Good luck!

1 Like

Appreciate the help everyone! Thank you so much for the insights.

That implies that you’re taking control of your customer’s domains to be able to do that. I don’t recommend that, that’s not a good move. Your customers should remain in control of their own domains, and just point a CNAME to your own domain.

1 Like

Isn’t origin certificates just for the communication between cloudflare and the origin and not the outward public facing domain?

Yes, that’s what origin certs are.

But the cloudflare DNS plugin is for ACME DNS, i.e. issue a cert from Let’s Encrypt using the DNS challenge. It cannot write a TXT record to a domain you don’t control. It doesn’t have anything to do with origin certs.

2 Likes

I agree with you. Seems to be some confusion on my side as to what @vvic has setup and want to achieve.

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