Environment variables in caddy.json

1. The problem I’m having:

I’m trying to create a caddy.json config using environment variables to set some values. I can’t use CaddyFile because its not supported by some of the plugins I am using.

I can’t figure out how to use ENV vars in the caddy.json file and I can’t find it in the documentation. Can someone help me with this?

As an example, I have a debug mode env var called DEBUG (boolean)
In DEV its set to true and in PROD its set to false. It should default to false if no value is passed.
I would use this to set the “multi_error” value in my “oas_validator” handler.

Caddy version / Installation

I’m using Caddy 2.10 from the docker image and building it with the plugins using xcaddy. My final image is called ‘caddy-gateway’

Docker Compose File

services:
  caddy:
    image: caddy-gateway:latest
    ports:
      - 8080:8080
      - 5555:5555
    networks:
      - caddy
    volumes:
      - ./caddy.json:/etc/caddy/caddy.json
      - ./openapi:/etc/caddy/openapi
    command: ["caddy", "run", "--config", "/etc/caddy/caddy.json"]
    environment:
      - DEBUG=${DEBUG:-false}
      - MONITORING_PORT=5555
      - HEALTH_PATH=/health
      - METRICS_PATH=/metrics
    depends_on:
      - redis
      - httpbin
      - echo
  redis:
    image: redis:7.2.9
    networks:
      - caddy
    ports:
      - 6379:6379
  httpbin:
    image: kennethreitz/httpbin
    networks:
      - caddy
    ports:
      - 80:80
  echo:
    image: ealen/echo-server
    networks:
      - caddy
    ports:
      - 81:80

networks:
  caddy:
    driver: bridge

My complete Caddy config:

{
  "admin": {
    "disabled": false
  },
  "logging": {
    "logs": {
      "default": {
        "writer": {
          "output": "stdout"
        },
        "encoder": {
          "format": "json"
        }
      }
    }
  },
  "apps": {
    "http": {
      "http_port": 80,
      "https_port": 443,
      "servers": {
        "srv0": {
          "listen": [":8080"],
          "routes": [
            {
              "match": [{"path": ["/api/*"]}],
              "handle": [
                {"handler": "request_id"},
                {
                  "handler": "oas_validator",
                  "spec_file": "/etc/caddy/openapi/httpbin-api.json",
                  "fall_through": true,
                  "log_error": true,
                  "multi_error": true
                },
                {
                  "handler": "rewrite",
                  "strip_path_prefix": "/api"
                },
                {
                  "handler": "reverse_proxy",
                  "upstreams": [
                    {
                      "dial": "httpbin:80"
                    }
                  ]
                }
              ]
            },
            {
              "match": [
                {
                  "path": ["/echo*"]
                }
              ],
              "handle": [
                {
                  "handler": "request_id"
                },
                {
                  "handler": "oas_validator",
                  "spec_file": "/etc/caddy/openapi/echo-api.json",
                  "fall_through": true,
                  "log_error": true,
                  "multi_error": true
                },
                {
                  "handler": "reverse_proxy",
                  "upstreams": [
                    {
                      "dial": "echo:80"
                    }
                  ]
                }
              ]
            },
            {
              "handle": [
                {
                  "handler": "static_response",
                  "status_code": 404,
                  "body": "Not Found"
                }
              ]
            }
          ]
        },
        "srv1": {
          "listen": [":5555"],
          "routes": [
            {
              "match": [
                {
                  "path": ["/health"]
                }
              ],
              "handle": [
                {
                  "handler": "static_response",
                  "status_code": 200,
                  "body": "OK"
                }
              ]
            },
            {
              "match": [
                {
                  "path": ["/metrics"]
                }
              ],
              "handle": [
                {
                  "handler": "metrics"
                }
              ]
            }
          ]
        }
      }
    }
  }
}
1 Like

Thanks @timelordx . I can do that but it’s much more complicated. The way it’s handled when using CaddyFile format is super standard for these types of applications.

What you are suggesting should be done by Caddy and not as part of my CI. Caddy should take a JSON file with env vars and transform it into a JSON file with the hard coded values before using it. I’m having to create my own system of inserting placeholders into a caddy.json file which are invalid caddy syntax, and replacing them with values from my docker compose file or kubernetes environment.

Anyhow, thanks for the clarification. At least I can stop breaking my head trying to get it working.

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