skip to Main Content

I’m building an image from the following Dockerfile and following command docker build --rm -f "Dockerfile" -t non_root_image_plz_work .:

DockerFile

FROM node:14.7.0-buster-slim AS apache_for_selenium

# Create non-root group and user
RUN addgroup --system shared-folder 
&& adduser --system --home /var/cache/shared-folder --group shared-folder --uid 1001

# Make Port accessable 
EXPOSE 80/tcp

# Set Node env.Name
ENV NODE_ENV=dev 

RUN apt-get -qq update && apt-get -qq install -y --no-install-recommends nano git openssl bash musl curl apache2 apache2-utils systemd && 
    systemctl enable apache2 && npm config set registry http://localhost:5000/repository/repo && 
    npm i -g pm2 serve && mkdir /usr/share/shared-folder

RUN ln -sf /dev/stdout /var/log/apache2/access.log && 
    ln -sf /dev/stderr /var/log/apache2/error.log    

WORKDIR /usr/share/shared-folder 

COPY . /usr/share/shared-folder/

RUN npm install && npm cache clean --force && npm cache verify && 
    rm /var/www/html/index.html && 
    ln -s /usr/share/shared-folder/mochawesome-report /var/www/html/mochawesome-report && 
    chown www-data -R /var/www/html/mochawesome-report && chgrp www-data -R /var/www/html/mochawesome-report 

VOLUME /usr/share/shared-folder/mochawesome-report

USER 1001

CMD [ "sh", "-c", "service apache2 start ; pm2-runtime process.yml --no-daemon" ]

When I try to run the image using docker run non_root_image_plz_work, I get the following error:

Error after running docker run command:
Starting Apache httpd web server: apache2 failed!
The apache2 configtest failed. … (warning).
Output of config test was:
mkdir: cannot create directory ‘/var/run/apache2’: Permission denied
chown: changing ownership of ‘/var/lock/apache2.3FGoa8Y71E’: Operation not permitted

It seems to be a permissions issue, as if I’m not properly running the container as a non-root user. Any suggestions on how I can get the container to run properly as a non-root user?

Note: I used a dummy registry in the Dockerfile for I don’t want to show the actual registry, thanks

3

