I’m new to Caddy, so there are likely some big holes in my thinking here, but I wanted to see if there was any interest in re-sparking the conversation around adding syntax support for macros with arguments as mentioned in topic #2852 (or if there is currently an ongoing discussion about something along these lines that I missed, please point me in the right direction).
I understand one of the goals of the Caddyfile syntax is to minimize repetition and I think something along the lines of what I’m proposing below could take that goal to the next level.
My Caddyfile on my dev machine has 15 vhosts all setup identically except for the host and the proxy port. Each vhost is defined as shown below, causing a lot of repetition and making my Caddyfile longer than my old comparable nginx config. As far as I can tell, snippets cannot solve this problem.
project-one.tld {
proxy / localhost:24611 {
transparent
}
tls self_signed
}
# ... +14 more of these
So what if instead I was able to define a macro for my common vhost setup like this:
# define macro
def @vhost(host, proxy_port) {
[host] {
proxy / localhost:[proxy_port] {
transparent
}
[...] # defines where the body of the macro should be inserted when called
}
}
# call macro like a directive with or without a body
@vhost project-one.tld 24611
@vhost project-2.tld 24612 {
tls self_signed
}
It ends up feeling like a directive when you use it, but the @ saves you from namespace conflicts and let’s you know to look for that definition above (or from an above import).
Thoughts? As I said at the top of this message, I’m sure there are some pretty big holes in my thinking here, but I just wanted to get the conversation going again
Not really – the goal is to be simple and readable, not necessarily to reduce repetition. Repetition, though not ideal when things change, is at least plain and simple. We really don’t want to make the Caddyfile programmable… instead, opt for config file generation.
Have you looked at Caddyfile snippets? They seem to be closest to what you’re asking for.
I’d still probably opt to use the import directive and perhaps feed it parameters via subdirective block, if I were implementing something like this.
That said, you’re essentially making functions in the Caddyfile. It’s a big leap for complexity. This kind of task is quite well achieved by templating config generation.
Thanks for the quick reply I was basing my assumption of a goal of minimal repetition off of your blog post here where you said:
A few distinct features of the Caddyfile are: very low duplication, almost no punctuation, irrelevant extraneous whitespace… The Caddyfile is designed to reduce identical, duplicate lines and reduce the amount of typing overall.
If that’s not one of the main goals with the syntax then I see where you’re coming from.
I have seen snippets, and as I understand it they wouldn’t solve my problem. My current caddy file looks like this:
If I understand right, using snippets would only increase the number of lines in my Caddyfile, though it would give me the benefit of only having to edit shared code in one place.
While it definitely is an increase in complexity, I don’t know if I would go as far as calling it a function, it’s more like a super simple template for concise config generation.
Yes, config generation would be one way to not have to repeat myself. But it seems more like an escape hatch that allows you to do all sorts of things at the cost of extra project complexity. It’s a tradeoff.
I totally understand if something like this is not a priority for the Caddy project, but I see it as something only slightly more complex than the snippets (there’s no logic in these macros, just simple string formatting), but much more useful.