18

I have a container with nodejs and pm2 as start command and on OpenShift i get this error on startup:

Error: EACCES: permission denied, mkdir '/.pm2'

I tried same image on a Marathon hoster and it worked fine.

Do i need to change something with UserIds?

The Dockerfile:

FROM node:7.4-alpine

RUN npm install --global yarn pm2

RUN mkdir /src

COPY . /src

WORKDIR /src

RUN yarn install --production

EXPOSE 8100

CMD ["pm2-docker", "start", "--auto-exit", "--env", "production", "process.yml"]

Update
the node image already creates a new user "node" with UID 1000 to not run the image as root.
I also tried to fix permissions and adding user "node" to root group.
Further i told pm2 to which dir it should use with ENV var:

PM2_HOME=/home/node/app/.pm2

But i still get error:

Error: EACCES: permission denied, mkdir '/home/node/app/.pm2'

Updated Dockerfile:

FROM node:7.4-alpine

RUN npm install --global yarn pm2

RUN adduser node root
COPY . /home/node/app
WORKDIR /home/node/app
RUN chmod -R 755 /home/node/app
RUN chown -R node:node /home/node/app

RUN yarn install --production

EXPOSE 8100

USER 1000

CMD ["pm2-docker", "start", "--auto-exit", "--env", "production", "process.yml"]

Update2 thanks to Graham Dumpleton i got it working

FROM node:7.4-alpine

RUN npm install --global yarn pm2

RUN adduser node root
COPY . /home/node/app
WORKDIR /home/node/app

RUN yarn install --production

RUN chmod -R 775 /home/node/app
RUN chown -R node:root /home/node/app

EXPOSE 8100

USER 1000

CMD ["pm2-docker", "start", "--auto-exit", "--env", "production", "process.yml"]
ivoba
  • 5,780
  • 5
  • 48
  • 55
  • Which of the RUN lines gives you this error? EDIT: Ah sorry, it happens when running the container... – Alexander Block Feb 21 '17 at 10:58
  • It looks like that pm2-docker is ignoring the current working directory. Also, by checking the image history (I could not find a Dockerfile for 7.4), it looks like the expected working directory is /home/node. Probably pm2-docker (never used it) also expects this to be the working dir. Can you try to change COPY and WORKDIR so that the source is located inside /home/node? – Alexander Block Feb 21 '17 at 11:11
  • the Dockerfile should be this: https://github.com/nodejs/docker-node/blob/90d5e3df903b830d039d3fe8f30e3a62395db37e/7.5/alpine/Dockerfile – ivoba Feb 21 '17 at 17:07
  • i actually wonder if i need pm2 at all, isnt the container automatically restarted when the node process crashes? – ivoba Feb 22 '17 at 13:25
  • On which kernel version are you and which storage driver do you use in the daemon? There are known problems regarding permissions and the overlay driver with older kernels which you may suffer from. – Alexander Block Feb 22 '17 at 14:30
  • the kernel on the machine where the images is created is 4.4.0-63-generic, the storage driver is Storage Driver: aufs – ivoba Feb 22 '17 at 15:13
  • aufs had a lot of permission issues in the past, maybe you are facing something like this. Can you retry with the overlay2 driver or with the overlay driver in case docker fails to start with overlay2. – Alexander Block Feb 22 '17 at 15:34

5 Answers5

19

OpenShift will by default run containers as a non root user. As a result, your application can fail if it requires it runs as root. Whether you can configure your container to run as root will depend on permissions you have in the cluster.

It is better to design your container and application so that it doesn't have to run as root.

A few suggestions.

  • Create a special UNIX user to run the application as and set that user (using its uid), in the USER statement of the Dockerfile. Make the group for the user be the root group.

  • Fixup permissions on the /src directory and everything under it so owned by the special user. Ensure that everything is group root. Ensure that anything that needs to be writable is writable to group root.

  • Ensure you set HOME to /src in Dockerfile.

