Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Could CADDY_MERCURE_JWT_SECRET be a runtime env var? #702

Open
norkunas opened this issue Nov 25, 2024 · 25 comments
Open

Could CADDY_MERCURE_JWT_SECRET be a runtime env var? #702

norkunas opened this issue Nov 25, 2024 · 25 comments

Comments

@norkunas
Copy link

I build the end docker image in the github actions. It is working properly, but I was disabled mercure.
Now after enabling it, i get:

php-1  | Error: loading initial config: loading new config: loading http app module: provision http: server srv0: setting up route handlers: route 0: loading handler modules: position 0: loading module 'subroute': provision http.handlers.subroute: setting up subroutes: route 2: loading handler modules: position 1: loading module 'mercure': provision http.handlers.mercure: a JWT key or the URL of a JWK Set for publishers must be provided

But I always provide it:

SERVER_NAME=... \
CADDY_MERCURE_JWT_SECRET=... \
docker compose ... up -d

For some reason I was getting this even before enabling mercure: WARN[0000] The "CADDY_MERCURE_JWT_SECRET" variable is not set. Defaulting to a blank string.

Now I have tried to add ARG CADDY_MERCURE_JWT_SECRET and ENV CADDY_MERCURE_JWT_SECRET=$CADDY_MERCURE_JWT_SECRET to Dockerfile and then to the github action (set also the secret for repo):

          build-args: |
            CADDY_MERCURE_JWT_SECRET=${{ secrets.CADDY_MERCURE_JWT_SECRET }}

but that didn't help.

@7-zete-7
Copy link
Contributor

Hi @norkunas!

This warning (within this project and for this environment variable) can be ignored when building a container. It is intended only for running the container.
Also, you should not pass secrets as arguments for the build, since the arguments are stored as open values ​​in the image build metadata (see https://docs.docker.com/reference/dockerfile/#arg).

Can you show your Caddyfile (how exactly mercure was disabled)?

@norkunas
Copy link
Author

Hi @norkunas!

Hey!

This warning (within this project and for this environment variable) can be ignored when building a container. It is intended only for running the container.

That bothers me everytime because I get the same log maybe 5-10 times per docker command..

Also, you should not pass secrets as arguments for the build, since the arguments are stored as open values ​​in the image build metadata (see https://docs.docker.com/reference/dockerfile/#arg).

I know, but was just trying things to make it work..

Can you show your Caddyfile (how exactly mercure was disabled)?

I just commented the mercure part totally. Is there another way?

@7-zete-7
Copy link
Contributor

That bothers me everytime because I get the same log maybe 5-10 times per docker command..

To avoid these warnings, you can, for example, set some placeholder as the value of this environment variable during the build steps. For example:

CADDY_MERCURE_JWT_SECRET=foobar docker compose ... build ...

This environment variable value will not be used during the build, it will only eliminate warnings.

I just commented the mercure part totally.

In my experience, disabling mercure by simply commenting out its configuration won't work. Mercure is connected in a different place. In the Caddyfile of this project, only its configuration is performed. And without configuring, mercure does not receive the parameters necessary for its operation, generating this error.

If this is useful: in my projects, I disabled mercure by disabling access to it and changing its transport to local://local (to disable storing history, see https://mercure.rocks/docs/hub/config#directives).

I myself wondered how to correctly disable mercure via configuration. So far, I have only been able to figure out that mercure must be excluded from the FrankenPHP/Caddy build to disable it.

@norkunas
Copy link
Author

I disabled mercure by disabling access to it and changing its transport to local://local

Thanks, good to know.
But the point that I came up to the point where I need to use mercure in my project.
So the problem is that it still doesn't use my given CADDY_MERCURE_JWT_SECRET and gives the warning 😞

@7-zete-7
Copy link
Contributor

So the problem is that it still doesn't use my given CADDY_MERCURE_JWT_SECRET and gives the warning 😞

To clarify:

  • Error: loading initial config: loading new config: loading http app module: provision http: server srv0: setting up route handlers: route 0: loading handler modules: position 0: loading module 'subroute': provision http.handlers.subroute: setting up subroutes: route 2: loading handler modules: position 1: loading module 'mercure': provision http.handlers.mercure: a JWT key or the URL of a JWK Set for publishers must be provided — an error in an already running FrankenPHP/Caddy container due to the lack of mercure configuration.
  • WARN[0000] The "CADDY_MERCURE_JWT_SECRET" variable is not set. Defaulting to a blank string. — a warning when running Docker Compose about the environment variable required for the current compose.yaml files not being passed. No containers or images are affected by this warning. This warning occurs when reading the Docker Compose configuration (the same warning can be obtained by running docker compose ... config).

To avoid getting the warning during the build, you can simply use a placeholder as the value of this environment variable.

If this warning appears when running the project, it is likely that this environment variable is not set.

Are you currently getting this warning during build or run?

@norkunas
Copy link
Author

I'm getting the warning during the run.

My compose.prod.yaml contains:

environment:
    CADDY_MERCURE_JWT_SECRET: ${CADDY_MERCURE_JWT_SECRET}
    MERCURE_PUBLISHER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET}
    MERCURE_SUBSCRIBER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET}

