Passing config via environment variable

I’m using a Caddy server deployed as a container, I need to pass a configuration to the Caddy server without “wrapping” the Caddy image with my own private repository/registry (e.g. AWS ECR). I’m looking to override the default configuration and provide my own, just using an environment variable (no extra infrastructure/API setups).

Would it be possible, happy to make a PR, to update the Caddy image to check for a Caddy config from an environment variable and replace that on startup? I have given this some thought and think it would be nice to have an environment variable named CADDY_CONFIG_BASE64 that the image would be able to detect, decode, and replace the default Caddy configuration in the image. This would prevent “wrapping” the public image with a private one, just to copy a single file into the container.

Would this be a feature worth discussing/adding to the image build process?

Note: Happy to make this an issue on Github if that makes more sense.

1 Like

Hey Jason! Welcome back to the forum :slight_smile:

We intentionally do not take config from outside a config file (or the API, technically) because then the config is harder to lose track of and is more self-contained and portable.

But have you tried setting the entire config in an env variable and then using {$CADDY_CONFIG} in your Caddyfile?

If the platform you’re using supports Swarm, you can use this: Store configuration data using Docker Configs | Docker Documentation

1 Like

Thanks @matt!

I don’t think I was really clear. What I am imagining is creating an docker-entrypoint.sh shell script as the ENTRYPOINT for the container image. Everything else would stay the same.

The docker-entrypoint.sh script would look something like this:

#!/usr/bin/env sh
set -e

# is the caddy config base64 environment set?
if [ -n "$CADDY_CONFIG_BASE64" ]; then
    # decode the base64 config and replace the Caddyfile
    echo "$CADDY_CONFIG_BASE64" | base64 -d > /etc/caddy/Caddyfile
fi

exec "${@}"

Note: I borrowed some of this from the Envoy Proxy container image entrypoint.

Adding the entrypoint script allows for the following:

  1. We don’t need to wrap a public container image (e.g. caddy:2.6) into a private one to override a single file.
  2. When deploying to any container platform, we only need to define an environment variable to override the Caddyfile that ships with the image using the upstream image (e.g. caddy:2.6), then Caddy can continue to watch the file as it deems necessary because it would override the file during container creation.
  3. This would not be a breaking change as nothing happens in the container/existing image unless that environment variable is set.
  4. The exec "${@}" line would still allow passing commands to caddy, so the existing use cases of the images would still work

Clearly this is a quick script thrown together to show the use case, it would need a little more thought process to ensure all of the other image use cases are covered (hence the link to the Envoy Proxy entrypoint).

Does that make more sense?

I’m thinking about a more generic image change that all platforms can benefit from, I provided more details in the most recent reply to make my use case clear.

Problem is, using any docker-entrypoint.sh has baggage, because it won’t properly forward signals to the underlying process by default, among other gotchas.

I don’t agree with that approach though. There’s a bevy of ways to mount a file into the container. We don’t need to add another non-standard way.

If you want an image with an entrypoint like that, then I suggest you make your own image and publish it to Docker Hub or whatever. That’s what those services are there for.

I think you’re overstating the benefits. Very few users would actually use this. Your usecase is definitely niche.

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