0

Can I use dynamic generated values in docker-compose.yml file like in the code below?

version: "3"
services:
  php:
    build:
      context: ./.docker-config/dockerfiles
      dockerfile: php.dockerfile
      args:
        - HOST_UID=${id -u}
        - HOST_GID=${id -g}
        - HOST_USER=${whoami}
    volumes:
      - ./:/var/www/html:delegated

...and in the php.dockerfile:

ARG HOST_UID
ARG HOST_USER

RUN useradd $HOST_USER -u $HOST_UID

It says:

ERROR: Invalid interpolation format for "build" option in service "php": "HOST_UID=${id -u}"

I think now the parameter passed into container contains this string: ${id -u} and not the value of the expression.

Can I somehow pass in the result of the expression?

netdjw
  • 5,419
  • 21
  • 88
  • 162
  • 1
    https://stackoverflow.com/questions/29377853/how-to-use-environment-variables-in-docker-compose https://stackoverflow.com/questions/62121588/how-to-evaluate-a-dynamic-variable-in-a-docker-compose-yml-file https://stackoverflow.com/questions/57880893/how-can-i-set-runtime-variable-for-docker-compose-environment-variable https://stackoverflow.com/questions/63234896/dynamic-docker-compose-config-from-env – KamilCuk Jan 20 '23 at 09:29
  • What you're trying to do can't be done. You ought to set the environment variables beforehand (either .env file or in the shell) and set the variable substitution to the name of the environment variables you've chosen, as KamilCuk's comment points out – EDG956 Jan 20 '23 at 09:33
  • @KamilCuk yes, I googled it before ask. Your linked questions are all operates insanely complex command line commands or operates with environment variables from command line. Environment variables are an unneccessary complexity level for easy-to-use docker configuration. If it's possible I want to keep as simple as possible the developers job when they start using containers. Nor 1000 chars lenght commands, nor bash env variable are enough simple for my needs. – netdjw Jan 20 '23 at 10:23
  • I do not understand. Your question is `Can I somehow pass in the result of the expression?` the answer is "Yes, use env variables". This is how it is. If you want to enable shell execution as part of variable expansion in docker-compose, patch docker with that functionality. You can use a preprocessor, like m4, to execute a command, which boils down to docker-compose.yml generation. – KamilCuk Jan 20 '23 at 10:36
  • I picked one of @KamilCuk's suggestions that most closely matches this question, and another that more directly matches the "build the host uid into the image" use case. Note that recompiling the image for every possible host user isn't generally a good practice; if my host uid is 501, why can't I use your image? – David Maze Jan 20 '23 at 12:55
  • @DavidMaze that is exactly why I want to pass in the current user's data into the container – netdjw Jan 20 '23 at 13:43

1 Answers1

1

You can set the variables as environment variables on your docker-compose build command, like this

HOST_UID=$(id -u) HOST_GID=$(id -g) HOST_USER=$(whoami) docker-compose build

Then you need to change your docker-compose file to get the values from the environment variables, like this

args:
  - HOST_UID=${HOST_UID}
  - HOST_GID=${HOST_GID}
  - HOST_USER=${HOST_USER}

It's not as user-friendly as having the commands in the docker-compose file, of course.

Here's how I tested it:

docker-compose.yml

version: '3'
services:
  app:
    build:
      context: .
      args:
        - HOST_UID
        - HOST_GID
        - HOST_USER

Dockerfile:

FROM debian
ARG HOST_UID
ARG HOST_GID
ARG HOST_USER
RUN echo ${HOST_UID}
RUN echo ${HOST_GID}
RUN echo ${HOST_USER}

Build command:

HOST_UID=$(id -u) HOST_GID=$(id -g) HOST_USER=$(whoami) docker-compose build --no-cache
Hans Kilian
  • 18,948
  • 1
  • 26
  • 35
  • sure, I know this works, but I want to avoid using more and more command line parameters. I'm looking for soultion to keep my command as simple as possible, like this `docker-compose up -d` – netdjw Jan 20 '23 at 10:17
  • I know. But that's not possible, I think. – Hans Kilian Jan 20 '23 at 10:40
  • Now I tried to put this into the .nev file: `HOST_USER="djw"` and in the dockerfile `RUN echo "host user is ${HOST_USER}"` the result of this echo is this: `host user is ` and the variable contains still empty string – netdjw Jan 20 '23 at 11:05
  • The .env file only applies to the docker-compose file. Not to Dockerfiles built with it. So you need to pass it on from the docker-compose file to the Dockerfile using `args`. – Hans Kilian Jan 20 '23 at 11:20
  • I pass it, but nothing – netdjw Jan 20 '23 at 13:41
  • I've updated my answer to show how I tested it – Hans Kilian Jan 20 '23 at 15:09
  • Thanks, but I'm looking for a solution to keep my command line command as simple as possible. This suggestion is working, but it's a brainmelting way... :) Now I try to use a `docker.env` file to keep there my variables, but still not working. – netdjw Jan 23 '23 at 13:10
  • Environment variables are only available at run-time, so you can't use them at build time – Hans Kilian Jan 23 '23 at 13:16
  • So there isn't any way to store my variables in `.env` file or read it from a command at running `docker-compose up -d` ? – netdjw Jan 23 '23 at 22:46