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

[BUG] docker compose only tries to load the .env located near the first docker-compose.yml file even if it not in the PWD #12054

Closed
BergLucas opened this issue Aug 13, 2024 · 2 comments · May be fixed by compose-spec/compose-go#675

Comments

@BergLucas
Copy link
Contributor

Description

Hi, I have a project with a structure like this:

.
├── .env
├── docker-compose.yml
├── front
│   └── docker-compose.yml
└── api
    └── docker-compose.yml

My goal is to be able to start both the front and the back sub-projects in one command. To do so, I'm using a docker-compose.yml file in the project root which adds the dependencies between the services of the front and the back.

However, when I run the command docker compose -f api/docker-compose.yml -f front/docker-compose.yml -f docker-compose.yml up in the project root to start everything, it crashes with the error :

error while interpolating services.api.environment.[]: required variable POSTGRES_USER is missing a value: Missing username

It is really weird because this environment variable is defined in the .env file. After some trial and error, I found that using the very similar command docker compose -f docker-compose.yml -f api/docker-compose.yml -f front/docker-compose.yml up works. I have also tried a few other commands and I have concluded that docker compose only tries to read the .env file at the level of the first docker-compose.yml file. You could tell me that I could just change the order of the files so that I don't get the error anymore, except that by changing the order, the files are not combined in the same way. In my case, I would have liked the name of the docker compose project to be the one of the project root docker-compose.yml file and not the ones of the other files so I need it to be the last file.

To summarise, here's what's happening:

  • Running docker compose -f api/docker-compose.yml -f front/docker-compose.yml -f docker-compose.yml up in project root : Don't work
  • Running docker compose -f docker-compose.yml -f api/docker-compose.yml -f front/docker-compose.yml up in project root : Works
  • Placing the .env file in the api directory and running docker compose -f api/docker-compose.yml -f front/docker-compose.yml -f docker-compose.yml up in project root : Works
  • Running docker compose -f api/docker-compose.yml -f front/docker-compose.yml -f docker-compose.yml --env-file .env up in project root : Works

These behaviours go quite against what is written in the documentation, where it is said that the .env file is loaded from the local working directory (PWD) which is the project root in these cases. This is also counter-intuitive, as by manually specifying the .env from the local working directory (PWD) in the first command, it works (as shown in the last example).

I also tested this on an old version of docker compose that I had (v2.11.0) and the bug already existed so the problem doesn't seem to come from the changes that have been made this year concerning the .env files.

Steps To Reproduce

1. In this environment:

Please see section Compose version and Docker environment

2. With this config:

.env

POSTGRES_USER=user
POSTGRES_PASSWORD=password
POSTGRES_DB=db

docker-compose.yml

name: app

services:
    front:
        environment:
            - API_URL=http://api:3001
        depends_on:
            - api

front/docker-compose.yml

name: front

services:
    front:
        image: node
        environment:
            - API_URL

back/docker-compose.yml

name: api

services:
    api:
        image: python
        environment:
            - DATABASE_URL=DATABASE_URL=postgresql://${POSTGRES_USER?Missing username}:${POSTGRES_PASSWORD?Missing password}@db:5432/${POSTGRES_DB?Missing database}

3. Run

docker compose -f api/docker-compose.yml -f front/docker-compose.yml -f docker-compose.yml up

4. See error

error while interpolating services.api.environment.[]: required variable POSTGRES_USER is missing a value: Missing username

Compose Version

Docker Compose version v2.29.1

Docker Environment

Client: Docker Engine - Community
 Version:    27.1.1
 Context:    default
 Debug Mode: false
 Plugins:
  buildx: Docker Buildx (Docker Inc.)
    Version:  v0.16.1
    Path:     /usr/libexec/docker/cli-plugins/docker-buildx
  compose: Docker Compose (Docker Inc.)
    Version:  v2.29.1
    Path:     /usr/libexec/docker/cli-plugins/docker-compose

Server:
 Containers: 0
  Running: 0
  Paused: 0
  Stopped: 0
 Images: 18
 Server Version: 27.1.1
 Storage Driver: overlay2
  Backing Filesystem: extfs
  Supports d_type: true
  Using metacopy: false
  Native Overlay Diff: true
  userxattr: false
 Logging Driver: json-file
 Cgroup Driver: systemd
 Cgroup Version: 2
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local splunk syslog
 Swarm: inactive
 Runtimes: io.containerd.runc.v2 runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: 8fc6bcff51318944179630522a095cc9dbf9f353
 runc version: v1.1.13-0-g58aa920
 init version: de40ad0
 Security Options:
  seccomp
   Profile: builtin
  cgroupns
 Kernel Version: 6.9.12-200.fc40.x86_64
 Operating System: Fedora Linux 40 (Workstation Edition)
 OSType: linux
 Architecture: x86_64
 CPUs: 12
 Total Memory: 14.82GiB
 Name: lucas-hp
 ID: 425f8ada-cce4-4b71-8df7-d8f6cf667c4a
 Docker Root Dir: /var/lib/docker
 Debug Mode: false
 Experimental: false
 Insecure Registries:
  127.0.0.0/8
 Live Restore Enabled: false

Anything else?

No response

@ndeloof
Copy link
Contributor

ndeloof commented Aug 19, 2024

"project directory" is defined by the parent folder in the first compose file set by -f (defaults to $PWD/compose.yaml)
.env file is loaded from project directory, so if you use -f api/compose.yaml a local .env fils won't be used
You should use an explicit --env-file flag

@ndeloof ndeloof closed this as completed Aug 19, 2024
@BergLucas
Copy link
Contributor Author

Hi @ndeloof,

I think that the documentation is wrong then:
image
https://docs.docker.com/compose/environment-variables/variable-interpolation/#ways-to-set-variables-with-interpolation

The second point indicates that it looks for variables in the .env file of the PWD before looking for variables in the .env file of the ‘project directory’, as indicated in the third point.

Thank you anyway for your reply and have a nice day.

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

Successfully merging a pull request may close this issue.

2 participants