I'm trying to run a simple command with docker that read a file in my home directory and write an output file in the same directory on my local machine (/home/userxyz/projects/data). The data folder belongs to me (userxyz) and my group which has the same name (userxyz) with R/W permissions.
I built an image with a Dockerfile like so (following How to add users to Docker container?):
FROM osgeo/gdal:alpine-small-latest
RUN mkdir /usr/tmp
RUN addgroup -S userxyz \
&& adduser -S -D -h /usr/tmp userxyz userxyz \
&& chown -R userxyz:userxyz /usr/tmp
USER userxyz
WORKDIR /usr/tmp
and:
docker build -t userxyz/test .
I ran docker with:
docker run --rm -v /home/userxyz/projects/data:/usr/tmp userxyz/test gdal_translate -ot UInt32 /usr/tmp/input.tif /usr/tmp/output.tif
However, I still get:
ERROR 4: Attempt to create new tiff file `/usr/tmp/output.tif' failed: Permission denied
It works when I only read the file:
docker run --rm -v /home/userxyz/projects/data:/usr/tmp userxyz/test gdalinfo /usr/tmp/input.tif
Any idea what could be wrong with the writing permissions?
EDIT: when opening the data folder to read/write for "Others", the file is correctly created by user#500100, so I guess it's something with username attribution? How can I do so that the file is created by userxyz and not user#500100?
Although you set the same user & group in Dockerfile with userxyz:userxyz, but host rootfs & container rootfs are 2 different rootfs. This means the UID & GID for same username/group name still be different.
As a result, just copy username, groupname is not enough, you also need to copy UID, GID, something like next:
Dockerfile:
FROM ubuntu:16.04
ARG UID
ARG GID
RUN groupadd -g $GID userxyz
RUN useradd -m -u $UID -g $GID -s /bin/bash userxyz
Build command:
docker build -t abc:1 --build-arg UID=`id userxyz -u` --build-arg GID=`id userxyz -g` .
Explain:
id userxyz -u & id userxyz -g get the UID/GID on host, and pass them to build container, then docker build use them to set the same UID/GID with the host for userxyz. This will assure in container you have same permission with the host.
You must add the user in your group based on the group ID not on the group name. User and group names are isolated in the container, so it won't work.
You can find the group ID in the /etc/group file, using this command on the host machine:
cat /etc/group | grep userxyz
Once found, you add the user to the group in the Dockerfile:
FROM osgeo/gdal:alpine-small-latest
RUN mkdir /usr/tmp
RUN groupadd -g $GID userxyz \
&& adduser -S -D -h /usr/tmp userxyz userxyz \
&& chown -R userxyz:userxyz /usr/tmp
USER userxyz
WORKDIR /usr/tmp
where you replace $GID by the the group ID.
Related
As the title says, I'm trying to run docker compose as a non-root user on an alpine container.
I have the following Dockerfile:
FROM docker.io/jenkins/ssh-agent:4.4.0-alpine-jdk17
# SSH public key
ENV JENKINS_AGENT_SSH_PUBKEY "ssh-key"
# Install Docker CLI
RUN apk add --no-cache docker-cli docker-cli-compose
# Add docker permissions to Jenkins user
COPY docker-perms.sh /docker-perms.sh
RUN delgroup ping && sh /docker-perms.sh
# I have to delete ping group as it has the same GID as docker
and docker-perms.sh:
#!/bin/sh
set -e
DOCKER_SOCKET=/var/run/docker.sock
RUNUSER=jenkins
if [ -S ${DOCKER_SOCKET} ]; then
DOCKER_GID=$(stat -c '%g' ${DOCKER_SOCKET})
DOCKER_GROUP=$(getent group ${DOCKER_GID} | awk -F ":" '{ print $1 }')
if [ $DOCKER_GROUP ]
then
addgroup $RUNUSER $DOCKER_GROUP
else
addgroup -S -g ${DOCKER_GID} docker
addgroup $RUNUSER docker
fi
fi
I then mount the host's docker socket when I start the container. However, two things happen:
I have to re-run docker-perms.sh as root inside the container because running docker ps as jenkins user returns the permission denied error. After running the script, it no longer produces an error
When I run a job from the Jenkins controller, the permission denied error appears again anyway
What am I doing wrong?
I figured out what I was doing wrong: the docker.sock is only mounted after the image is built, so the script can't add the group.
This isn't a very pretty workaround, but I guess I can just add the group directly on the Dockerfile instead:
FROM docker.io/jenkins/ssh-agent:4.4.0-alpine-jdk17
# SSH public key
ENV JENKINS_AGENT_SSH_PUBKEY "ssh-key"
# Install Docker CLI
RUN apk add --no-cache docker-cli docker-cli-compose
# Add Docker permissions to Jenkins user
RUN DOCKER_GID=999 && \
delgroup $(grep $DOCKER_GID /etc/group | cut -d: -f1) && \
addgroup -S -g $DOCKER_GID docker && addgroup jenkins docker
This supposes that the docker group ID will be 999
Is there a way to execute or login as current user to a bash of specific container . I tried running docker-compose exec -u $USER phoenix bash but it says unable to find user raz: no matching entries in passwd file
I tried another way by adding a useradd command in a dockerfile.
FROM elixir:latest
ARG USER_ID
ARG GROUP_ID
RUN addgroup --gid $GROUP_ID raz
RUN adduser --disabled-password --gecos '' --uid $USER_ID --gid $GROUP_ID raz
USER raz
RUN apt-get update && \
apt-get install -y postgresql-client && \
apt-get install -y inotify-tools && \
apt-get install -y nodejs && \
curl -L https://npmjs.org/install.sh | sh && \
mix local.hex --force && \
mix archive.install hex phx_new 1.5.3 --force && \
mix local.rebar --force
COPY . /app
WORKDIR /app
COPY ./entrypoint.sh /entrypoint.sh
RUN ["chmod", "+x", "/entrypoint.sh"]
ENTRYPOINT ["/entrypoint.sh"]
but when I run docker-compose build I get a permission denied error when running the apt-get commands.
I also look for gosu as a step down root user but it seems complicated.
Is it possible for added user in Dockerfile command to have same permission as my current user?
I'm running WSL2 btw.
This question is pretty interesting. Let me begin with a short explanation:
Understanding the problem
In fact the user that exists inside container will be valid only inside the container itself. What you're trying to do is to use a user that exists outside a container, i.e. your docker host, inside a container. Unfortunately this movement can't be done in a normal way.
For instance, let me try to change to my user in order to get this container:
$ docker run -it --rm --user jon ubuntu whoami
docker: Error response from daemon: unable to find user jon: no matching entries in passwd file.
I tried to run a classic ubuntu container inside my docker host; Although the user exists on my local machine, the Docker image says that didn't find the user.
$ id -a
uid=1000(jon) gid=1001(jon) groups=1001(jon),3(sys),90(network),98(power),108(vboxusers),962(docker),991(lp),998(wheel),1000(autologin)
The command above was executed on my computer, proving that "jon" username exists.
Making my username available inside a container: a docker trick
I suppose that you didn't create a user inside your container. For demonstration I'm going to use the ubuntu docker image.
The trick is to mount both files responsible for handling your user and group definition inside the container, enabling the container to see you inside of it.
$ docker run -it --rm --volume /etc/passwd:/etc/passwd:ro --volume /etc/group:/etc/group:ro --user $(id -u) ubuntu whoami
jon
For a more complete example:
$ docker run -it --rm --volume /etc/passwd:/etc/passwd:ro --volume /etc/group:/etc/group:ro --user $(id -u):$(id -g) ubuntu "id"
uid=1000(jon) gid=1001(jon) groups=1001(jon)
Notice that I used two volumes pointing to two files? /etc/password and /etc/group?
Both I mounted read only (appending ":ro") just for safety.
Also notice that I used the id -u, which brings me the user id (1000 on my case), forcing the user id for being the same of mine defined on my /etc/password file.
Caveat
If you try to set the username to jon rather than the UID, you're going to run into an issue:
$ docker run -it --rm --volume /etc/passwd:/etc/passwd:ro --volume /etc/group:/etc/group:ro --user jon ubuntu whoami
docker: Error response from daemon: unable to find user jon: no matching entries in passwd file.
This happens because the docker engine would try to change the username before mouting the volumes and this should exists before running the container. If you provide a numeric representation of the user, this one doesn't needs to exist within the container, causing the trick to work;
https://docs.docker.com/engine/reference/run/#user
I hope being helpful. Be safe!
Building on top of the answer by Joepreludian, focusing on docker-compose:
You can use the user: and volumes: options in the compose file. For example:
my-service:
image: ubuntu:latest
user: ${MY_UID}:${MY_GID}
volumes:
- /etc/passwd:/etc/passwd:ro
- /etc/group:/etc/group:ro
and define these variables where you are starting your compose:
MY_UID="$(id -u)" MY_GID="$(id -g)" docker-compose up
I try to start a new container from ubuntu 18.04 docker image. I do as follows:
pull the docker image
docer pull ubuntu:18.04
create a new container
docker run -ti -v $(pwd):/home/shared --name ubuntu_test ubuntu:18.04
and then log out.
start the created container
docker start ubuntu_test
log in as root user, update OS and install vim
docker exec -ti ubuntu_test /bin/bash and apt update, apt install -y vim
then log out.
log in as non-root user
docker exec -ti -u daemon ubuntu_test /bin/bash
Then I found that I have no permission to create new files or new folders.
I do not want to log in as root user since there could be some problems with mpirun.
Is there any solution for this problem ? Thank you for any help.
It is not like you (non-root user) don't have permissions to write or read. It is that everything on the system (files/folders) belong to the root user and no other user can modify anything by default.
You can create a new user as well as home folder for that user when you are building the image and then the user will be able to modify stuff in its home (standard linux stuff).
Example Dockerfile
FROM ubuntu
RUN groupadd --gid 1000 someuser \
&& useradd --uid 1000 --gid someuser --shell /bin/bash --create-home someuser
test with
docker build -t utest .
docker container run -it -u someuser utest /bin/bash
cd /home/someuser
touch myfile
If you need to add some other folders under that user's administration other than its home, you can use chown -R someuser:someuser <folder> which will recursively change ownership of the specified folder and everything in it to that of the new user.
Example: changing ownership of /etc folder
FROM ubuntu
RUN groupadd --gid 1000 someuser \
&& useradd --uid 1000 --gid someuser --shell /bin/bash --create-home someuser
RUN chown -R someuser:someuser /etc
I have containers for multiple Atlassian products; JIRA, Bitbucket and Confluence. When I'm trying to access the running containers I'm usually using:
docker exec -it -u root ${DOCKER_CONTAINER} bash
With this command I'm able to access as usual, but after running a script to extract and compress log files, I can't access that one container anymore.
Excerpt from the 'clean up script'
This is the first point of failure, and the script is running once each week (scheduled by Jenkins).
docker cp ${CLEAN_UP_SCRIPT} ${DOCKER_CONTAINER}:/tmp/${CLEAN_UP_SCRIPT}
if [ $? -eq 0 ]; then
docker exec -it -u root ${DOCKER_CONTAINER} bash -c "cd ${LOG_DIR} && /tmp/compressOldLogs.sh ${ARCHIVE_FILE}"
fi
When the script executes these two lines towards the Bitbucket container the result is:
unable to find user root: no matching entries in passwd file
It's failing on the 'docker cp'-command, but only towards the Bitbucket container. After the script has ran, the container is unaccessible with both the 'bitbucket' (defined in Dockerfile) and 'root' users.
I was able to copy /etc/passwd out of the container, and it contains all of the users as expected. When trying to access by uid, I get the following error:
rpc error: code = 2 desc = oci runtime error: exec failed: process_linux.go:75: starting setns process caused "fork/exec /proc/self/exe: no such file or directory"
Dockerfile for Bitbucket image:
FROM java:openjdk-8-jre
ENV BITBUCKET_HOME /var/atlassian/application-data/bitbucket
ENV BITBUCKET_INSTALL_DIR /opt/atlassian/bitbucket
ENV BITBUCKET_VERSION 4.12.0
ENV DOWNLOAD_URL https://downloads.atlassian.com/software/stash/downloads/atlassian-bitbucket-${BITBUCKET_VERSION}.tar.gz
ARG user=bitbucket
ARG group=bitbucket
ARG uid=1000
ARG gid=1000
RUN mkdir -p $(dirname $BITBUCKET_HOME) \
&& groupadd -g ${gid} ${group} \
&& useradd -d "$BITBUCKET_HOME" -u ${uid} -g ${gid} -m -s /bin/bash ${user}
RUN mkdir -p ${BITBUCKET_HOME} \
&& mkdir -p ${BITBUCKET_HOME}/shared \
&& chmod -R 700 ${BITBUCKET_HOME} \
&& chown -R ${user}:${group} ${BITBUCKET_HOME} \
&& mkdir -p ${BITBUCKET_INSTALL_DIR}/conf/Catalina \
&& curl -L --silent ${DOWNLOAD_URL} | tar -xz --strip=1 -C "$BITBUCKET_INSTALL_DIR" \
&& chmod -R 700 ${BITBUCKET_INSTALL_DIR}/ \
&& chown -R ${user}:${group} ${BITBUCKET_INSTALL_DIR}/
${BITBUCKET_INSTALL_DIR}/bin/setenv.sh
USER ${user}:${group}
EXPOSE 7990
EXPOSE 7999
WORKDIR $BITBUCKET_INSTALL_DIR
CMD ["bin/start-bitbucket.sh", "-fg"]
Additional info:
Docker version 1.12.0, build 8eab29e
docker-compose version 1.8.0, build f3628c7
All containers are running at all times, even Bitbucket works as usual after the issue occurres
The issue disappears after a restart of the container
You can use this command to access to the container with root user:
docker exec -u 0 -i -t {container_name_or_hash} /bin/bash
try debug with that. i think the script maybe remove or disable root user.
This issue is caused by a docker engine bug but which is tracked privately, Docker is asking users to restart the engine!
It seems that the bug is likely to be older than two years!
https://success.docker.com/article/ucp-health-checks-fail-unable-to-find-user-nobody-no-matching-entries-in-passwd-file-observed
https://forums.docker.com/t/unable-to-find-user-root-no-matching-entries-in-passwd-file/26545/7
... what can I say, someone is doing his best to get more funding.
Its a Long standing issue, replicated on my old version 1.10.3 to at least 1.17
As mentioned by #sorin the the docker forum says Running docker stop and then docker start fixes the problem but is hardly a long-term solution...
The docker exec -u 0 -i -t {container_name_or_hash} /bin/bash solution also in the same forum post mentioned here by #ObranZoltan might work for you, but does not work for many. See my output below
$ sudo docker exec -u 0 -it berserk_nobel /bin/bash
exec: "/bin/bash": stat /bin/bash: input/output error
I met a problem while using docker.
Now I have a ubuntu based docker container. And in the container ,the user id is root by default which is not my expectation, I suppose the user id is like abc which is another user account on the HOST OS running docker.
I have tried the following ways but all fail:
su abc;
Then running docker run xxx to bring up a container, but login the container, the user in container is still root.
Then by adding the -u flag for docker run: like :
docker run -t -i -u abc ubuntu /bin/bash
the the docker show errors unable to find user abc
Can some one tell me how to fix it?
Or does docker support run a container in which the user is a specific one than the default root?
You can create User inside Docker images. But for that you will have to extend base image. For example you can create user abc in Ubuntu as below,
FROM ubuntu:14.04
RUN apt-get update
# Replace 1000 with your user / group id
RUN export uid=1000 gid=1000 && \
mkdir -p /home/abc && \
echo "abc:x:${uid}:${gid}:Abc,,,:/home/abc:/bin/bash" >> /etc/passwd && \
echo "abc:x:${uid}:" >> /etc/group && \
echo "abc ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/abc && \
chmod 0440 /etc/sudoers.d/abc && \
chown ${uid}:${gid} -R /home/abc
USER abc
ENV HOME /home/abc
WORKDIR $HOME
CMD /bin/bash
Then you build and run it,
docker build -t abc .
docker run -it abc bash
you should see bash prompt with user abc like below,
abc#<container-hostname>:~$
According to https://medium.com/redbubble/running-a-docker-container-as-a-non-root-user-7d2e00f8ee15, this is possibly, but you can only refer to HOST users by their numerical ids. Read that helpful article for more details and a fuller explanation.