Wildcard site root directive

1. Caddy version (caddy version):

v2.1.1 h1:X9k1+ehZPYYrSqBvf/ocUgdLSRIuiNiMo7CvyGUQKeA=

2. How I run Caddy:

Plain binary:
caddy run -config /etc/caddy/site.conf -adapter caddyfile

a. System environment:

Debian Buster, no Docker, plain binary

b. Command:

caddy run -config /etc/caddy/site.conf -adapter caddyfile

c. Service/unit/compose file:


d. My complete Caddyfile or JSON config:

https://*.domain.co {

root * /home/pee/stages/{http.request.host.labels.2}

root * /home/domain/stages/{labels.2}

header X-subdomain {http.request.host.labels.2}
php_fastcgi unix//var/run/php/php74/domain.sock

3. The problem I’m having:

I can run without a problem for example https://dev.domain.co/ and it takes /home/domain/stages/. Since SSL is hard to have double subdomain, like on http (for example: dev.user.domain.co) you have to use hack like (https://dev-user.domain.co) to use wildcard SSL.

Is it possible to parse this dash and have served folder /home/domain/|user|/stages/|dev|. Or is there any other smart solution on this problem i dont see?

** also a hint, I used 2 days to find this placeholder {http.request.host.labels.2}, it should be mentioned here root (Caddyfile directive) — Caddy Documentation, because a lot of people are looking for wildcard solution. Just an idea.

4. Error messages and/or full log output:

5. What I already tried:

everything possible, checked docs for last 3 days, but couldnt find anything.

6. Links to relevant resources:

Thanks a lot, and thanks for great software,

IMHO, simple solution for this case is as follow:

dev-user.domain.co {

dev.user.domain.co {
    redir https://dev-user.domain.co{uri}

Due to the way browsers handle certificates nowadays(requirement for Subject Alternative Name for every single sub-domain), wildcard certificate kind of lost its purpose.

You could use a header_regexp matcher on the Host header to parse out exactly the parts you need instead of using labels.*

Maybe something like this (regexp is mostly bullshit, not spending much effort on it right now, you can adjust to your needs):

@parseHost header_regexp parsedHost Host ^([a-z0-9]+)-([a-z0-9]+)\.domain\.co$
root @parseHost /home/domain/{re.parsedHost.2}/stages/{re.parsedHost.1}
1 Like

Thanks this worked great for now. One question, is this regex slowing down caddy a lot, or it is little overhead?

Would it be good to write headers with first and second param and use them in all other requests? That could maybe have less impact on performance.

It’ll be imperceptible. The regexp is compiled ahead of time, so most of the cost is offloaded to server startup. It’s not as fast as substring matches, but it’s also not slow, per se. This is a pretty simple regexp ultimately, since there’s no lookaheads or lookbehinds or anything like that, so it shouldn’t be a problem.

Also you shouldn’t worry about premature optimization. You should only care that it’s slow if your server is totally getting flooded all the time, and you just can’t scale up with a bigger server, or scale out with more Caddy instances. You’ll hit other bottlenecks much earlier than this regexp.


OK great, thanks for such a great explanation. I too think there will be other bottlenecks before this one. Much appreciated

p.s.: running caddy is much faster than nginx, maybe its just my case, but really great job from you guys.


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