datastack-net / dockerized

Run popular commandline tools within docker
MIT License
1.26k stars 39 forks source link

Overriding system environment variables issue #26

Closed jtdevops closed 2 years ago

jtdevops commented 2 years ago

I have noticed that on my Windows 10 laptop when I use WSL and attempt to override the Linux HOME environment variable, the overriding of the value partially works.

The reason that I am trying to do this is so my Windows home .ssh configuration is shared between the CMD and WSL environments, while using the same dockerized docker-compose.yaml file.

In Windows 10, there is no HOME environments variable, instead there is a HOMEPATH. In WSL there is already a HOME environments variable that points to the Linux /home/\ folder. I would like to override this to point to the Windows 10 HOMEPATH environments variable instead.

NOTE: Below is a working version as I am using the HOMEPATH environment variable in the docker-compose.yml file. When I change HOMEPATH to HOME, it then fails.

Here is my setup:

# C:\Users\<user>\dockerized.env (Command Prompt)

HOME=${HOMEPATH}
COMPOSE_FILE="${COMPOSE_FILE};${HOME}/.dockerized/docker-compose.yml"
# /home/<wsl user>/dockerized.env (WSL2)

HOMEPATH=/mnt/c/Users/<user>
HOME=${HOMEPATH}
COMPOSE_FILE="${COMPOSE_FILE};${HOME}/.dockerized/docker-compose.yml"
# C:\Users\<user>\.dockerized\docker-compose.yml
# /mnt/c/Users/<user>/.dockerized/docker-compose.yml

version: "3"
services:
  dev:
    image: "my-project-build-env"
    build:
      context: ${HOMEPATH:-.}/.dockerized/apps/my-project-build-env
    stdin_open: true # docker run -i
    tty: true        # docker run -t
    entrypoint: [ "/init.sh", "/bin/bash" ]
    volumes:
      - ${HOMEPATH:-.}/.m2:/root/.m2
      - ${HOMEPATH:-.}/.ssh:/dockerized/host/home/.ssh
      - ${HOMEPATH:-.}/.dockerized/apps/my-project-build-env/init.sh:/init.sh

Here is the successful WSL debug logs when using HOMEPATH:

> dockerized -v dev
Dockerized root: /mnt/c/Tools/dockerized
Loading: '/mnt/c/Tools/dockerized/.env'
Loading: '/home/<wsl user>/dockerized.env'
Compose files: /mnt/c/Tools/dockerized/docker-compose.yml, /mnt/c/Users/<user>/.dockerized/docker-compose.yml

# My dockerized 'dev' service works.

Here is the failing WSL debug logs when using HOME:

> dockerized -v dev
Dockerized root: /mnt/c/Tools/dockerized
Loading: '/mnt/c/Tools/dockerized/.env'
Loading: '/home/<wsl user>/dockerized.env'
Compose files: /mnt/c/Tools/dockerized/docker-compose.yml, /mnt/c/Users/<user>/.dockerized/docker-compose.yml

# My dockerized 'dev' service fails.

The above debug logs are exactly the same.

Based on the compose files specified above, I generated a docker-compose command:

> docker-compose -f /mnt/c/Tools/dockerized/docker-compose.yml -f /mnt/c/Users/<user>/.dockerized/docker-compose.yml config

ERROR: build path /home/<wsl user>/.dockerized/apps/my-project-build-env either does not exist, is not accessible, or is not a valid URL.

When I run:

> HOME=/mnt/c/Users/<user> docker-compose -f /mnt/c/Tools/dockerized/docker-compose.yml -f /mnt/c/Users/<user>/.dockerized/docker-compose.yml config

# It succeedds and shows the complete docker-compose file which was assembled from the 2 yaml files.

Based on this, I think that the system environment variables aren't being overridden, or the system variables are being applied on top of the other .env and dockerized.env variables.

Would it be possible to create an internal dockerized 'config' service so that it will show the complete docker compose file and service configuration, like the 'docker-compose config' does?

boukeversteegh commented 2 years ago

Thank you for your feedback! It would be great to allow dockerized users to load configs from their Windows home, rather than the WSL2 home.

I haven't reproduced your scenario yet, but I know there's the following issue:

dockerized.env (and the base .env) do not override system environment variables.

This is by design. The reason is that users should be able to override the configs from env files in their local shells, as is common with most cli tools. For example: GO_VERSION=1.16 dockerized go.

Dockerized cannot tell whether the ENV var was set within the shell, or whether its a default provided by the system.

As such, the priority of env vars is like this:

The $HOME var is not defined in some shells on Windows. In that case, dockerized will set it to the user home directory, before loading the env files. It is (currently) not possible to override this variable from the .env files, as they have lower priority.

Setting the home variable from the env files is also problematic, because the first thing dockerized does, is looking up the home directory, and then loading the env files from it.

A better approach might be to not use the home var at all, and just create a dockerized.env file in your Windows home folder, and also in your WSL home folder. There you can specify a shared compose file you want to load. However, I see that the issue is then that you have to define your .env files twice as well, and this is the core of the problem. In some way, your situation is that you want to share your windows HOME directory with WSL.

But if you want to specify it for dockerized only, then we need some extra feature. For example, allowing to specify more env files to be loaded from an existing env file.


Some sort of debugging feature will be useful. Perhaps in the form you've suggested. I think some solution will be needed where dockerized explains how the env vars were produced from the settings.

jtdevops commented 2 years ago

Thanks. I will continue to use the HOMEPATH environment variable then as I showed in my example. This will fix my problem as the 'dev' service is defined and shared between my CMD and WSL shells via my local ~/.dockerized/docker-compose.yml