Core problem is that when a container is creating files for persistence they are effectively owned by root and will require me to enter sudo password to delete. I want all containers to run as my user or at least in a way that I can delete temporary files created by containers. Look at this minimal example:
# docker-compose.yml
version: "2.2"
services:
app:
build: .
container_name: app
environment:
- UID=${UID}
- GID=${GID}
- USER=${USER}
# Dockerfile
FROM alpine
RUN apk update
RUN apk upgrade
RUN apk add shadow
RUN useradd -G root,wheel -u ${UID} -g ${GID} -s /bin/ash -d /home/${USER} ${USER}
USER ${USER}
CMD /bin/ash
# output
❯ docker-compose up -d --remove-orphans --build
[ ] Building 0.4s (8/8) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 212B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 32B 0.0s
=> [internal] load metadata for docker.io/library/alpine:latest 0.0s
=> [1/5] FROM docker.io/library/alpine 0.0s
=> CACHED [2/5] RUN apk update 0.0s
=> CACHED [3/5] RUN apk upgrade 0.0s
=> CACHED [4/5] RUN apk add shadow 0.0s
=> ERROR [5/5] RUN useradd -G root,wheel -u ${UID} -g ${GID} -s /bin/ash -d /home/${USER} ${USER} 0.3s
------
> [5/5] RUN useradd -G root,wheel -u ${UID} -g ${GID} -s /bin/ash -d /home/${USER} ${USER}:
#0 0.325 useradd: invalid user ID '-g'
------
failed to solve: executor failed running [/bin/sh -c useradd -G root,wheel -u ${UID} -g ${GID} -s /bin/ash -d /home/${USER} ${USER}]: exit code: 3
The useradd
command is failing because none of the env vars are set. That means the command that is being run is /bin/sh -c useradd -G root,wheel -u -g -s /bin/ash -d /home
.
Related SO answers / what I've tried so far:
The UID or EUID variable is provided by your bash, to which docker and docker compose is unaware.
How to fix this?
So you know that the docker compose knows about the environment variables, you can create the one which does't conflict with shell variables.
The new docker-compose.yaml would be
services:
app:
build:
context: .
args:
UID: ${UID1}
USER: ${USER1}
environment:
UID: ${ENV_UID} # updated
USER: ${USER}
and the .env
file would also have similar update
UID1=${ENV_UID} # updated
USER1=${USER}
Conclusion
Docker compose looks for the environment variables and has no information for the shell variables. The $UID variable is provided by the shell, you can check that by searching for "your shell name default variables" on your favourite search engine. To fix this, you are supposed to export an environment variable different from the shell variable, this is only to avoid conflicts.