Dynamic reverse proxy using environment variables

1. The problem I’m having:

I’m trying to configure Caddy to reverse proxy from service.domain.tld to service.internal (also sub.service.domain.tld to sub.service.internal). Here service should be allowed to be any subdomain and I would like that nothing about the domains is hardcoded in the Caddyfile.

The problem I’m having is that when using regular expressions with the map directive, I’m unable to use environment variables in the regex. I’m not sure if that should even be supported though. Any ideas how I could do this differently?

2. Error messages and/or full log output:

No errors

3. Caddy version:


4. How I installed and ran Caddy:

a. System environment:


b. Command:

export ROOT_DOMAIN_EXTERNAL=domain.tld
export ROOT_DOMAIN_INTERNAL=internal
caddy run

d. My complete Caddy config:

:80 {

	map {host} {service} {upstream} {
		~(.*)\.domain\.tld$ "${1}" "${1}.{$ROOT_DOMAIN_INTERNAL}" # how to do this without hardcoding?
		default "root" ""

	@service expression `{host}.endsWith(r".{$ROOT_DOMAIN_EXTERNAL}")`
	handle @service {
		reverse_proxy {
			dynamic a {upstream} 80
	handle {
		respond "root"

What do you mean by this? What behaviour are you actually seeing? Any errors or logs?

Try running caddy adapt -p to get the adapted JSON for your Caddyfile.

The env vars using {$ENV} syntax get replaced before Caddyfile parsing so I don’t see why that wouldn’t work.

1 Like

You’re right, it all works beautifully. I somehow got confused here since at one point I though I might need placeholder support in the regexp. The only thing I need to do here is to export another environment variable with the dots escaped to be used inside the regexp.

Sorry for the false alarm.

1 Like

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