Caddy – Use Environment Variables for Dynamic Processing

Last modified date

Comments: 0

I wanted to use an OS environment variable to decide if a directive in a Caddyfile site block should be processed or not. This allows for some sort of URL processing or feature to be enabled / disabled without having to recode your Caddyfile. Change the environment variable from true to false and the feature can be quickly disabled (or vice-versa).

For reference, the structure of a Caddyfile is detailed here.

Here’s the Caddyfile site block to do this:

http://{$DOMAIN} {

  root * /var/www/mysite

  @redis_enabled vars {env.REDIS_ENABLED} "true" "True" "TRUE"

  handle /thumbs/* {
    handle /*.php {
        respond 404
    }
    handle @redis_enabled {
        import redis_logging
    }
    header Cache-Control "public, max-age=2592000, immutable"
    file_server
  }
}

To explain the code:

  • This is the site block for http://$DOMAIN (the FQDN also being an environment variable).
  • The root of the website is defined
  • We then set the redis_enabled variable to the value of the environment variable called REDIS_ENABLED
    • Including the three version of true covers the environment variable being capitalised, an initial capital or not at all
    • So for any of those values matching, redis_enabled will be set to TRUE
    • If REDIS_ENABLED is false, False, blank or something else, redis_enabled is set to FALSE
  • We process any requests going to a URL which matches http://$DOMAIN/thumbs/*
    • Should the request be for any file ending .php, a 404 error is returned (so block accessing)
    • Next, if the Caddy variable redis_enabled is TRUE, we “import” the code block called redis_logging and run it
    • A header for the response is set and the file will be served by Caddy as a static file (file_server)

I put import above in quotes as code blocks (called snippets) can be declared in the Caddyfile and re-used. The import direction can also pull in configuration from other files. So the snippet called redis_logging is defined in the Global section of the same Caddyfile as this site block and I can use it multiple times as needed. If I want to change the snippet, I only have once place to amend it.

(redis_logging) {
    simple_stats {
        redis_addr {$REDIS_CONTAINER_NAME}:{$REDIS_PORT}
        prefix {$REDIS_KEY_PREFIX}:key
    }
}

Chris

Leave a Reply

Your email address will not be published. Required fields are marked *

Post comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.