skip to Main Content

I have this Dockerfile setup:

FROM node:14.5-buster-slim AS base
WORKDIR /app


FROM base AS production
ENV NODE_ENV=production

RUN chown -R node:node /app
RUN chmod 755 /app
USER node
... other copies
COPY ./scripts/startup-production.sh ./
COPY ./scripts/healthz.sh ./

CMD ["./startup-production.sh"]

The problem I’m facing is that I can’t execute ./healthz.sh because it’s only executable by the node user. When I commented out the two RUN and the USER commands, I could execute the file just fine. But I want to enforce the executable permissions only to the node for security reasons.

I need the ./healthz.sh to be externally executable by Kubernetes’ liveness & rediness probes.

How can I make it so? Folder restructuring or stuff like that are fine with me.

2

Answers


  1. In most cases, you probably want your code to be owned by root, but to be world-readable, and for scripts be world-executable. The Dockerfile COPY directive will copy in a file with its existing permissions from the host system (hidden in the list of bullet points at the end is a note that a file "is copied individually along with its metadata"). So the easiest way to approach this is to make sure the script has the right permissions on the host system:

    # mode 0755 is readable and executable by everyone but only writable by owner
    chmod 0755 healthz.sh
    git commit -am 'make healthz script executable'
    

    Then you can just COPY it in, without any special setup.

    # Do not RUN chown or chmod; just
    WORKDIR /app
    COPY ./scripts/healthz.sh .
    
    # Then when launching the container, specify
    USER node
    CMD ["./startup-production.sh"]
    

    You should be able to verify this locally by running your container and manually invoking the health-check script

    docker run -d --name app the-image
    # possibly with a `docker exec -u` option to specify a different user
    docker exec app /app/healthz.sh && echo OK
    

    The important thing to check is that the file is world-executable. You can also double-check this by looking at the built container

    docker run --rm the-image ls -l /app/healthz.sh
    

    That should print out one line, starting with a permission string -rwxr-xr-x; the last three r-x are the important part. If you can’t get the permissions right another way, you can also fix them up in your image build

    COPY ./scripts/healthz.sh .
    # If you can't make the permissions on the original file right:
    RUN chmod 0755 *.sh
    
    Login or Signup to reply.
  2. You need to modify user Dockerfile CMD command like this : ["sh", "./startup-production.sh"]

    This will interpret the script as sh, but it can be dangerous if your script is using bash specific features like [[]] with #!/bin/bash as its first line.

    Moreover I would say use ENTRYPOINT here instead of CMD if you want this to run whenever container is up

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search