It would seem as though Caddy v2 doesn’t yet support imports?
4. Error messages and/or full log output:
adapt: Caddyfile:40 - Error during parsing: File to import not found: tls-{env.TARGET_ENV}
5. What I already tried:
I’ve confirmed that the environment variable is available to Caddy via KUEUI_BASIC_AUTH_USERNAME=$(echo "user" | base64) KUEUI_BASIC_AUTH_PASSWORD=$(echo "pass" | base64) TARGET_ENV=local ./caddy environ | grep TARGET_ENV and the output is TARGET_ENV=local as expected.
Hmm, I don’t know that you will be able to use environment variables for importing in v2. We’re trying to take env variable logic out of the Caddyfile parser, because they are evaluated when modules are loaded, deeper in the system.
While we’re on the topic of environment variables logic in the Caddfile parser, I thought I should bring this to your attention.
This works:
example.com {
file_server * {
root /www
}
}
But the following fails with adapt: server block 0, key 0 ({env.APP_DOMAIN}): determining listener address: parsing key: parse //{env.APP_DOMAIN}: invalid character "{" in host name when being executed with APP_DOMAIN=example.com ./caddy adapt --config ./static/root/etc/Caddyfile --pretty:
Ah, fun… guess we’ll need to find a way to hopefully benefit from the Go standard library’s URL parser while allowing placeholders. Okay, added to my list…
If you’ve been following along, you’ll notice that we’re making it so that you can use {$ENV_VAR} syntax in the Caddyfile to be replaced before parsing even begins. That should probably meet your needs, I think.
This implies that {env.VAR}-style placeholders are still deferred until runtime to be evaluated.
So, this:
I am not sure we can get this to work. The Caddyfile needs to know something about the site: the port, the domain name, a path, something… but since {env.APP_DOMAIN} would only be evaluated at runtime (after the Caddyfile is adapted into JSON), the Caddyfile adapter won’t know how to structure the JSON, because it’s not sure what to make of the site address (it remains a placeholder!).
Now, in your case, you can just use {$APP_DOMAIN} and that will be replaced by the Caddyfile before tokenizing and parsing even begins, and so that should work, because in theory Caddy would have a value to work with. But using {env.APP_DOMAIN} would leave it clueless, so… I’m not sure we can get that to work.
Is that OK with you? (If not, do you have an alternative idea/solution?)
It will always generate an error similar to what I demonstrated as you mention, it needs to know something about site at adapt time.
I think there are two solutions. The first being as you mentioned, making sure APP_DOMAIN exists at adapt-time, in this scenario, the following should work:
{$APP_DOMAIN} {
file_server ...
}
The other is the following:
https://{env.APP_DOMAIN} {
file_server ...
}
I think that would work based on what I’ve seen in the PR on GitHub? It will give the Caddyfile adapter enough information to proceed:
port: 443 (implied by https).
domain: {env.APP_DOMAIN} that will be passed through into the JSON and then evaluated at runtime.
To be clear, there already will be a solution, if you don’t mind the substitution happening at the time the Caddyfile is adapted: use {$APP_DOMAIN} instead of {env.APP_DOMAIN}.
However, if the runtime environment will be different and thus you have to use {env.APP_DOMAIN}, then yeah that won’t work.
However, if you can at least give it a hint:
https://{env.APP_DOMAIN} {
...
}
That might be enough. Or {env.APP_DOMAIN}:1234 or example.com:{env.PORT} – I think these should all be able to work.
Given the alternative is landing probably tomorrow, do you really need this to work? I can add it to my list but the parsing logic to support this probably wouldn’t be simple, might take some time to figure out. (I’d rather not do it right now, unless there’s an actual and urgent need for it, if that’s alright.) Will the {$APP_DOMAIN} solution work for you?
At start time, a Caddyfile in the static container will configure Caddy. At runtime (sometime later), a dynamically generated Caddyfile compiled in the supervisor container will update Caddy’s configuration in static via the Configuration API and the POST /load endpoint.
I should say, this will all be running in Kubernetes…