Docker run "error while creating mount source path '[...]': mkdir [...]: permission denied" - linux

I'm trying to mount a directory in Docker run:
docker run --restart always -t -v /home/dir1/dir2/dir3:/dirX --name [...]
But I get the error:
error while creating mount source path '/home/dir1/dir2/dir3': mkdir /home/dir1/dir2/dir3: permission denied.
All the directories exist for sure, and the strange thing is when trying to mount dir2 and not dir3 it is working ok:
docker run --restart always -t -v /home/dir1/dir2/:/dirX --name [...] # THIS IS WORKING
All the directories ('dir2' and 'dir3') have the same permissions: drwxr-x---
Any suggestions on what might be the problem? why one is working and the other don't?
Thanks

Check the permission for the folder you're trying to mount docker with ls -la, you might need to modify the permissons with chmod.
If you don't want to modify permissions, just add sudoto the beggining of the command.
sudo docker run --restart always -t -v /home/dir1/dir2/dir3:/dirX --name [...]

Related

docker copy and chown in bash script

I'm building a network with docker compose and some bash scripts and i'm having problems during the process. Basically i have a some containers and volumes.
In one of the container i have to rename a file and copy it in a volume to make it accesible to other containers.
The problem is that this file is regenerated with a different name every time i start the network (this because it's a key) so i don't know its name.
If i try with this command in the container:
docker exec -it containerName cp /path_in_container/* /volume/key.pem
docker give me an error related to the path. The same thing happen if i use
docker exec -it containerName cp /path_in_container/. /volume/key.pem
If i insert the real name this way:
docker exec -it containerName cp /path_in_container/2164921649_sk /volume/key.pem
i have no problem but, how i already explained, i can't know its name.
I tried to solve the problem copying the file from the linked volume folder directly in my system but, since the folder is protected, i need to use:
sudo chown -R user:user /tmp/path/*
In this case, the problem is that if I enter the chown command in a bash script, I then have to enter the password and it doesn't always work.
So I would like to try to copy the file directly from the container by making a copy of all the files in the folder or make the bash script run with the chown command inside, before the various copy operations, without entering the password.
Can someone help me?
Thanks
EDIT:
This is a part of the code useful to understand the problem
#Copy TLS-CA certificate
docker exec -it tls-ca cp /tmp/hyperledger/fabric-ca/admin/msp/cacerts/tls-ca-7051.pem /certificates/tls-ca-7051.pem
echo "Start operation for ORG0"
#ENROLL ORDERER
# for identity
docker exec -it rca-org0 fabric-ca-client enroll -d -u https://orderer1-org0:ordererpw#rca-org0:7052 --tls.certfiles /tmp/hyperledger/fabric-ca/admin/msp/cacerts/rca-org0-7052.pem --home /tmp/hyperledger/fabric-ca-enrollment/orderer --mspdir msp
sleep 5
# for TLS
docker exec -it rca-org0 fabric-ca-client enroll -d -u https://orderer1-org0:ordererPW#tls-ca:7051 --enrollment.profile tls --csr.hosts orderer1-org0 --tls.certfiles /certificates/tls-ca-7051.pem --home /tmp/hyperledger/fabric-ca-enrollment/orderer --mspdir tls-msp
sleep5
#ENROLL ADMIN USER
docker exec -it rca-org0 fabric-ca-client enroll -d -u https://admin-org0:org0adminpw#rca-org0:7052 --tls.certfiles /tmp/hyperledger/fabric-ca/admin/msp/cacerts/rca-org0-7052.pem --home /tmp/hyperledger/fabric-ca-enrollment/admin/ --mspdir msp
sleep 5
#CREATE NECESSARY FOLDERS
docker exec rca-org0 cp /tmp/hyperledger/fabric-ca-enrollment/orderer/tls-mps/keystore/*
chown -R fabrizio:fabrizio /tmp/hyperledger/*
mv /tmp/hyperledger/org0/orderer/tls-msp/keystore/* /tmp/hyperledger/org0/orderer/tls-msp/keystore/key.pem
mkdir -p /tmp/hyperledger/org0/orderer/msp/admincerts
cp /tmp/hyperledger/org0/admin/msp/signcerts/cert.pem /tmp/hyperledger/org0/orderer/msp/admincerts/orderer-admin-cert.pem
mkdir /tmp/hyperledger/org0/msp
mkdir /tmp/hyperledger/org0/msp/{admincerts,cacerts,tlscacerts,users}
cp /tmp/hyperledger/org0/ca/admin/msp/cacerts/rca-org0-7052.pem /tmp/hyperledger/org0/msp/cacerts/org0-ca-cert.pem
cp /tmp/hyperledger/certificates/tls-ca-7051.pem /tmp/hyperledger/org0/msp/tlscacerts/tls-ca-cert.pem
cp /tmp/hyperledger/org0/admin/msp/signcerts/cert.pem /tmp/hyperledger/org0/msp/admincerts/admin-org0-cert.pem
cp ./org0-config.yaml /tmp/hyperledger/org0/msp/config.yaml
In the script you show, you run a series of one-off commands in an existing container, and then need to manage the container filesystem. It might be more straightforward to script a series of docker run commands, that can use docker run -v bind mounts to inject input files into the container and get the output files back out.
docker run --rm \
-v "$PWD/cacerts:/cacerts" \
-v "$PWD/certs:/certs" \
image-for-fabric-ca-client \
fabric-ca-client enroll \
-d \
-u https://orderer1-org0:ordererpw#rca-org0:7052 \
--tls.certfiles /cacerts/rca-org0-7052.pem \
--home /certs \
--mspdir msp
If this invocation has the TLS CA certificates used as input in ./cacerts, and the resulting TLS server certificates as output in ./certs, then you've "escaped" Docker space; you can use ordinary shell commands here.
mv ./certs/*_sk ./certs/key.pem
Depending on what the fabric-ca-client enroll command actually does, it might be possible to run it as the same user ID as on the host
docker run \
-u $(id -u) \
-v "$PWD/certs:/certs" \
...
So long as the host ./cacerts directory is world-readable and the ./certs directory is writable by the current user, the main container process will run as the same (numeric) user ID as on the host, and the files will be readable without chown.
In general I'd recommend avoiding docker exec and docker cp in scripts, in much the same way you don't use a debugger like gdb for routine tasks like generating CA certificates.
Also consider the possibility that you may need to run this script as root anyways. TLS private keys typically aren't readable by other than their owner (mode 0600 or 0400) and you might need to chown the files to the eventual container users, which will require root access. Also note in the last docker run invocation that nothing stops you from specifying -u root or mounting a "system" host directory -v /host-etc:/etc, so it's very easy to use docker run to root the host; on many systems access to the Docker socket will be very reasonably restricted to require sudo access.

Docker build says directory already exists but it is not

In dockerfile I am creating directory /var/log/nginx since it didn't exist in the container even though nginx.conf is set to save logs in /var/log/nginx
However, the docker build failed saying the directory /var/log/nginx already exists. But it doesn't.
Docker build error:
root#jsd-user-management:~/flask# docker build -t flask_app .
Sending build context to Docker daemon 716.8kB
Step 1/6 : FROM tiangolo/uwsgi-nginx-flask:python3.5
---> dea8fea96656
Step 2/6 : RUN mkdir /var/log/nginx
---> Running in 9e9ff86747a7
mkdir: cannot create directory ‘/var/log/nginx’: File exists
The command '/bin/sh -c mkdir /var/log/nginx' returned a non-zero code: 1
Inside Docker container:
root#jsd-user-management:~/flask# docker exec -it flask_jsd-user-management_1 bash
root#c6d43f610a51:/app/app# ls /var/log
root#c6d43f610a51:/app/app#
Surprisingly enough, when I attempt to create the directory from inside the container, it works. However, no logs are populated inside it.
You can use -p flag.
-p, --parents
no error if existing, make parent directories as needed
RUN mkdir -p /var/log/nginx
RUN ls /var/log/
It might be case parent director missing.

Docker: mount image's original /docker-entrypoint.sh to a volume in read/write mode

I try to mount image's original /docker-entrypoint.sh to a volume in read/write mode, in order to be able to change it easily from outside (without entering the container) and then restart the container to observe the changes.
I do it (in ansible) like this:
/app/docker-entrypoint.sh:/docker-entrypoint.sh:rw
If /app/docker-entrypoint.sh doesn't exist on the host, a directory /app/docker-entrypoint.sh (not a file, as wish) is created, and I get following error:
Error starting container e40a90eef1525f554e6078e20b3ab5d1c4b27ad2a7d73aa3bf4f7c6aa337be4f: 400 Client Error: Bad Request (\"OCI runtime create failed: container_linux.go:348: starting container process caused \"process_linux.go:402: container init caused \\\"rootfs_linux.go:58: mounting \\\\\\\"/app/docker-entrypoint.sh\\\\\\\" to rootfs \\\\\\\"/var/lib/docker/devicemapper/mnt/4d3e4f4082ca621ab5f3a4ec3f810b967634b1703fd71ec00b4860c59494659a/rootfs\\\\\\\" at \\\\\\\"/var/lib/docker/devicemapper/mnt/4d3e4f4082ca621ab5f3a4ec3f810b967634b1703fd71ec00b4860c59494659a/rootfs/docker-entrypoint.sh\\\\\\\" caused \\\\\\\"not a directory\\\\\\\"\\\"\": unknown: Are you trying to mount a directory onto a file (or vice-versa)? Check if the specified host path exists and is the expected type
If I touch /app/docker-entrypoint.sh (and set proper permissions) before launching the container - the container fails to start up and keeps restarting (I assume because the /app/docker-entrypoint.sh and therefore internal /docker-entrypoint.sh are empty).
How can I mount the original content of container's /docker-entrypoint.sh to the outside?
If you want to override docker-entry point it should be executable or in other words you have to set chmod +x your_mount_entrypoint.sh in the host then you can mount otherwise it will through permission error. As entrypoint script should be executable.
Second thing, As mentioned in the comment you can mount the file better to keep the entrypoint script in directory like docker-entrypoint/entrypoint.sh.
or if you want to mount specific file then both name should be same otherwise entrypoint script will not be overridden.
docker run --name test -v $PWD/entrypoint.sh:/docker-entrypoint/entrypoint.sh --rm my_image
or
docker run --name test -v $PWD/entrypoint.sh:/docker-entrypoint/entrypoint.sh:rw --rm my_image
See this example, entrypoint generated inside dockerfile and you can overide this from any script but it should be executable and should be mount to docker-entrypoint.
Dockerfile
FROM alpine
RUN mkdir -p /docker-entrypoint
RUN echo -e $'#!/bin/sh \n\
echo "hello from docker generated entrypoint" >> /test.txt \n\
tail -f /test.txt ' >> /docker-entrypoint/entrypoint.sh
RUN chmod +x /docker-entrypoint/entrypoint.sh
ENTRYPOINT ["/docker-entrypoint/entrypoint.sh"]
if you build and run it you will
docker build -t my_image .
docker run -t --rm my_image
#output
hello from docker generated entrypoint
Now if you want to overide
Create and set permission
host_path/entrypoint/entrypoint.sh
for example entrypoint.sh
#!/bin/sh
echo "hello from entrypoint using mounted"
Now run
docker run --name test -v $PWD/:/docker-entrypoint/ --rm my_image
#output
hello from entrypoint using mounted
Update:
If you mount directory of the host it will hide the content of docker image.
The workaround
Mount some directory other then entrypoint name it backup
add instruction in entrypoint to copy entrypoint to that location at run time
So it will create new file on the host directory instead
FROM alpine
RUN mkdir -p /docker-entrypoint
RUN touch /docker-entrypoint/entrypoint.sh
RUN echo -e $'#!/bin/sh \n\
echo "hello from entrypoint" \n\
cp /docker-entrypoint/entrypoint.sh /for_hostsystem/ ' >> /docker-entrypoint/entrypoint.sh
RUN chmod +x /docker-entrypoint/entrypoint.sh
ENTRYPOINT ["/docker-entrypoint/entrypoint.sh"]
Now if you run you will have the docker entrypoint in the host, as opposit as you want
docker run --name test -v $PWD/:/for_hostsystem/ --rm my_image

Docker mounting volume. Permission denied

I have a problem with creating new files in mounted docker volume.
Firstly after installation docker i added my user to docker group.
sudo usermod -aG docker $USER
Created as my $USER folder:
mkdir -p /srv/redis
And starting container:
docker run -d -v /srv/redis:/data --name myredis redis
when i want to create file in /srv/redis as a user which created container I have a problem with access.
mkdir /srv/redis/redisTest
mkdir: cannot create directory ‘/srv/redis/redisTest’: Permission denied
I tried to search in other threads but i didn't find appropriate solution.
The question title does not reflect the real problem in my opinion.
mkdir /srv/redis/redisTest
mkdir: cannot create directory ‘/srv/redis/redisTest’: Permission denied
This problem occurs very likely because when you run:
docker run -d -v /srv/redis:/data --name myredis redis
the directory /srv/redis ownership changes to root. You can check that by
ls -lah /srv/redis
This is normal consequence of mounting external directory to docker. To regain access you have to run
sudo chown -R $USER /srv/redis
I think /srv/redis/redisTest directory is created by user inside redis container, so it belong to redis container user.
Have you already check using ls -l to see that /srv/redis/redisTest directory belong to $USER?
This could also be related (as I just found out) to having SELinux activated. This answer on the DevOps Stack Exchange worked for me:
The solution is to simply append a :z to the [docker] run volume argument so that this:
docker run -v /host/foobar:/src_dir /bin/bash
becomes this:
docker run -it -v /host/foobar:/src_dir:z /bin/bash

Docker volume option create folder as "root" user

I am logged in in my PC (Fedora 24) as rperez. I have setup Docker for being able to run through this user, so I am running a container as follow:
$ docker run -d \
-it \
-e HOST_IP=192.168.1.66 \
-e PHP_ERROR_REPORTING='E_ALL & ~E_STRICT' \
-p 80:80 \
-v ~/var/www:/var/www \
--name php55-dev reypm/php55-dev
Notice the $ sign meaning I am running the command as a non root user (which uses #). The command above creates the following directory: /home/rperez/var/www but owner is set to root I believe this is because docker run as root user behind scenes.
Having this setup I am not able to create a file under ~/var/www as rperez because the owner is root so ...
What is the right way to deal with this? I have read this and this but is not so helpful.
Any help?
As discussioned here, this is an expected behavior of docker. You can create the target volume directory before running docker command or change the owner to your current user after the directory is created by docker:
chown $(whoami) -R /path/to/your/dir
I hit this same issue (also in a genomics context for the very same reason) and also found it quite unintuitive. What is the recommended way to "inherit ownership". Sorry if this described elsewhere, but I couldn't find it. Is it something like:
docker run ... -u $(id -u):$(id -g) ...

Resources