File ownership inside container with machine executor

Hello, I have a docker-compose setup where I bind mount my project dir into the container, and I’m noticing different behavior between a plain ubuntu server install vs the CircleCI ubuntu-2204:current on machine executor.

Docker stuff looks like so:

dockerfile

FROM node:16
COPY ./package.json ./package-lock.json ./
RUN npm install
COPY . .
USER node
ENTRYPOINT ["npm"]
CMD ["start"]

docker-compose.yml

  myapp:
    entrypoint: tail -f /dev/null
    build:
      context: .
      target: builder
    ...
    volumes:
      - .:/app
      - node_modules:/app/node_modules

When I docker compose up -d && docker exec -it myapp bash into my local container, I see what I would expect:

ls -la /app
drwxrwxr-x  15 node node    4096 Nov  8 17:04 app
drwxrwxr-x   6 node node    4096 Nov  8 17:04 arch
drwxrwxr-x   2 node node    4096 Nov  8 17:04 config

However when I do the same thing in CircleCI, everything is owned by the circleci user, not the node user.

circleci@ip-10-0-76-255:~/project$ id -u circleci
1001

Inside container:

ls -la /app
drwxrwxr-x  15 1001 1002    4096 Nov  9 21:31 app
drwxrwxr-x   6 1001 1002    4096 Nov  9 21:31 arch
drwxrwxr-x   2 1001 1002    4096 Nov  9 21:31 config

OP: Sorry I thought I would be able to edit after I posted this - I guess my question is,
I’m trying to run a process inside the container (as node) I want to write to one of those directories, and then pick up the file from the host, but the node user can’t write to those directories due to being owned by the circleci user.

Why the discrepancy? And is there anything I can do?

I tried explicitly setting the user in docker-compose user: node:node but to no avail.

I can not say if it is the correct answer(as there is more than one), but when I build a container I set the user and group to what I want on the COPY command. Using my code as an example my dockerfile contains

COPY --chown=www-data:www-data .circleci/deployment/crontab  /etc/cron.d/www-data

So ownership and group is set to www-data as copy runs, which in my case is for a single file.

The more detailed writeup on the command can be found here