How to give non-root user permission to make and give access to a folder in a Dockerfile - docker

I am trying to create/permission to folders using a non-root user using an image from ubi8/ubi-minimal redhat.
Here are two questions:
Make a folder: Another way to give non-user permission to create folders and give permission to folders. I have searched a bit. Could be possible under the RUN command after it installs all package with microdnf?
Give access: Will RUN chmod -R 777 /app is not best practice and best to do RUN chown -R $USER:$USER /app?
Here is my Dockerfile which I repeat chown a bit for permission.
FROM registry.access.redhat.com/ubi8/ubi-minimal
ENV USER=appuser
RUN microdnf update -y \
&& rm -rf /var/cache/yum \
&& microdnf install gcc wget tar gzip make zlib-devel findutils bzip2-devel openssl-devel ncurses-devel \
sqlite-devel libffi-devel xz-devel which shadow-utils \
&& microdnf clean all ;\
useradd -m $USER
RUN chown -R $USER:$USER /opt
RUN mkdir -p /app
RUN chown $USER /app
USER $USER
WORKDIR /app
COPY . /app/
RUN chown -R $USER:$USER /app

Related

Understanding comand in run of docker

I have code which have dockerfile having this
FROM node:16-slim AS base
RUN apt-get update
RUN apt-get -y install build-essential libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev
RUN useradd -ms /bin/bash xyz-deployer
WORKDIR /srv/app
RUN chmod -R g+rwX /srv/app
RUN yarn global add ts-node#^10.1.0
Can someone please tell me what is this doing in particular?
RUN useradd -ms /bin/bash xyz-deployer
WORKDIR /srv/app
RUN chmod -R g+rwX /srv/app
RUN useradd -ms /bin/bash xyz-deployer
creates a new user called xyz-deployer with a home directory and /bin/bash as the shell.
WORKDIR /srv/app
changes the working directory to /srv/app.
RUN chmod -R g+rwX /srv/app
sets all files in /srv/app to be group readable, writable and executable.
It doesn't make much sense in the context of the Dockerfile you've shown, but hopefully it helps.

Docker: how to use entrypoint + CMD together

