2

When using Symfony inside a container, %env(csv:...)% seems to break when populating a config option that expects an array. For example, in config/packages/framework.yaml:

# see https://symfony.com/doc/current/reference/configuration/framework.html
framework:
 trusted_proxies: '%env(string:APP_TRUSTED_PROXIES)%'
 trusted_headers: '%env(csv:APP_TRUSTED_HEADERS)%'

Because .env files are not read in my containerized setup, I set APP_TRUSTED_HEADERS via Docker Compose as a comma-separated string.

Running:

docker compose exec php php bin/console debug:container --env-vars | grep APP_

I get:

In BaseNode.php line 496:
 
 Invalid type for path "framework.trusted_headers.0". Expected one of "bool" 
 , "int", "float", "string", but got "array". 

trusted_headers expects an array<int, int|bool|string>, but Symfony complains it receives an array<int, array>.

How to reproduce? Start a new Symfony app in Docker (I used the FrankenPHP image from symfony-docker):

git clone https://github.com/dunglas/symfony-docker
cd symfony-docker
docker compose build --pull --no-cache
docker compose up --wait

Then edit the config/packages/framework.yaml and add:

framework:
 trusted_headers: '%env(csv:APP_TRUSTED_HEADERS)%'

In compose.yaml, define the env var. I tried the following (each variant tested separately):

service:
 php:
 environment:
 APP_TRUSTED_HEADERS: forwarded,x-forward-port # does NOT WORK
 APP_TRUSTED_HEADERS: forwarded # does NOT WORK
 APP_TRUSTED_HEADERS: "forwarded" # does NOT WORK
 APP_TRUSTED_HEADERS: "'forwarded'" # does NOT WORK
 APP_TRUSTED_HEADERS: "${APP_TRUSTED_HEADERS}" # with the host env set

All variants result in the same error. I read "Environment variable processors", this post about "Environment variables in a dockerized Symfony" and How to Configure Symfony to Work behind a Load Balancer or a Reverse Proxy

What am I doing wrong, and how should APP_TRUSTED_HEADERS be passed so that %env(csv:...)% resolves to a flat array of strings?

Note on possible duplicates

I’ve read "docker-compose variable substitution/interpolation with list/map or array values?" and I believe this is not a duplicate: I’m not trying to pass an array via Compose.

I’m intentionally passing a single comma-separated string (e.g., forwarded,x-forwarded-for,...) and relying on Symfony’s %env(csv:VAR)% processor to parse it at runtime. The problem is that, even with a plain string in the container env, Symfony ends up treating framework.trusted_headers.0 as an array (i.e., array). So this question is about Symfony/Dotenv CSV processing in a containerized setup, not Compose array interpolation.

halfer
20.1k19 gold badges110 silver badges207 bronze badges
asked Sep 1 at 13:30
2
  • 1
    You can run docker compose exec php env | grep APP_TRUSTED_HEADERS to check the value of APP_TRUSTED_HEADERS, to ensure that it is passed properly to the container. Commented Sep 1 at 19:54
  • 1
    Are you sure this is related to Docker at all? Does it work when using a "plain" PHP setup with the given configuration? Checking this helps to rule out whether this is a problem with PHP, Symfony, or Docker Commented Sep 3 at 11:24

3 Answers 3

1

The /framework/trusted_headers is always treated as a plain scalar, even if properly tagged as sequence.

What happens is, that Symfony renders it as the first member of the sequence then, e.g.:

framework:
 trusted_headers: XXX

effectively becomes:

framework:
 trusted_headers:
 - XXX

This is also the reason why the schema validation reports an array on the first member of the sequence with the built-in environment variable processor that decoded the environment parameter value into an array:

Invalid type for path "framework.trusted_headers.0". Expected one of "bool"
, "int", "float", "string", but got "array".

This is now an array inside an array. From the Symfony configuration guidelines you have to put the array into the YAML file.

The single test on the trusted_headers configuration setting is limited to a single only for SYMFONY_TRUSTED_HEADERS (#58161), the underlying parameter and the latest step towards featuring the environment.

answered Sep 2 at 17:49
0

I found a solution with the new simpler trusted proxies configuration .

In Symfony 7.2 we're simplifying this thanks to new environment variables. Instead of configuring the previous file, you can now set the trusted proxies configuration in these env vars:

  • SYMFONY_TRUST_X_SENDFILE_TYPE_HEADER

  • SYMFONY_TRUSTED_HEADERS

  • SYMFONY_TRUSTED_HOSTS

  • SYMFONY_TRUSTED_PROXIES

So I removed the two configuration lines in my framework.yaml file.

framework.yaml is empty, so the default configuration is applied:

framework:
 trusted_proxies: '%env(default:SYMFONY_TRUSTED_PROXIES)%'
 trusted_headers: '%env(default:SYMFONY_TRUSTED_HEADERS)%'

And I updated my compose.<environment>.yaml files

# compose.test.yaml
services:
 php:
 environment:
 # All private subnets are trusted in test environment
 SYMFONY_TRUSTED_PROXIES: PRIVATE_SUBNETS
 SYMFONY_TRUSTED_HEADERS: x-forwarded-host,x-forwarded-proto,x-forwarded-port
# compose.dev.yaml
services:
 php:
 environment:
 SYMFONY_TRUSTED_PROXIES: 
 SYMFONY_TRUSTED_HEADERS: 
# compose.prod.yaml
services:
 php:
 environment:
 SYMFONY_TRUSTED_PROXIES: 172.16.0.xxx # The IP of your reverse-proxy 
 SYMFONY_TRUSTED_HEADERS: x-forwarded-host,x-forwarded-proto,x-forwarded-port
answered Sep 3 at 7:29
1
  • If that was the answer, then please review the question and my answer as I pointed to SYMFONY_TRUSTED_HEADERS specifically. Didn't dv btw, but you should give credit where credit is due. If you think otherwise, feedback appreciated. Commented yesterday
-2

The issue comes from how Docker/YAML handles quotes. Symfony’s %env(csv:...)% expects a plain comma separated string, but if you add quotes or extra characters, it sees each element as an array instead of a string. That’s why you get the Invalid type for path "framework.trusted_headers.0" error.

In your docker-compose.yml, pass the environment variable without the quotes:

services:
 php:
 environment:
 APP_TRUSTED_HEADERS: forwarded,x-forwarded-for,client-ip

In your framework.yaml, use the CSV processor like this:

framework:
 trusted_proxies: '%env(string:APP_TRUSTED_PROXIES)%'
 trusted_headers: '%env(csv:APP_TRUSTED_HEADERS)%'

And then check inside the container:

docker compose exec php bash
echo $APP_TRUSTED_HEADERS
php bin/console debug:container --env-vars | grep APP_TRUSTED_HEADERS

You should see a flat string, and Symfony will correctly convert it into an array.

answered Sep 1 at 21:05
New contributor
Roman is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
3
  • 1
    Do you have any resource about how Docker/YAML handles quotes like that ? I tried to test it but I always get a plain string value, and OP already tried defining the value without quotes (see his first attempt on the list). Commented Sep 2 at 8:30
  • 1
    I'm sorry, but This is exactly what I've done! And Symfony doesn't convert it correctly ! (And your solution is exactly what I've described in my first test. Does it really work with your environment? Commented Sep 2 at 9:16
  • 1
    And yet, the question mentions they use your proposed solution, and they claim it does not work. Why don't you address this on the answer? Commented Sep 2 at 9:37

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.