Adding a second DNS provider to an existing stack - best practice?

1. The problem I’m having:

Hi! I have a Caddy set up that is currently running fantastically (thankyou for that!), with multiple services and machines pointing to different domains, all through a single provider, Cloudflare.

I want to host a new website, the domain of which has to be with a different provider.

The new provider has suggested that I simply point them to cloudflare’s DNS servers.

My question is whether Caddy is able to work with that as well. For example, the API tokens cloudflare provides are dependent on the specific domain, so would I instead have to self-sign certificates?

If so, how does that change the required caddy file setup?

For clarity’s sake, the new website is a wordpress, so would I just add a code block like so?

URL4.com.au {
file_server
encode zstd gzip
header {
Access-Control-Allow-Headers *
Access-Control-Allow-Methods *
Access-Control-Allow-Origin *
}
@options {
method OPTIONS
}
respond @options 204
reverse_proxy IP:PORT {
header_up Host URL4.com.au
}
tls {
issuer acme {
dns cloudflare {env.TOKEN_4}
resolvers 1.1.1.1
propagation_delay 60s
propagation_timeout -1
}
}
}

3. Caddy version:

v2.9.1 h1:OEYiZ7DbCzAWVb6TNEkjRcSCRGHVoZsJinoDR/n9oaY=

4. How I installed and ran Caddy:

Caddy is run on Ubuntu Linux as a cloudflare binary with systemctl automatically at startup.

a. System environment:

Ubuntu 24.04.2 x64 Intel

b. Command:

systemctl status caddy
sudo systemctl daemon-reload

d. My complete Caddy config:

URL1 {
        reverse_proxy IP:PORT
        tls {
                issuer acme {
                        dns cloudflare {env.TOKEN}
                        resolvers 1.1.1.1
                        propagation_delay 60s
                        propagation_timeout -1
                }
        }
}

URL2.wordpress {
        file_server
        encode zstd gzip

        header {
                Access-Control-Allow-Headers *
                Access-Control-Allow-Methods *
                Access-Control-Allow-Origin *
        }
        @options {
                method OPTIONS
        }
        respond @options 204

        reverse_proxy IP:PORT {
                header_up Host URL2.wordpress
        }
        tls {
                issuer acme {
                        dns cloudflare {env.TOKEN_2}
                        resolvers 1.1.1.1
                        propagation_delay 60s
                        propagation_timeout -1
                }
        }
}

sub.URL2 {
        reverse_proxy IP:PORT
}

sub2.URL2 {
    reverse_proxy IP:PORT
}

sub3.URL2 {
        reverse_proxy IP:PORT
}


sub4.URL2 {
        reverse_proxy IP:PORT
}

sub4.URL2:PORT {
        reverse_proxy IP:PORT
}

URL3 {
        reverse_proxy IP:PORT
}

5. Links to relevant resources:

Bump for visibility.

I’ve tried looking at the Caddy documents but as far as I’m aware I can’t see any discussion of this specific use case

Well, I have gone ahead and tried to do the above, I’ve gotten most of the way but am stuck at a 522 error, so I guess this is now a request for assistance :sweat_smile:

I believe I’ve taken all the steps but it’s not working. When I turn off Cloudflare proxy (orange cloud) it changes to ERR_SSL_PROTOCOL_ERROR

I’ve checked the journal logs and there is no mention of the website at all.

Caddyfile (excluding other working entries):

URL4.com.au {
        file_server
        encode zstd gzip

        header {
                Access-Control-Allow-Headers *
                Access-Control-Allow-Methods *
                Access-Control-Allow-Origin *
        }
        @options {
                method OPTIONS
        }
        respond @options 204

        reverse_proxy INTERNALIP:PORT {
                header_up Host URL4.com.au
        }
        tls {
                issuer acme {
                        dns cloudflare {env.TOKEN4}
                        resolvers 1.1.1.1
                        propagation_delay 60s
                        propagation_timeout -1
                }
        }
}


wp-config.php

if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false) {
        $_SERVER['HTTPS'] = 'on';
}

if ($configExtra = getenv_docker('WORDPRESS_CONFIG_EXTRA', '')) {
        eval($configExtra);
}

if ( ! defined( 'ABSPATH' ) ) {
        define( 'ABSPATH', __DIR__ . '/' );
}

require_once ABSPATH . 'wp-settings.php';

define( 'FORCE_SSL_ADMIN', true );

