Attempt to insert "harmless" variable to Caddyfile, or remove row based on environment variable

1. The problem I’m having:

I’m trying to use the same Caddyfile in production and in local development, and rely to variables for the minor changes, such as domain names. I’m using self-created certificates for local https. Everything is working perfectly. Except that now in my caddyfile I have declared something like this:

{$DOMAIN:localhost} {
        tls /certs/site.crt /certs/site.key

        root * /srv/www/landing-page

        # Enable the static file server.
        file_server
}

On the server side this whole tls row should not exist, for caddy to setup the https automatically. It works fine if I remove it, but I want to be able to do it dynamically. I want to minimize the need for additional scripts or tools for changing config files. So I figured something like this should do it

{$DOMAIN:localhost} {
        {$PROD_HARMLESS_STRING:"tls /certs/site.crt /certs/site.key"}

        root * /srv/www/landing-page

        # Enable the static file server.
        file_server
}

Variables are served to the caddy container from docker compose using an env-file.

version: "3"

networks:
  caddynet:
    driver: bridge

services:
  caddy:
    image: caddy:latest
    container_name: caddy
    restart: unless-stopped
    ports:
      - 80:80 
      - 443:443
    volumes:
      - ./certs:/certs
      - ./caddy/Caddyfile:/etc/caddy/Caddyfile
      - ./landing-page:/srv/www/landing-page
      - /opt/caddy/config:/config
      - /opt/caddy/data:/data
    env_file:
      - vars.env
    networks:
      - caddynet

And the env file looks like this

DOMAIN=example.com
PROD_HARMLESS_STRING="vars /foo* isFoo 'yep'"

I took it from the examples for vars directive use in Caddyfile. But the container won’t run properly, and from docker logs I can see:

2. Error messages and/or full log output:

"msg":"using provided configuration","config_file":"/etc/caddy/Caddyfile","config_adapter":"caddyfile"}
Error: adapting config using caddyfile: /etc/caddy/Caddyfile:2: unrecognized directive: vars /foo* isFoo 'yep'

I tried everything I could come up with inside the PROD_HARMLESS_STRING, spaces, newlines, vars directive usage without matcher… I got the unrecognized directive error every time, even with whitespace, the error just desrcribing what I had in the variable. I’m stumped.

I know this whole approach is a bit “hacky” so I’m open to suggestions. I just want something semi-clean and simple.

3. Caddy version:

v2.7.6 h1:w0NymbG2m9PcvKWsrXO6EEkY9Ru4FJK8uQbYcev1p3A=

4. How I installed and ran Caddy:

Docker compose as described above.

a. System environment:

Ubuntu 20.04.6 LTS

b. Command:

docker-compose up -d

c. Service/unit/compose file:

Compose file provided above.

d. My complete Caddy config:

Caddyfile provided above.

I’ll need to play around with those env vars to replicate the behvaiour…

But one approach I know will work is to use import with either snippets or files.

For example, you could have two snippets (dev) and (prod), then import using an env like import {$ENV:dev} or something like that.

It does mean the config is always in your Caddyfile, but the active one gets toggled based on the env.

1 Like

Thank you so much for the prompt reply! The solution you mentioned is clean and works perfectly for us.

As a curiosity it might be nice to understand why our solution did not work in the first place, but it does not matter much, at least for me.

1 Like

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