Answers


  1. In Docker, all folders are owned by root. Without knowing your directory structure, I guess your problem is, that your user 1001 (or the setup programm which is run with 1001‘s permission) tries to access directories that (probably) are owned by root.

    Either you can try:

    1. Change your permissions of the folders.

      This can be used of you know which folders are accessed and want to prevent further permission issues.

      chmod -R 777 /path/to/folder
      
    2. Give your user proper permissions.

      Here is a very quick walkthrough. Please comment if it didn’t slove your problem and I’ll try to update this for a more specific answer.

      A small example (taken from here).
      You can setup your non-root-user foo with passwordless access:

      RUN 
          groupadd -g 1001 foo && useradd -u 1001 -g foo -G sudo -m -s /bin/bash 1001 
      && 
          sed -i /etc/sudoers -re 's/^%sudo.*/%sudo ALL=(ALL:ALL) NOPASSWD: ALL/g' && 
          sed -i /etc/sudoers -re 's/^root.*/root ALL=(ALL:ALL) NOPASSWD: ALL/g' && 
          sed -i /etc/sudoers -re 's/^#includedir.*/## **Removed the include directive** ##"/g' && 
          echo "foo ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers;  su - foo -c id
      

      Hint: You will probably need to install sudo

      apt-get install sudo
      

      Now, try running the entrypoint (or your commad) with sudo.


    EDIT:
    I’ve updated the answer to match your Docker-File. Have a look at it. The user nonroot is assigned uuid 1001 and added to /etc/sudoers. Also your command is now run with sudo which should prevent the permission issues.

    FROM node:14.7.0-buster-slim AS apache_for_selenium
    
    # Create non-root group and user
    RUN addgroup --system shared-folder 
        && adduser --system --home /var/cache/shared-folder --ingroup shared-folder --uid 1001 nonroot
    
    # Make Port accessable 
    EXPOSE 80/tcp
    
    # Set Node env.Name
    ENV NODE_ENV=dev 
    
    RUN apt-get -qq update && apt-get -qq install -y --no-install-recommends 
        sudo nano git openssl bash musl curl apache2 apache2-utils systemd 
        && systemctl enable apache2 
        #
        # && #npm config set registry http://localhost:5000/repository/repo && 
        #npm i -g pm2 serve && mkdir /usr/share/shared-folder
    
    RUN ln -sf /dev/stdout /var/log/apache2/access.log && 
        ln -sf /dev/stderr /var/log/apache2/error.log    
    
    WORKDIR /usr/share/shared-folder 
    
    COPY . /usr/share/shared-folder/
    
    RUN npm install && npm cache clean --force && npm cache verify && 
        rm /var/www/html/index.html && 
        ln -s /usr/share/shared-folder/mochawesome-report /var/www/html/mochawesome-report && 
        chown www-data -R /var/www/html/mochawesome-report && chgrp www-data -R /var/www/html/mochawesome-report 
    
    VOLUME /usr/share/shared-folder/mochawesome-report
    
    RUN 
        sed -i /etc/sudoers -re 's/^%sudo.*/%sudo ALL=(ALL:ALL) NOPASSWD: ALL/g' && 
        sed -i /etc/sudoers -re 's/^root.*/root ALL=(ALL:ALL) NOPASSWD: ALL/g' && 
        sed -i /etc/sudoers -re 's/^#includedir.*/## **Removed the include directive** ##"/g' && 
        echo "nonroot ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
    
    USER nonroot
    CMD [ "sudo sh", "-c", "service apache2 start ; pm2-runtime process.yml --no-daemon" ]
    
    Login or Signup to reply.
  2. The problem here: apache is special user. it only can start by root user.
    you can not start apache by another user. That why you got permission deny.
    Seen i saw your dockerfile. your user created is normal user.

    Try make script like below with name apache-start :

        #!/bin/sh
    set -e
    # Apache gets grumpy about PID files pre-existing
    rm -f /usr/local/apache2/logs/httpd.pid
    exec httpd -DFOREGROUND "$@"
    

    and your docker file should be like

    FROM node:14.7.0-buster-slim AS apache_for_selenium
    # Create non-root group and user
    RUN addgroup --system shared-folder 
    && adduser --system --home /var/cache/shared-folder --group shared-folder --uid 1001
    # Make Port accessable 
    EXPOSE 80/tcp
    # Set Node env.Name
    ENV NODE_ENV=dev 
    RUN apt-get -qq update && apt-get -qq install -y --no-install-recommends nano git openssl bash musl curl apache2 apache2-utils systemd && 
        systemctl enable apache2 && npm config set registry http://localhost:5000/repository/repo && 
        npm i -g pm2 serve && mkdir /usr/share/shared-folder
    RUN ln -sf /dev/stdout /var/log/apache2/access.log && 
        ln -sf /dev/stderr /var/log/apache2/error.log    
    WORKDIR /usr/share/shared-folder 
    COPY . /usr/share/shared-folder/
    RUN npm install && npm cache clean --force && npm cache verify && 
        rm /var/www/html/index.html && 
        ln -s /usr/share/shared-folder/mochawesome-report /var/www/html/mochawesome-report && 
        chown www-data -R /var/www/html/mochawesome-report && chgrp www-data -R /var/www/html/mochawesome-report 
    VOLUME /usr/share/shared-folder/mochawesome-report
    COPY apache-start /usr/local/bin/
    CMD ["apache-start"]
    USER 1001
    
    Login or Signup to reply.
  3. Another option is to switch to podman tool which is an alternative to Docker. With podman you can run containers (the same images you use in Docker) but with normal users. That has a lot of benefits specially from security point of view.

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