[docker compose] environment variable is not set

$ cat compose.yml 
services:
    test:
        image: bash
        annotations:
            user: $USER
            uid: $UID


$ echo $USER, $UID
my-name, 1000


$ docker compose config
WARN[0000] The "UID" variable is not set. Defaulting to a blank string. 
services:
  test:
    annotations:
      uid: ""
      user: my-name
blahblah...

The “UID” variable is not set…

Why?

Quote:

No context, just a quoted code. You will need to work on your question to get help. The topic remains unlisted until you add more information that can actually help to understand your issue and what you did to get the error message.

$ bash --version 
GNU bash, versione 5.2.21(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2022 Free Software Foundation, Inc.
Licenza GPLv3+: GNU GPL versione 3 o successiva <http://gnu.org/licenses/gpl.html>

Questo è software libero; sei libero di cambiare e ridistribuirlo.
NON esiste alcuna GARANZIA, nella misura consentita dalla legge.




$ pwd
/tmp/tmp.nI5p0BRXiB



$ docker compose config
WARN[0000] The "UID" variable is not set. Defaulting to a blank string. 
name: tmpni5p0brxib
services:
  test:
    annotations:
      uid: ""
      user: my-name
    image: bash
    networks:
      default: null
networks:
  default:
    name: tmpni5p0brxib_default

I’m trying to do something more concrete

+ echo $UID:$GID
1000:

mmmhhh…

+ echo $UID:$UID
1000:1000

OK

+ tree
├── compose-1.yml
└── compose-2.yml

+ cat compose-1.yml
services:
  test:
    image: bash
    volumes:
        - .:/data

+ cat compose-2.yml
services:
  test:
    image: bash
    volumes:
        - .:/data
    user: "${UID}:${UID}"

Let’s do some tests

+ touch out-docker

+ docker compose --file compose-1.yml run --rm test touch /data/inside-docker

+ ls -n ./inside-docker ./out-docker
-rw-r--r-- 1    0    0 0 mag 18 09:25 ./inside-docker
-rw-rw-r-- 1 1000 1000 0 mag 18 09:25 ./out-docker

But I would like inside-docker to have the same user-id/group-id as out-docker (1000).

+ docker compose --file compose-2.yml run --rm test touch /data/inside-docker
WARN[0000] The "UID" variable is not set. Defaulting to a blank string. 
WARN[0000] The "UID" variable is not set. Defaulting to a blank string. 

Why?

+ echo $UID
1000

Everything seems fine.

So why the “UID” variable is not set?

It’s because UID is not an environment variable, but a bash “internal” variable. As such, it does not get exported to child processes like docker-compose or the docker CLI. USER, on the other hand, is and does. See here.

To solve your problem, I would set a different variable’s value to $UID, and use that in the compose file.

Things docker CLI?

I can see the solution, but to avoid misunderstandings, it’s better if you give an example

Something like this:

$ cat compose.yml 
services:
    test:
        image: bash
        annotations:
            user: $USER
            uid: $USERID



$ USERID=$UID docker compose config
services:
  bash:
    annotations:
      user: my-name
      uid: "1000"
blahblah...

What if I used the homonym UID instead of USERID?
A bit like here https://stackoverflow.com/a/79592626/11889508

In bash, that will give an error like this:

bash: UID: readonly variable

Better to use a different name.

Are you sure?

$ USERID=$UID docker compose config && echo SUCCESSFUL
blahblah...
SUCCESSFUL

You used USERID here, just like I suggested. This will work. If you did this:

$ UID=$UID docker compose config

the you would get the bash error,

I apologize

$ UID=$UID docker compose config && echo SUCCESSFUL
...
SUCCESSFUL

I don’t think so.

$ UID=$UID docker compose config | head && echo SUCCESSFUL
bash: UID: variabile in sola lettura
name: "100"
services:
blahblah...
SUCCESSFUL

Sorry, I missed the first line (output too long)

bash: UID: variabile in sola lettura

But docker runs anyway…

name: "100"
services:
blahblah...
SUCCESSFUL