if( strpos( $_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false )
    $_SERVER['HTTPS'] = 'on';

I have another wordpress already running with an identical set up which is currently connected and working, so the networking must all be functioning properly. Something about the url handover is breaking the SSL. I was wondering if maybe it has something to do with the headers not being passed through properly?

I have also gone into the mysql db in the backend and confirmed that both the home/siteurl is correctly set:

+-------------+-------------------------------+
| option_name | option_value                  |
+-------------+-------------------------------+
| home        | https://URL4.com.au |
| siteurl     | https://URL4.com.au |

I don’t think it’s clear what’s special about your use case here. You have this new url4.com.au using Cloudflare DNS, and you said your other domains are also using Cloudflare DNS, so nothing sounds unusual there. Is that you have a different API token for that domain than the others?

OK so it sounds like you don’t have a certificate. Have you restarted Caddy? Are you sure it’s using the Caddyfile that you’ve edited? There can be quirks with this when running Caddy in docker, if you are.

1 Like

Hi there,

Thanks for your reply. To clarify, the new URL4.com.au is with a new domain provider, outside cloudflare, and is being pointed to the cloudflare DNS.

I spoke to the company today and they said the http requests and headers should all be coming through like normal, so it has to be something on the back end.

I have run sudo systemctl daemon-reload several times, but it hasn’t made a difference. I will try restarting the server entirely and verifying the caddy file to see if that helps.

The domain provider (by which I assume you mean the registrar?) does not matter to Caddy or certificate issuance, only the DNS host which is Cloudflare.

That only reloads the systemd configuration (in case you have changed a .service file) - it does not reload or restart Caddy. You want sudo systemctl reload caddy.

1 Like

Ah yep, registrar. My mistake. Good to know.

So I restarted the server, ran the command, I’m getting a 525 error and now at least am getting something in the journal output:

{"level":"error","ts":1761048233.1357915,"msg":"cleaning up solver","identifier":"URL4.com.au","challenge_type":"dns-01","error":"no memory of presenting a DNS record for \"_acme-challenge.URL4.com.au\" (usually OK if presenting also failed)","stacktrace":"github.com/mholt/acmez/v3.(*Client).solveChallenges.func1\n\tgithub.com/mholt/acmez/v3@v3.0.0/client.go:318\ngithub.com/mholt/acmez/v3.(*Client).solveChallenges\n\tgithub.com/mholt/acmez/v3@v3.0.0/client.go:363\ngithub.com/mholt/acmez/v3.(*Client).ObtainCertificate\n\tgithub.com/mholt/acmez/v3@v3.0.0/client.go:136\ngithub.com/caddyserver/certmagic.(*ACMEIssuer).doIssue\n\tgithub.com/caddyserver/certmagic@v0.21.6/acmeissuer.go:477\ngithub.com/caddyserver/certmagic.(*ACMEIssuer).Issue\n\tgithub.com/caddyserver/certmagic@v0.21.6/acmeissuer.go:371\ngithub.com/caddyserver/caddy/v2/modules/caddytls.(*ACMEIssuer).Issue\n\tgithub.com/caddyserver/caddy/v2@v2.9.1/modules/caddytls/acmeissuer.go:249\ngithub.com/caddyserver/certmagic.(*Config).obtainCert.func2\n\tgithub.com/caddyserver/certmagic@v0.21.6/config.go:626\ngithub.com/caddyserver/certmagic.doWithRetry\n\tgithub.com/caddyserver/certmagic@v0.21.6/async.go:104\ngithub.com/caddyserver/certmagic.(*Config).obtainCert\n\tgithub.com/caddyserver/certmagic@v0.21.6/config.go:700\ngithub.com/caddyserver/certmagic.(*Config).ObtainCertAsync\n\tgithub.com/caddyserver/certmagic@v0.21.6/config.go:505\ngithub.com/caddyserver/certmagic.(*Config).manageOne.func1\n\tgithub.com/caddyserver/certmagic@v0.21.6/config.go:415\ngithub.com/caddyserver/certmagic.(*jobManager).worker\n\tgithub.com/caddyserver/certmagic@v0.21.6/async.go:73"}
Oct 21 23:03:53 calcifer caddy[1580]: {"level":"error","ts":1761048233.4504573,"logger":"tls.obtain","msg":"could not get certificate from issuer","identifier":"URL4.com.au","issuer":"acme-v02.api.letsencrypt.org-directory","error":"[URL4.com.au] solving challenges: presenting for challenge: adding temporary record for zone \"URL4.com.au.\": got error status: HTTP 400: [{Code:6003 Message:Invalid request headers ErrorChain:[{Code:6111 Message:Invalid format for Authorization header}]}] (order=https://acme-v02.api.letsencrypt.org/acme/order/2192031295/440228620641) (ca=https://acme-v02.api.letsencrypt.org/directory)"}
Oct 21 23:03:53 calcifer caddy[1580]: {"level":"error","ts":1761048233.4504929,"logger":"tls.obtain","msg":"will retry","error":"[URL4.com.au] Obtain: [URL4.com.au] solving challenges: presenting for challenge: adding temporary record for zone \"URL4.com.au.\": got error status: HTTP 400: [{Code:6003 Message:Invalid request headers ErrorChain:[{Code:6111 Message:Invalid format for Authorization header}]}] (order=https://acme-v02.api.letsencrypt.org/acme/order/2192031295/440228620641) (ca=https://acme-v02.api.letsencrypt.org/directory)","attempt":1,"retrying_in":60,"elapsed":1.753406899,"max_duration":2592000}

That would suggesting something is wrong with the API key you provided for Cloudflare.

You are correct!

So it ended up being that I was inputting the env var incorrectly, I was using the export API_TOKEN=ABC123ETC but what I needed to do was actually sudo systemctl edit caddy and input the environment variable under the [Service] tag.

Oops!

Thanks for your help @hmoffatt

1 Like

For the record, there’s a guide for systemd env vars in the docs Keep Caddy Running — Caddy Documentation

1 Like

As the documentation that @francislavoie linked says, I think EnvironmentFile would be preferable as then you won’t have to edit the systemd service to update it.

Glad to hear you have it sorted.

1 Like