I’m trying to learn how to use environmental variables and files and the documentation does not appear to match behavior.
given this compose file:
# environment test
services:
env-demo:
container_name: env-demo
image: filebrowser/filebrowser
user: "${test_UID}:${test_GID}"
#env_file: manual_load.env
#env_file: "manual_load.env"
#env_file: /opt/docker-stacks/env-demo/manual_load.env
If I create a file “.env” and put in it:
test_UID=1001
test_GID=1001
Then when I run “docker compose config”:
** root@docker0 ** /opt/docker-stacks/env-demo ** Wed Oct 23 06:23:37
# docker compose -f compose-demo.yaml config
name: env-demo
services:
env-demo:
container_name: env-demo
image: filebrowser/filebrowser
networks:
default: null
user: 1001:1001
networks:
default:
name: env-demo_default
It works as expected and the variables in the “user:” parameter are substituted with “1001”.
w00t!
If I rename the file from “.env” to “manual_load.env”, and then explicitly load the file using “env_file:” it fails interestingly:
** root@docker0 ** /opt/docker-stacks/env-demo ** Wed Oct 23 17:06:48
# docker compose -f compose-demo.yaml config
WARN[0000] The "test_UID" variable is not set. Defaulting to a blank string.
WARN[0000] The "test_GID" variable is not set. Defaulting to a blank string.
name: env-demo
services:
env-demo:
container_name: env-demo
environment:
test_GID: "1001"
test_UID: "1001"
image: filebrowser/filebrowser
networks:
default: null
user: ':'
networks:
default:
name: env-demo_default
There is now a new section “environment:” (which doesn’t appear when you use “.env”); but the variable substitution does not occur and you’re left with “user: ‘:’”
The file is clearly being parsed because the correct values show up in “environment:”.
The behavior is the same regardless of whether one uses a relative or full path.
If you specify the file on the command line with the “–env-file” parameter:
** root@docker0 ** /opt/docker-stacks/env-demo ** Wed Oct 23 17:12:55
# docker compose -f compose-demo.yaml --env-file manual_load.env config
name: env-demo
services:
env-demo:
container_name: env-demo
environment:
test_GID: "1001"
test_UID: "1001"
image: filebrowser/filebrowser
networks:
default: null
user: 1001:1001
networks:
default:
name: env-demo_default
It now both shows the “environment:” tag missing from .env and it performs the variable substitution.
If I explicitly add an “environment:” section in the compose file and run it without attempting to load an environment file:
** root@docker0 ** /opt/docker-stacks/env-demo ** Wed Oct 23 17:13:06
# docker compose -f compose-demo.yaml config
WARN[0000] The "test_UID" variable is not set. Defaulting to a blank string.
WARN[0000] The "test_GID" variable is not set. Defaulting to a blank string.
name: env-demo
services:
env-demo:
container_name: env-demo
environment:
test_GID: "1001"
test_UID: "1001"
image: filebrowser/filebrowser
networks:
default: null
user: ':'
networks:
default:
name: env-demo_default
Obviously, there is now an “environment:” section in the config output; but no variable substitution occurs.
So, finally, the actually questions:
Is this expected behavior?
If this is expected behavior, what’s the logic?
I’m also assuming the choice of image makes no difference; but I haven’t experimented with that.
Version info:
# docker --version
Docker version 27.3.1, build ce12230
# docker compose version
Docker Compose version v2.29.7
# lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 24.04.1 LTS
Release: 24.04
Codename: noble