I know the difference between ENTRYPOINT and CMD but cannot solve myself my issue.
This is my Dockerfile for use ansible without install it.
FROM python:3.10.4-slim-buster
# Update and upgrade
RUN apt-get update -y && apt-get upgrade -y
# Install requirements
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends openssh-client sshpass
RUN pip install pip --upgrade
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY entrypoint.sh /entrypoint.sh
RUN chmod a+x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
CMD ["--version"]
And this is the entrypoint.sh
#!/usr/bin/env sh
set -e
cp -pr /ssh /root/.ssh
chown -R root:root /root/.ssh/config
ansible-playbook
So, I'm expecting that launching my Docker with
docker run \
--rm -it \
-v $(TOPDIR)/playbook:/playbook:ro \
-v ~/.ssh:/ssh:ro \
sineverba/ansible:latest
(so, without arguments or CMDs) I get the version of ansible in console. But nothing is returned or printed.
Neither if I add the right usage, that I thought it overwrites the CMD instruction
docker run \
--rm -it \
-v $(TOPDIR)/playbook:/playbook:ro \
-v ~/.ssh:/ssh:ro \
--name $(CONTAINER_NAME) \
$(IMAGE_NAME):$(VERSION) \
-i /playbook/inventory.yml /playbook/playbook.yml
But, If I remove the entrypoint and re-build with
FROM python:3.10.4-slim-buster
# Update and upgrade
RUN apt-get update -y && apt-get upgrade -y
# Install requirements
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends openssh-client sshpass
RUN pip install pip --upgrade
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY entrypoint.sh /entrypoint.sh
RUN chmod a+x /entrypoint.sh
ENTRYPOINT ["ansible-playbook"]
CMD ["--version"]
I get version in console / I can use ansible (well, no, 'because I need to change owner of SSH keys) but, apart of ssh trouble, I get my working docker.
So, how can I replace the entrypoint ansible-playbook with the sh entrypoint?
Your script doesn't do anything with any parameters it might get. You need to add the parameters to the ansible-playbook command in the script, like this
#!/usr/bin/env sh
set -e
cp -pr /ssh /root/.ssh
chown -R root:root /root/.ssh/config
ansible-playbook $#

docker image only runs on kubernetes if runAsGroup, runAsUser are changed to 0 from 1000

I'd like to start with I'm new to docker/kubernetes, so I apologize if I get terminologies wrong.
We are trying to get our docker image to run on kubernetes. When deployed on kubernetes, the yaml file generated has this line:
securityContext:
runAsUser: 1000
runAsGroup: 1000
As is, the website doesn't work, but if changed to 0 from 1000, it works.
We suspect that it has to do with apache in our Dockerfile, but haven't been able to figure out how to fix it. Here is the Dockerfile (with ENV and COPY commands removed):
FROM cern/cc7-base
EXPOSE 8083
RUN yum update -y && yum install -y \
ImageMagick \
httpd \
npm \
php \
python3-pip
RUN echo "alias python=python3" >>~/.bashrc
RUN yum update -y && yum install -y \
epel-release \
root \
python3-root
COPY requirements.txt /code/requirements.txt
RUN pip3 install -r /code/requirements.txt
RUN mkdir /db /run/secrets
RUN chown -R apache:apache /db /var/www /run/secrets
RUN ln -s /dev/stdout /etc/httpd/logs/access_log
RUN ln -s /dev/stderr /etc/httpd/logs/error_log
RUN chown apache:apache /etc/httpd/logs/error_log
RUN chown apache:apache /etc/httpd/logs/access_log
RUN chmod 666 /etc/httpd/logs/error_log
RUN chmod 666 /etc/httpd/logs/access_log
WORKDIR /webapp
COPY webapp/package.json /webapp/package.json
RUN npm install
COPY webapp /webapp
RUN npm run build
RUN cp -r /webapp/build /var/www/public
RUN cp -r /webapp/build /webapp/public
RUN mkdir /var/www/results /var/www/results/pdfs /var/www/results/pngs /var/www/results/jsons
RUN chmod 777 /var/www/results /var/www/results/pdfs /var/www/results/pngs /var/www/results/jsons
RUN chgrp -R 1000 /run && chmod -R g=u /run
RUN chgrp -R 1000 /etc/httpd/logs && chmod -R g=u /etc/httpd/logs
CMD ["/usr/sbin/httpd","-D","FOREGROUND"]
Some of the things I tried are: How to run Apache as non-root user?, https://www.henryxieblogs.com/2020/01/dockerfile-example-of-linux-nonroot.html, https://takac.dev/docker-run-apache-as-non-root-user-based-on-the-official-image/
I am not sure if they are not addressing my problem, or if I am just executing the solutions wrong.
Changing the location of error_log, access_log in httpd.conf solved this for me. I also changed all the apache:apache to 1000:1000 in the Dockerfile.
I got the idea to change the location of the logs from here:
https://stackoverflow.com/a/525724/9062782

How to run docker container from non-root user?

How do I make a docker container run as non-root user and have working directory (and its files) owned by a non-root user. Variants I could find in various online tutorials didn't work for some reason, files in /var/www would still be owned by root root.
Below is my Dockerfile, I use docker-compose to build and run containers. Host system is Windows 10.
FROM php:7.4-fpm
ARG user
ARG uid
RUN apt-get update && apt-get install -y \
libpng-dev \
libonig-dev \
libxml2-dev \
zip \
unzip
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
WORKDIR /var/www
USER $user
You can try this docker file
FROM php:7.4-fpm
ARG user
ARG uid
RUN apt-get update && apt-get install -y \
libpng-dev \
libonig-dev \
libxml2-dev \
zip \
unzip
RUN addgroup -g $uid $user && \
adduser -S -G $user -u $uid -h $user
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
RUN chown $user:$user -R /var/www
WORKDIR /var/www
USER $user
This change is needed to make sure that the user is created in the docker image
RUN addgroup -g $uid $user && \
adduser -S -G $user -u $uid -h $user
This is needed to change the ownership of the files to the new user
RUN chown $user:$user -R /var/www
Simply add
RUN chown $user:$user -R /var/www
before your WORKDIR instruction. Similarly you can change ownership for other locations as needed.

How to change permission of a folder to 777 in Dockerfile?

I have a project directory like this:
|-var/www
|-docker-compose.yml
|-app
|--uploads
|---photos
|-Dockerfile
This is my docker-compose.yml file:
myapp:
build:
context: myfolder
dockerfile: Dockerfile
container_name: flask
image: api/v1:01
restart: unless-stopped
environment:
APP_ENV: "prod"
APP_DEBUG: "False"
APP_PORT: 5000
volumes:
- appdata:/var/www
What I want:
I want to change app/uploads/photos this folder's permission to 777.This is an upload folder,so user can upload to this folder.
My Dockerfile now is look like this:
FROM python:3.6.8-alpine3.9
ENV GROUP_ID=1000 \
USER_ID=1000
WORKDIR /var/www/
ADD . /var/www/
RUN apk add --no-cache build-base libffi-dev openssl-dev ncurses-dev
RUN pip install --upgrade pip
RUN pip install -r requirements.txt
RUN addgroup -g $GROUP_ID www
RUN adduser -D -u $USER_ID -G www www -s /bin/sh
USER www
EXPOSE 5000
After looking in this question,In order to achieve what I want,I tried below:
FROM python:3.6.8-alpine3.9
ENV GROUP_ID=1000 \
USER_ID=1000
WORKDIR /var/www/
ADD . /var/www/
RUN apk add --no-cache build-base libffi-dev openssl-dev ncurses-dev
RUN pip install --upgrade pip
RUN pip install -r requirements.txt
RUN addgroup -g $GROUP_ID www
RUN adduser -D -u $USER_ID -G www www -s /bin/sh
RUN chown -R www:www /var/www
RUN chmod -R 777 /var/www/uploads
RUN chmod -R 777 /var/www/uploads/photos
USER www
EXPOSE 5000
But seems like the chmod command in my dockerfile is not taking effect.Cause whenever I upload some files to app/uploads/photos in my code,my nginx server keep getting this error:
PermissionError: [Errno 13] Permission denied: '/var/www/uploads/photos/myfilename.png'
Somebody please help.Please provide a solution for how to change the permission of a folder in Dockerfile.
UPDATE:
I tried to change the permission of /var/www/uploads after build the container and the container is running by doing below:
docker exec -it myapp /bin/sh
then run
chmod -R 777 /var/www/uploads
What I get is chmod: /var/www/uploads: Operation not permitted
Therefore I suspect the this error will also happened when the docker is building,then according to this answer from serverfault, I tried to modify the dockerfile to this:
FROM python:3.6.8-alpine3.9
ENV GROUP_ID=1000 \
USER_ID=1000
WORKDIR /var/www/
ADD . /var/www/
USER root
RUN chmod -R 777 /var/www/uploads
RUN addgroup -g $GROUP_ID www
RUN adduser -D -u $USER_ID -G www www -s /bin/sh
USER www
RUN apk add --no-cache build-base libffi-dev openssl-dev ncurses-dev
RUN pip install --upgrade pip
RUN pip install -r requirements.txt
EXPOSE 5000
But it still doesnt work.Look like my above approach is also wrong.Cause I already run in root in the dockerfile.But at the same time,when I access the container in host using docker exec,also getting Operation not permitted.
I am very new in Docker.Just cant figure it out how to get this done.
What I hope to know:
1) How to change the folder var/www/uploads to permission 777?
2) What is the problem causing I cant change the permission from my approach?
3) What is the better way to achieve this? (If any)

Resources