By Tcoch

Docker compose & symfony : the scope of environment variables


Why this article ?

Handling environment variables, between host machine, .env file(s), and container, is not always easy. Is my variable used when building the Dockerfile ? When using docker compose ? Is it passed to my container ?
This article will address this question in regard to using FrankenPHP for building a Symfony app.
We will also focus on the APP_ENV environment variable and its actual value, depending on some cases.

Passing the environment variables

Using Symfony Docker image, some environment variables are defined to be used inside the container. Namely:
services:
  php:
    [...]
    environment:
      SERVER_NAME: ${SERVER_NAME:-localhost}, php:80
      MERCURE_PUBLISHER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET:-!ChangeThisMercureHubJWTSecretKey!}
      MERCURE_SUBSCRIBER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET:-!ChangeThisMercureHubJWTSecretKey!}
      DATABASE_URL: postgresql://${POSTGRES_USER:-app}:${POSTGRES_PASSWORD:-!ChangeMe!}@database:5432/${POSTGRES_DB:-app}?serverVersion=${POSTGRES_VERSION:-15}&charset=${POSTGRES_CHARSET:-utf8}
      MERCURE_URL: ${CADDY_MERCURE_URL:-http://php/.well-known/mercure}
      MERCURE_PUBLIC_URL: ${CADDY_MERCURE_PUBLIC_URL:-https://${SERVER_NAME:-localhost}:${HTTPS_PORT:-443}/.well-known/mercure}
      MERCURE_JWT_SECRET: ${CADDY_MERCURE_JWT_SECRET:-!ChangeThisMercureHubJWTSecretKey!}
      SYMFONY_VERSION: ${SYMFONY_VERSION:-}
      STABILITY: ${STABILITY:-stable}
I'll focus on the second one.
MERCURE_PUBLISHER_JWT_KEY will be an environment variable available in the container. Its value will either be the value of the CADDY_MERCURE_JWT_SECRET variable, on !ChangeThisMercureHubJWTSecretKey! by default.

How do you set the CADDY_MERCURE_JWT_SECRET variable value ? Here's some options:
  • The environment variable exists on your host machine: it will be used
  • A more flexible option is to use a .env file, in which you will set the environment value to the value you need
  • Alternatively, you can define the variable value in the start of your docker command(s), for example CADDY_MERCURE_JWT_SECRET=MySecret docker compose [...]
Now that this is clear, let's deploy an actual Symfony app.

Deploying an app in dev environment

Creating an app in a dev environment is quite simple ... and well explained here : https://github.com/dunglas/symfony-docker/tree/main.

When you check the various files and containers, you'll see that the APP_ENV variable has a default dev value in the frankenphp_dev image. Which means, any container using this image, will have APP_ENV=dev as its core. Cool, that's what you needed in our app anyway.

Deploying an app in test environment

To create the same app as before, but for the purpose of testing, we would assume that it works just as dev. Then, inside your container, you perform bin/console dump-env:test, and your good. Well, spoiler : no.

If you create a container for your Symfony app, in a dev environment or similar (understand: not prod environment), you will obtain a container using the frankenphp_dev image, with the APP_ENV=dev environment variable.

Now, let's connect to that container, and check what's going on.
$ git clone https://github.com/dunglas/symfony-docker.git .
Clonage dans '.'...
[...]
$ docker compose build
[...]
  Service php  Built
$ docker compose up -d
[+] Running 1/1
  Container frankenphp_test_env-php-1  Started
$ docker exec -it frankenphp_test_env-php-1 bash
root@6c03bca33d57:/app# set | grep ENV
APP_ENV=dev
root@6c03bca33d57:/app# bin/console cache:clear

    // Clearing the cache for the dev environment with debug true


 [OK] Cache for the "dev" environment (debug=true) was successfully cleared.
OK, so, by default / by design, APP_ENV is set to dev by building the frankenphp image, and we see that here. The environment variable is indeed set to dev, and when using a console command, you see that our app uses this dev env.
No worries, let's perform bin/console dump-env:test !
root@6c03bca33d57:/app# composer dump-env test
APP_ENV=dev
root@6c03bca33d57:/app# bin/console cache:clear

    // Clearing the cache for the dev environment with debug true


 [OK] Cache for the "dev" environment (debug=true) was successfully cleared.
Mmmh ... Still in dev env ! Let me check my .env.local.php file, maybe something as gone wrong.
root@6c03bca33d57:/app# cat .env.local.php
<?php

// This file was generated by running "composer dump-env test"

return array (
    'APP_ENV' => 'test',
    'SYMFONY_DOTENV_PATH' => './.env',
    'APP_SECRET' => '',
);
Seemed to have worked fine ...
Yet, my app doesn't know it ... Yes, because your server environment variable (which means in this case, the container environment variables) are preferred over the app definitions !

And yes, this is mentioned in the official documentation :
https://symfony.com/doc/current/configuration.html#configuring-environment-variables-in-env-files
Articles

Find a random article based on a tag:
Socials