dockerubuntuherokudocker-compose

Permission problem with heroku stack build locally with docker compose on ubuntu 24.04


I've been struggling for two days now and can't find a solution. I've read Heroku support article Local Development with Docker Compose, but it didn't help. I've upgraded my computer from Ubuntu 23.10 to Ubuntu 24.04, and Docker engine as well (from 24.x to 27.3.1).

For local development only, we use docker compose and import heroku stack image with FROM heroku/heroku:22-build.

It was working fine before my Ubuntu upgrade, but I'm getting permission issue now, and the appuser have permission denied to create and modify files.

With the following dockerfile, I can build successfully, but when I execute the command docker compose run node-base-20 bash -lc "yarn", it fails with Internal Error: EACCES: permission denied, mkdir '/app/user/.yarn/cache'

And when I enter the container with docker compose run node-base-20 bash -l and then execute ls -la, I see that all the files and folder have heroku:heroku owner, which should not be the case with the chown command of my dockerfile (I guess) :

appuser@fe1332271a86:~/user$ ls -la
total 1040
drwxrwxr-x 20 heroku  heroku   4096 Nov 26 11:00 .
drwxr-xr-x  1 appuser root     4096 Nov 27 09:54 ..
-rw-rw-r--  1 heroku  heroku    119 Nov 26 10:45 .dockerignore
-rw-rw-r--  1 heroku  heroku   2684 Nov 26 10:45 .env
-rw-rw-r--  1 heroku  heroku   3798 Nov 26 10:45 .eslintrcOld.js
drwxrwxr-x  8 heroku  heroku   4096 Nov 26 10:45 .git
drwxrwxr-x  3 heroku  heroku   4096 Nov 26 10:45 .github
-rw-rw-r--  1 heroku  heroku    706 Nov 26 10:45 .gitignore
-rw-rw-r--  1 heroku  heroku    109 Nov 26 10:45 .graphqlconfig.ymlOld
drwxrwxr-x  3 heroku  heroku   4096 Nov 26 14:50 .idea
drwxrwxr-x  3 heroku  heroku   4096 Nov 26 10:45 .yarn
-rw-rw-r--  1 heroku  heroku     56 Nov 26 10:45 .yarnrc.yml
-rw-rw-r--  1 heroku  heroku   4891 Nov 26 10:45 Certificat-SSL.md
-rw-rw-r--  1 heroku  heroku     38 Nov 26 10:45 Procfile
-rw-rw-r--  1 heroku  heroku  14873 Nov 26 10:45 README.md
-rw-rw-r--  1 heroku  heroku     46 Nov 26 10:45 Setup.hs
drwxrwxr-x  6 heroku  heroku   4096 Nov 26 10:45 bd-admin
...

I don't know if something changed concerning the user heroku in their docker stack image ? Or is it related to a new behavior of Ubuntu 24.04 maybe ? Or something else...

Here is the relevant part of my docker-compose.yml file :

services:
  node-base-20:
    build:
      context: '.'
      dockerfile: dockerfiles/bd_heroku_node_20.Dockerfile
      args:
        UID: "$UID"
    image: bd_heroku_node_20
    volumes:
      - .:/app/user/:delegated
  bd-conso:
    image: bd_heroku_node_20
    user: "$UID"
    command: bash -l -c "cd /app/user/bd-conso-next; yarn run dev"
    volumes:
      - .:/app/user/:delegated
    env_file: ./bd-conso-next/.env.local
    environment:
      - PORT=3002
    links:
      - bd-api
    ports:
      - '3002:3002'

And here is my bd_heroku_node_20.Dockerfile :

# Inherit from Heroku's stack
FROM heroku/heroku:22-build

# Internally, we arbitrarily use port 3000
ENV PORT 3000

# Locate our binaries
ENV PATH /app/heroku/node/bin/:/app/user/node_modules/.bin:$PATH
COPY package.json /app/user/package.json

# Create user linked to host current user
ARG UID
RUN adduser --system --uid ${UID} --shell /bin/bash --home /app appuser
RUN chown -R appuser /app
USER appuser

# Create some needed directories
RUN mkdir -p /app/heroku/node /app/.profile.d /app/user/node_modules
WORKDIR /app/user

# Install nvm
RUN touch ~/.profile
ENV NVM_DIR=/app/.nvm
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash

# Define NODE_VERSION as an environment variable
ENV NODE_VERSION=20.11.0

# install node version 20
RUN . $NVM_DIR/nvm.sh; \
  nvm install $(echo $NODE_VERSION) && \
  wait; \
  nvm alias default "${NODE_VERSION}"; \
  corepack enable; \
  corepack prepare yarn@stable --activate;

USER root
ENV TZ=Europe/Paris
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
USER appuser

-------------------------------------------------

Solution, thanks to @os11k tips

I had to use the heroku instead of creating a new user. So I had to give heroku user the /app folder as home directory in order for the rest to work properly.

Here is the change in my dockerfile :

# Modify the existing heroku user's home directory
USER root
RUN usermod -d /app heroku && chown -R heroku /app
USER heroku

instead of

# Create user linked to host current user
ARG UID
RUN adduser --system --uid ${UID} --shell /bin/bash --home /app appuser
RUN chown -R appuser /app
USER appuser

And of course use the heroku user everywhere instead of the appuser.


Solution

  • I think problem is that you try to use user appuser in bd_heroku_node_20, but seems it should be heroku.

    Can you try to update bd_heroku_node_20.Dockerfile like this:

    # Inherit from Heroku's stack
    FROM heroku/heroku:22-build
    
    # Internally, we arbitrarily use port 3000
    ENV PORT 3000
    
    # Locate our binaries
    ENV PATH /app/heroku/node/bin/:/app/user/node_modules/.bin:$PATH
    COPY package.json /app/user/package.json
    
    # Create user linked to host current user
    ARG UID
    RUN adduser --system --uid ${UID} --shell /bin/bash --home /app heroku
    RUN chown -R heroku /app
    USER heroku
    
    # Create some needed directories
    RUN mkdir -p /app/heroku/node /app/.profile.d /app/user/node_modules
    WORKDIR /app/user
    
    # Install nvm
    RUN touch ~/.profile
    ENV NVM_DIR=/app/.nvm
    RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
    
    # Define NODE_VERSION as an environment variable
    ENV NODE_VERSION=20.11.0
    
    # install node version 20
    RUN . $NVM_DIR/nvm.sh; \
      nvm install $(echo $NODE_VERSION) && \
      wait; \
      nvm alias default "${NODE_VERSION}"; \
      corepack enable; \
      corepack prepare yarn@stable --activate;
    
    USER root
    ENV TZ=Europe/Paris
    RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
    USER heroku