Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass variables through docker-compose to Dockerfile

I want to correctly share directories between host and docker's container where the same UID and GID are used on both systems. For this, I wanted to pass them as variables MY_UID=$(id -u) to the docker.

We are considering case where .env has row with reference to some variable like MY_UID=$(id -u), not row value like MY_UID=1000

Variables are correctly declared, exported as an environment variables and it works on the docker-compose.yml level, but docker-compose do not pass them further to Dockerfile(s).

I've tried so far in docker-compose.yml:

  • env_file field
  • environment field

together with in bash:

  • exporting variables, like:
    • cat .env | envsubst | docker-compose -f - ...
    • VAR=123 docker-compose ...

or options for docker-compose -e.

The entire route for the given variables is export > docker-compose > dockerfile.


for testing purpose Dockerfile is simple like: (on this level variables doesn't works!)

FROM heroku/heroku:18 AS production
RUN useradd -ms /usr/bin/fish -p $(openssl passwd -1 django) --uid "$MY_UID" --gid "$MY_GID" -r 

and $MY_UID is empty while using docker-compose.


docker-compose.yml (on this level variables works!)

version: '3.7'

networks: {}
services:
  django:
    build:
      context: ${MY_DIR}
      dockerfile: ${COMPOSE_DIR}/django/Dockerfile
    env_file:
      - .env
    environment:
      - MY_UID: ${MY_UID}
    volumes:
      - ${MY_DIR}:/app:rw

docker-compose config returns: MY_GID: $$(id -u) for .env: MY_GID=$(id -u)


I wanted to avoid the workaround like this:

source .env && cat template_Dockerfile | envsubst > Dockerfile

or

source .env && cat .env | envsubst > .env_for_dockercompose

like image 745
Sławomir Lenart Avatar asked Dec 07 '25 10:12

Sławomir Lenart


1 Answers

Regarding the proper way to pass values from docker-compose (or just from CLI) to Dockerfile, I guess you need to add some ARG directive, for example:

FROM heroku/heroku:18 AS production
ARG MY_UID="...default UID..."
ARG MY_GID="...default GID..."
RUN useradd -ms /usr/bin/fish -p $(openssl passwd -1 django) --uid "$MY_UID" --gid "$MY_GID" -r 

Then to test it:

$ docker build --build-arg=MY_UID="1000" --build-arg=MY_GID="1000" -t test .

I use a similar approach in the Dockerfile of coqorg/base (which is based on Debian).

However, if you are especially interested in passing variables to ensure that the UID/GID match, note that another approach is possible that has the additional benefit to make your image compatible with several hosts using different UID/GID. It is described in this SO answer by @BMitch which proposes to fix the permissions of a container's directory at startup time, see e.g.:

  • https://github.com/sudo-bmitch/docker-base/blob/master/examples/nginx/entrypoint.d/10-fix-perms.sh
  • https://github.com/sudo-bmitch/docker-base/blob/master/bin/fix-perms
like image 104
ErikMD Avatar answered Dec 10 '25 02:12

ErikMD



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!