docker-pm2
docker-pm2 copied to clipboard
Start container as non-root user
First of all, thanks for the image. Following best practices I learned that it's best to not start containers as a root user.
When I switch to the node user though, I get "permission denied" error:
Error: EACCES: permission denied, open '/usr/local/lib/node_modules/pm2/node_modules/array-unique/index.js'
at Object.fs.openSync (fs.js:651:18)
at Object.fs.readFileSync (fs.js:553:33)
at Object.Module._extensions..js (module.js:579:20)
at Module.load (module.js:503:32)
at tryModuleLoad (module.js:466:12)
at Function.Module._load (module.js:458:3)
at Module.require (module.js:513:17)
at require (internal/module.js:11:18)
at Object.<anonymous> (/usr/local/lib/node_modules/pm2/node_modules/micromatch/lib/utils.js:13:16)
at Module._compile (module.js:569:30)
Is there a way to start this container as non-root user, i.e. assuming user "node". When doing so, for what files and directories do I need to change ownership to that new user?
@Unitech any thought on this?
I ran into this problem as well.
As a Linux n00b I discovered several issues with this:
npmhas been installed by therootuser in the originalnode:alpineimage- installing
pm2therefor is only possible using therootuser as well - executing
pm2as a different user is not possible because it has been installed as root, so it gives you "permission denied"
To run NPM and PM2 using a different user I've created my own image with the following tweaks:
RUN chown -R USER:GROUP $(npm config get prefix)/lib/node_modules
RUN chown -R USER:GROUP /usr/local/bin/pm2
@Unitech maybe we can add the @jvduf workaround to the readme. What do you think about?
I've been experimenting some more...
This might be a cleaner option and is also the suggested solution as per https://docs.npmjs.com/getting-started/fixing-npm-permissions
RUN mkdir -p /home/app/.npm-global/bin \
&& npm config set prefix '/home/app/.npm-global' \
&& npm install -g pm2
ENV PATH=/home/app/.npm-global/bin:${PATH}
[edit: exporting the path was incorrect, so added it through ENV command]
This is part of my Dockerfile:
RUN addgroup -g 9999 app && adduser -u 9999 -G app -D app -s /bin/bash \
&& apk upgrade --update \
&& apk add --no-cache \
bash bash-completion \
git
COPY ./bash/.bash* /home/app/
USER app
ENV HOME=/home/app/
WORKDIR $HOME
RUN mkdir -p /home/app/.npm-global/bin \
&& npm config set prefix '/home/app/.npm-global' \
&& npm install -g pm2
ENV PATH=/home/app/.npm-global/bin:${PATH}
Update on 2020, The solution of @jvduf works until I want to log PM2 output to file (by adding output and error option in ecosystem.config.js), under is my Dockerfile:
Rest is same with @jvduf
...
CMD ["pm2-runtime", "ecosystem.config.js", "--env", "production"]
When I run, it'll say permission error on where log files will be created. And I figure out that, even I install and run PM2 under an user (using USER app), the log files created by PM will be owned by the host user and group whom we use to run the command docker-compose up. I don't experience this problem on Mac but it occurs on my Ubuntu server. I have no idea why PM2 can create log files in another user's permission, even if we explicitly run it by a non-root user.
Because of that reason, solution is set user id and group in Docker to be same as user on host system:
- In host system, run
id -uandid -gto find out your user and group IDs - Replace those values in Dockerfile (replace where
9999located)
Note:because User ID and Group ID with value 1000 are in used by node user inside container, so if your host user ID and group are also 1000, it'll print out user ID 1000 is in used during building Docker image, then you have 2 options:
- Option 1: change your host user ID and group ID to different ID (you usually may not prefer to do this)
- Option 2: in Dockerfile, change user to
nodeby settingUSER node, then all headache problems are gone.