lucaslorentz / caddy-docker-proxy

Caddy as a reverse proxy for Docker
MIT License
2.86k stars 168 forks source link

How to use environment variable for basicauth user ? #466

Open hollowshiroyuki opened 1 year ago

hollowshiroyuki commented 1 year ago

Hello !

Is there a way to set the user for the basicauth directive with an environment variable ?

https://caddyserver.com/docs/caddyfile/directives/basicauth

The usual syntax would be :

caddy.basicauth: "* bcrypt"
caddy.basicauth.admin: "${HASHED_PASSWORD}"

But the yaml keys in docker compose doesn't resolve environment so : caddy.basicauth.${USER}: "${HASHED_PASSWORD}" won't work.

Isn't there a syntax where we can "hardcode" the block or part of it like :

caddy.basicauth: "* bcrypt { ${USER} ${HASHED_PASSWORD} }"

Thanks for your assistance ! Best regards, Hollow

emilylange commented 1 year ago

As you already found out, variable substitution/interpolation in docker-compose does only work for values, not keys.

You could, however, use snippets and {args.*}with import instead. See https://caddyserver.com/docs/caddyfile/concepts#snippets

Let me know if I should provide you with an example if the docs are unclear :)

hollowshiroyuki commented 1 year ago

Thanks for the suggestion ! I thought about using snippets but didn't know about {args.*}.

But now I have a weird behavior with this :

caddy_0: "(basic_auth)"
caddy_0.basicauth: "* bcrypt"
"caddy_0.basicauth.{args.0}": "${HASHED_PASSWORD}"

caddy_1: "domain"
caddy_1.import: "basic_auth ${USER}"
caddy_1.reverse_proxy: "container:80"

The logs outputs this :

{
    "level": "info",
    "ts": 1677263426.517001,
    "logger": "docker-proxy",
    "msg": "New Caddyfile",
    "caddyfile": "(basic_auth) {\n\tbasicauth * bcrypt {\n\t\t{args {\n\t\t\t0} [REDACTED]\n\t\t}\n\t}\n}\n"
}

And this error :

{
  "level": "info",
  "ts": 1677264148.9798884,
  "logger": "docker-proxy",
  "msg": "Process Caddyfile",
  "logs": "[ERROR]  Removing invalid block: parsing caddyfile tokens for 'basicauth': Caddyfile:3 - Error during parsing: username and password cannot be empty or missing\ndomain {\n\timport basic_auth username\n\treverse_proxy container:80\n}\n\n"
}

Am I doing something wrong or is it a parser issue ?

francislavoie commented 1 year ago

Yeah, that certainly looks like a bug. It's adding newlines to the args placeholder. It shouldn't do that when there's no newline or space after the {.

As a workaround, you can use CADDY_DOCKER_CADDYFILE_PATH to set up a base Caddyfile which you can mount in the Caddy container which can contain snippets, then you can use labels to import that snippet.

hollowshiroyuki commented 1 year ago

I'm using docker in combination with ansible and I was using caddy-docker-proxy to avoid copying a Caddyfile for a simple configuration. I'm just gonna use a Caddyfile templated with jinja and ansible for now. 😛

Anyways, thanks for the help !

zieddhf commented 1 year ago

Hello ! I'm actually trying to set environment variables for the basicauth user and password in my Caddyfile

the syntax is the following :

 reverse_proxy * localhost:3000

  basicauth /* {
       {$GRAFANA_USER} {$GRAFANA_PWD}
  }

I tried export command to set the environment variables but the values return empty, the only way i found is by adding Environment directive to caddy's systemd configuration.

Is there another way to to use environment variables inside my Caddyfile without modifying systemd configuration?

Best Regards !

francislavoie commented 1 year ago

@zieddhf seems like you're asking in totally the wrong place. This is for Caddy-Docker-Proxy, but you're using systemd. Please open a topic on the forums: https://caddy.community, and make sure to fill out the help topic template.