@7-zete-7
Copy link
Contributor

@norkunas, Thanks for the information about the environment variable configuration in your compose.yaml file.

What command do you use to run?
Or which GitHub job is being launched?

@norkunas
Copy link
Author

My build action (it does not give any warning about CADDY_MERCURE_JWT_SECRET):

jobs;
  docker:
    permissions:
      contents: read
      packages: write
    runs-on: ubuntu-latest
    steps:
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Login to GitHub Container Registry
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - uses: actions/checkout@v4

      - name: Build and push Docker image
        id: docker_build
        uses: docker/build-push-action@v5
        with:
          context: .
          target: frankenphp_prod
          push: true

And the command which I run in server (which I've provided in my opening comment):

SERVER_NAME=... \
CADDY_MERCURE_JWT_SECRET=... \
docker compose -f compose.yaml -f compose.prod.yaml up -d

@norkunas
Copy link
Author

I have added a placeholder to the docker_build step, but it's still the same:

$ ./pull.sh && ./stop.sh && ./start.sh
[+] Pulling 40/40
 ✔ php Skipped - Image is already being pulled by scheduler                                                                                                0.0s 
 ✔ messenger Skipped - Image is already being pulled by scheduler                                                                                          0.0s 
 ✔ messenger2 Skipped - Image is already being pulled by scheduler                                                                                         0.0s 
 ✔ scheduler Pulled                                                                                                                                       18.5s 
   ✔ 2d429b9e73a6 Already exists                                                                                                                           0.0s 
   ✔ 7759049b801c Already exists                                                                                                                           0.0s 
   ✔ 9561d3cce706 Already exists                                                                                                                           0.0s 
   ✔ 2110a07a2e02 Already exists                                                                                                                           0.0s 
   ✔ 6d59d0c29399 Already exists                                                                                                                           0.0s 
   ✔ fdf3da526140 Already exists                                                                                                                           0.0s 
   ✔ 193efd3a556b Already exists                                                                                                                           0.0s 
   ✔ df86d4bbd5a1 Already exists                                                                                                                           0.0s 
   ✔ 6f33ab910a25 Already exists                                                                                                                           0.0s 
   ✔ 099bcf515c82 Already exists                                                                                                                           0.0s 
   ✔ 4488bb68e9da Already exists                                                                                                                           0.0s 
   ✔ f6c07c8e080f Already exists                                                                                                                           0.0s 
   ✔ b62d50ba6386 Already exists                                                                                                                           0.0s 
   ✔ 620a3f2470b9 Already exists                                                                                                                           0.0s 
   ✔ 72d274db215c Already exists                                                                                                                           0.0s 
   ✔ 64e1c5895a74 Already exists                                                                                                                           0.0s 
   ✔ f1c641049db7 Already exists                                                                                                                           0.0s 
   ✔ 4f4fb700ef54 Already exists                                                                                                                           0.0s 
   ✔ 12d13a1d8114 Pull complete                                                                                                                            1.3s 
   ✔ 00302af6eb53 Pull complete                                                                                                                            1.7s 
   ✔ caa106ebe634 Pull complete                                                                                                                           10.7s 
   ✔ ba91446c2237 Pull complete                                                                                                                           10.7s 
   ✔ 2bec3f07bd43 Pull complete                                                                                                                           10.7s 
   ✔ 8fcdc1bcd2d7 Pull complete                                                                                                                           10.8s 
   ✔ 92680e959cd8 Pull complete                                                                                                                           10.8s 
   ✔ 5a3af6b6de2a Pull complete                                                                                                                           10.8s 
   ✔ ca76f53eca3e Pull complete                                                                                                                           10.8s 
   ✔ 4921ab1d13c6 Pull complete                                                                                                                           10.9s 
   ✔ deb97abbbdcb Pull complete                                                                                                                           10.9s 
   ✔ cf40e981645f Pull complete                                                                                                                           15.8s 
   ✔ bf4b56b165a6 Pull complete                                                                                                                           16.6s 
   ✔ fef547a8c374 Pull complete                                                                                                                           16.6s 
   ✔ de62226a5212 Pull complete                                                                                                                           16.9s 
 ✔ meilisearch Pulled                                                                                                                                      1.1s 
 ✔ redis Pulled                                                                                                                                            1.1s 
 ✔ database Pulled                                                                                                                                         1.1s 
5330736d5fa1
c0025f947371
3e32b1fb7044
667d8a8c4c11
fe170f681777
d65d48f1c2ed
2ce77fd5ea29
5330736d5fa1
c0025f947371
3e32b1fb7044
667d8a8c4c11
fe170f681777
d65d48f1c2ed
2ce77fd5ea29
WARN[0000] The "CADDY_MERCURE_JWT_SECRET" variable is not set. Defaulting to a blank string. 
WARN[0000] The "CADDY_MERCURE_JWT_SECRET" variable is not set. Defaulting to a blank string. 
WARN[0000] The "CADDY_MERCURE_JWT_SECRET" variable is not set. Defaulting to a blank string. 
WARN[0000] The "CADDY_MERCURE_JWT_SECRET" variable is not set. Defaulting to a blank string. 
WARN[0000] The "CADDY_MERCURE_JWT_SECRET" variable is not set. Defaulting to a blank string. 
WARN[0000] The "CADDY_MERCURE_JWT_SECRET" variable is not set. Defaulting to a blank string. 
WARN[0000] The "CADDY_MERCURE_JWT_SECRET" variable is not set. Defaulting to a blank string. 
WARN[0000] The "CADDY_MERCURE_JWT_SECRET" variable is not set. Defaulting to a blank string. 
WARN[0000] The "CADDY_MERCURE_JWT_SECRET" variable is not set. Defaulting to a blank string. 
WARN[0000] The "CADDY_MERCURE_JWT_SECRET" variable is not set. Defaulting to a blank string. 
WARN[0000] The "CADDY_MERCURE_JWT_SECRET" variable is not set. Defaulting to a blank string. 
WARN[0000] The "CADDY_MERCURE_JWT_SECRET" variable is not set. Defaulting to a blank string. 
WARN[0000] The "CADDY_MERCURE_JWT_SECRET" variable is not set. Defaulting to a blank string. 
WARN[0000] The "CADDY_MERCURE_JWT_SECRET" variable is not set. Defaulting to a blank string. 
WARN[0000] The "CADDY_MERCURE_JWT_SECRET" variable is not set. Defaulting to a blank string. 
WARN[0000] The "CADDY_MERCURE_JWT_SECRET" variable is not set. Defaulting to a blank string. 
[+] Running 7/7
 ✔ Container meilisearch-1  Started                                                                                                                   0.6s 
 ✔ Container redis-1        Started                                                                                                                   0.7s 
 ✔ Container database-1     Started                                                                                                                   0.7s 
 ✔ Container php-1          Started                                                                                                                   1.1s 
 ✔ Container messenger-1    Started                                                                                                                   0.9s 
 ✔ Container scheduler-1    Started                                                                                                                   1.0s 
 ✔ Container messenger2-1   Started  

@7-zete-7
Copy link
Contributor

@norkunas, can you show content of your ./start.sh file?

Seems like the CADDY_MERCURE_JWT_SECRET environment variable isn't set or sets incorrectly.

@norkunas
Copy link
Author

norkunas commented Nov 25, 2024

I add it third time 😁

SERVER_NAME=... \
CADDY_MERCURE_JWT_SECRET=... \
docker compose -f compose.yaml -f compose.prod.yaml up -d

I'm passing more env variables but not listed them here, and they are correctly read in backend

@7-zete-7
Copy link
Contributor

Tried running with and without this environment variable:

  • without environment variable
    $ docker compose -f compose.yaml -f compose.prod.yaml config >/dev/null
    WARN[0000] The "CADDY_MERCURE_JWT_SECRET" variable is not set. Defaulting to a blank string.
    WARN[0000] The "CADDY_MERCURE_JWT_SECRET" variable is not set. Defaulting to a blank string.
    WARN[0000] The "CADDY_MERCURE_JWT_SECRET" variable is not set. Defaulting to a blank string.
    WARN[0000] The "CADDY_MERCURE_JWT_SECRET" variable is not set. Defaulting to a blank string.
    WARN[0000] The "CADDY_MERCURE_JWT_SECRET" variable is not set. Defaulting to a blank string.
  • with environment variable
    $ CADDY_MERCURE_JWT_SECRET=foobar docker compose -f compose.yaml -f compose.prod.yaml config >/dev/null

Even a completely copied example does not trigger a warning:

$ SERVER_NAME=... \
CADDY_MERCURE_JWT_SECRET=... \
docker compose -f compose.yaml -f compose.prod.yaml config >/dev/null

(ran with dots as is 😄)

It seems very likely that the environment variable is not being set. Or it is set somehow incorrectly.
It is difficult to say without a reproducer.

@norkunas
Copy link
Author

norkunas commented Nov 25, 2024

Then I don't understand why it does not properly take only this specific env var value :(

Thanks for the help. Will try to reproduce with a clean sf app and a fresh mind tomorrow

@7-zete-7
Copy link
Contributor

As the weirdest (and most security-questionable) way to test whether this environment variable is passed, try setting the variable via export before running docker compose ... up -d ...:

export CADDY_MERCURE_JWT_SECRET=...

SERVER_NAME=... \
docker compose -f compose.yaml -f compose.prod.yaml up -d

@norkunas
Copy link
Author

norkunas commented Nov 27, 2024

As the weirdest (and most security-questionable) way to test whether this environment variable is passed, try setting the variable via export before running docker compose ... up -d ...:

export CADDY_MERCURE_JWT_SECRET=...

SERVER_NAME=... \
docker compose -f compose.yaml -f compose.prod.yaml up -d

and this works for some reason 🤔

when trying to build up a reproducer I've found a difference that I've been including additionally CADDY_MERCURE_JWT_SECRET in environment to compose.yaml and compose.prod.yaml for each container, but removing them didn't make a difference

EDIT: too early for rejoice, phpinfo shows $_SERVER['CADDY_MERCURE_JWT_SECRET'] => just_a_placeholder which I've set as you mentioned in the build step 🤔

additional unrelated funny thing I have with APP_SECRET - it is always taken from .env even I provide it to docker compose up command same as CADDY_MERCURE_JWT_SECRET and I even removed composer dump-env prod from Dockerfile

@7-zete-7
Copy link
Contributor

@norkunas, maybe, as a guess, you have a commented line with one of the environment variables, or a backslash is missing at the end of one of the lines with environment variables? I have come across this more than once 😅

FIRST_VAR=foo \
#SECOND_VAR=bar \
THIRD_VAR=baz \
docker compose ... up -d ...

additional unrelated funny thing I have with APP_SECRET - it is always taken from .env even I provide it to docker compose up command same as CADDY_MERCURE_JWT_SECRET and I even removed composer dump-env prod from Dockerfile

This template has a rather complex system of calculating environment variables. Environment variables are taken from the .env file twice: by Docker Compose (and can be passed through, if configured so, into the container) and by Symfony itself. However, environment variables passed at run have the highest priority over environment variables in .env.

@norkunas
Copy link
Author

norkunas commented Nov 29, 2024

maybe, as a guess, you have a commented line with one of the environment variables, or a backslash is missing at the end of one of the lines with environment variables?

none of these :(

This template has a rather complex system of calculating environment variables. Environment variables are taken from the .env file twice: by Docker Compose (and can be passed through, if configured so, into the container) and by Symfony itself. However, environment variables passed at run have the highest priority over environment variables in .env.

but for some reason app_secret doesn't take the one passed 😑

the two problematic env vars for me are APP_SECRET AND CADDY_MERCURE_JWT_SECRET. All others are working properly.

@7-zete-7
Copy link
Contributor

In this case, the question is in the contents of the start.sh file (not its short version, there are no errors in it), which handler (sh, bash, zsh, etc) it is launched by and what handler options (see set) are configured for this file.

Testing via export showed that environment variables are passed to the command. It turns out that they are somehow not passed directly to the command.

For debugging purposes, you can try replacing the docker compose ... command with the env command and see what environment variables are passed in this run. I assume that APP_SECRET, CADDY_MERCURE_JWT_SECRET and some other environment variables will not be present as a result.

@7-zete-7
Copy link
Contributor

As a simpler solution, I would suggest using a .env.local file to pass environment variables to Docker Compose.

.env.local

APP_SECRET=...
CADDY_MERCURE_JWT_SECRET=...
# ...

Then change Docker Compose to this

$ docker compose --env-file .env --env-file .env.local ...

(see https://docs.docker.com/reference/cli/docker/compose/#options)

or this

COMPOSE_ENV_FILES=.env,.env.local docker compose ...

(see https://docs.docker.com/compose/how-tos/environment-variables/envvars/#compose_env_files)

@norkunas
Copy link
Author

norkunas commented Dec 2, 2024

But with these approaches all of the env vars will be passed to all containers?

@norkunas
Copy link
Author

norkunas commented Dec 2, 2024

I've tried with .env file, and now via phpinfo I see that caddy_mercure_jwt_secret is set, but for some reason i still get WARN[0000] The "CADDY_MERCURE_JWT_SECRET" variable is not set. Defaulting to a blank string. warning 😂
Even APP_SECRET at last is not from the default .env file which is stored in git

@7-zete-7
Copy link
Contributor

7-zete-7 commented Dec 3, 2024

I've tried with .env file, and now via phpinfo I see that caddy_mercure_jwt_secret is set

Interesting: if this environment variable is not forwarded in compose.yaml files, this environment variable should not be declared in the container (even if it is in .env files).

Docker Compose does not pass environment variables passed to it through.

This command can be used to get the environment variables passed to the container in a more accurate way:

docker compose ... run --rm --no-deps php env

The environment variables passed to Docker Compose can be checked using the command (here docker compose ... is replaced by env):

FOO=... \
BAR=... \
BAZ=... \
env

All .env files listed in the --env-file parameter will also be used to pass them to Docker Compose (not to the container).

Just in case: the services[].env_file attribute performs a different task — it passes all environment variables from the file to the container; Docker Compose does not work with them. This attribute will not be suitable for passing APP_SECRET and CADDY_MERCURE_JWT_SECRET environment variables to Docker Compose.

@norkunas
Copy link
Author

norkunas commented Dec 3, 2024

Just in case: the services[].env_file attribute performs a different task — it passes all environment variables from the file to the container; Docker Compose does not work with them. This attribute will not be suitable for passing APP_SECRET and CADDY_MERCURE_JWT_SECRET environment variables to Docker Compose.

But i see an inverted behavior - they are properly exposed in my container while previously they were not 😮 (expect one env variable which I've needed to left in my start.sh)

I don't properly understand the difference between:

  • just passing env vars via command line;
  • defining in compose.yaml: ENV_VAR: ${ENV_VAR}; (as it uses interpolation I'd think that I still need to provide via cmd and then it'd be forwarded to container??)
  • using env_file;

😞

@7-zete-7
Copy link
Contributor

7-zete-7 commented Dec 3, 2024

Environment variables from files listed in the services[].env_file attribute are passed through to the container, without being processed by Docker Compose.

Environment variables from files listed in the --env-file option are processed by Docker Compose (like those passed explicitly) and are not passed through to the container.

Basic environment variable behavior (true for both Docker Compose and Symfony): explicitly declared environment variables have higher priority than those declared in .env files.

See https://docs.docker.com/compose/how-tos/environment-variables/envvars-precedence/

Examples of interacting with Docker Compose environment variables

Docker Compose's environment only

$ cat .env

$ cat compose.yaml
services:
  printenv:
    image: busybox:latest
    environment:
      FORWARDED_VALUE: ${FORWARDED_VALUE:-2}
      COMBINED_VALUE: "plain:${PLAIN_VALUE:-1};forwarded:${FORWARDED_VALUE:-2}"
      FINAL_VALUE: "3"
    command: ["printenv"]

$ docker compose run --rm printenv
FORWARDED_VALUE=2
COMBINED_VALUE=plain:1;forwarded:2
FINAL_VALUE=3

Explicitly declared environment variables without .env file

$ cat .env

$ cat compose.yaml
services:
  printenv:
    image: busybox:latest
    environment:
      FORWARDED_VALUE: ${FORWARDED_VALUE:-2}
      COMBINED_VALUE: "plain:${PLAIN_VALUE:-1};forwarded:${FORWARDED_VALUE:-2}"
      FINAL_VALUE: "3"
    command: ["printenv"]

$ SOME_VALUE=400 FORWARDED_VALUE=200 PLAIN_VALUE=100 FINAL_VALUE=300 docker compose run --rm printenv
FORWARDED_VALUE=200
COMBINED_VALUE=plain:100;forwarded:200
FINAL_VALUE=3

.env file only

$ cat .env
SOME_VALUE=40
FORWARDED_VALUE=20
FINAL_VALUE=30

$ cat compose.yaml
services:
  printenv:
    image: busybox:latest
    environment:
      FORWARDED_VALUE: ${FORWARDED_VALUE:-2}
      COMBINED_VALUE: "plain:${PLAIN_VALUE:-1};forwarded:${FORWARDED_VALUE:-2}"
      FINAL_VALUE: "3"
    command: ["printenv"]

$ docker compose run --rm printenv
FORWARDED_VALUE=20
COMBINED_VALUE=plain:1;forwarded:20
FINAL_VALUE=3

Explicitly declared environment variables and .env file

$ cat .env
SOME_VALUE=40
FORWARDED_VALUE=20
FINAL_VALUE=30

$ cat compose.yaml
services:
  printenv:
    image: busybox:latest
    environment:
      FORWARDED_VALUE: ${FORWARDED_VALUE:-2}
      COMBINED_VALUE: "plain:${PLAIN_VALUE:-1};forwarded:${FORWARDED_VALUE:-2}"
      FINAL_VALUE: "3"
    command: ["printenv"]

$ SOME_VALUE=400 PLAIN_VALUE=100 FINAL_VALUE=300 docker compose run --rm printenv
FORWARDED_VALUE=20
COMBINED_VALUE=plain:100;forwarded:20
FINAL_VALUE=3

@norkunas
Copy link
Author

norkunas commented Dec 7, 2024

Thank you @7-zete-7 for a thorough explanation, will see if i'll be able to fix my issues

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants