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
.
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