With that done, when OpenShift runs your container as an assigned uid, where group is root, then by virtue of everything being group writable, application can still update files under /src. The HOME variable being set ensures that anything written to home directory by code goes into writable /src area.

Graham Dumpleton
  • 57,726
  • 6
  • 119
  • 134
  • i tried to use all your advices but it still fails, see updated questions – ivoba Feb 22 '17 at 10:14
  • Except you didn't quite get it right. The ``chmod`` should have been 775 and the ``chown`` should have been for ``node:root``. And do that after all other commands run, so after ``yarn install`` in case it is writing to workdir. – Graham Dumpleton Feb 22 '17 at 19:46
  • @GrahamDumpleton: Does the user(in this case `node`) need to also exist on the host, or just specified in the Dockerfile? – grizzthedj Oct 02 '19 at 15:21
  • The `node` user needs to exist in the `/etc/passwd` in the container image. It does not need to exist on the underlying OpenShift node host. – Graham Dumpleton Oct 02 '19 at 20:35
  • 1
    Step one, `Create a special UNIX user to run the application as and set that user (using its uid), in the USER statement of the Dockerfile.`, is pointless. Openshift doesn't allow custom users unless you go deep into their settings to change it. That said, ALL the users granted to the DockerImages are inside group root, so these instructions still work, accidentally. – Eliezer Berlin Nov 17 '21 at 16:38
5

You can also run the below command which grants root access to the project you are logged in as:

oc adm policy add-scc-to-user anyuid -z default

Gloorfindel
  • 404
  • 3
  • 8
0

Graham Dumpleton'solution is working but not recommended.

Openshift, will use random UIDs when running containers.

You can see that in the generated Yaml of your Pod.

spec:
    - resources:
      securityContext:
        runAsUser: 1005120000

You should instead apply Docker security best practices to write your Dockerfile.

  1. Do not bind the execution of your application to a specific UID : Make resources world readable (i.e., 0644 instead of 0640) and executable when needed.

  2. Make executables owned by root and not writable

For a full list of recommendation see : https://sysdig.com/blog/dockerfile-best-practices/

In your case, there is not need to :

RUN adduser node root
...
RUN chown -R node:node /home/node/app
USER 1000

In the original question, the application files are already owned by root.
The following chmod is enough to make them readable and executable to the world.

RUN chmod -R 775 /home/node/app
loonis
  • 1,317
  • 16
  • 19
0

By default, OpenShift Container Platform runs containers using an arbitrarily assigned user ID. This provides additional security against processes escaping the container due to a container engine vulnerability and thereby achieving escalated permissions on the host node.

For an image to support running as an arbitrary user, directories and files that are written to by processes in the image must be owned by the root group and be read/writable by that group. Files to be executed must also have group execute permissions.

Adding the following to your Dockerfile sets the directory and file permissions to allow users in the root group to access them in the built image:

RUN chgrp -R 0 /some/directory && \
    chmod -R g=u /some/directory


WORKDIR /some/directory

Because the container user is always a member of the root group, the container user can read and write these files.

https://docs.openshift.com/container-platform/4.11/openshift_images/create-images.html#use-uid_create-images


Example on how this would look on the docker file:

# Add non-root user (with home dir at /opal)

RUN useradd -m -b / -s /bin/bash opal

RUN chgrp -R 0 /opal && \
    chmod -R g=u /opal

WORKDIR /opal

This way you would be running as opal user, but the WORKDIR /opal has root as group.

JCompetence
  • 6,997
  • 3
  • 19
  • 26
-3

What kind of openshift are you using ?

You can edit the "restricted" Security Context Constraints :

From openshift CLI :

oc edit scc restricted 

And change :

runAsUser:
  type: RunAsUSer

to

runAsUser:
  type: RunAsAny

Note that Graham Dumpleton's answer is proper

Victor Rocheron
  • 61
  • 1
  • 10