docker copy and chown in bash script - linux

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.

Related

User/group permissions change when launching Docker container on remote server

I am trying to use a remote server to run experiments on Docker. The problem is that I have scripts that actively modify configuration files within the Docker container to run experiments, which I can only do if the user/group that owns the files does it (I do not have root access on the remote server).
On my local system, the user / group permissions are my personal user when accessed without launching the docker container. And as soon as the docker container is launched, the user / groups change to alice / alice by configuration as seen in the Dockerfile. But on the remote server, it shows as root / root even after launching in the docker container. Any suggestions?
Within my build/run shell script for Docker, I have the lines:
.
.
.
CURR_UID=$(id -u)
CURR_GID=$(id -g)
RUN_OPT="-u $CURR_UID:$CURR_GID --net=host --env DISPLAY=$DISPLAY \
--volume $XAUTHORITY:/home/alice/.Xauthority \
--volume /tmp/.X11-unix:/tmp/.X11-unix \
--privileged $MOUNT_DEVEL $MOUNT_LEARN \
--shm-size $SHM_SIZE $GPU_OPT $CONT_NAME \
-it $DETACH --rm $IMAGE_NAME:latest"
docker run $RUN_OPT
.
.
.
The run option -u $CURR_UID:$CURR_GID is supposed to set the user/group permissions to whatever user/group is running it at the moment. And within my Dockerfile:
.
.
.
# Working user
RUN groupadd --gid ${GROUP_ID} alice && \
useradd -m -s /bin/bash -u ${USER_ID} -g ${GROUP_ID} alice && \
echo "alice:alice" | chpasswd && adduser alice sudo
.
.
.
I can provide more information if needed, I really just need any help at all. Been at this for days. Please advise. Thank you.
In your docker container you can set the effective user with the directive:
USER alice
It is documented here: https://docs.docker.com/engine/reference/builder/#user

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

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 [...]

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

Providing shell access to particular docker container to user which is not added to docker group

My task is provide access to particular docker container without adding user to docker group.
What I did
1) Made a nsenter-based script which must enter container (let's call it script1.sh)
#!/bin/bash
PID=$(docker inspect --format {{.State.Pid}} kayako-dashboard)
nsenter --target $PID --mount --uts --ipc --net --pid /bin/sh
2) Make this script globally available sudo ln -s /full/path/to/script1.sh /usr/local/bin/some_new_command
3) Adjusted target ssh key by adding command="some_new_command" before ssh-rsa in authorized_keys file.
But when I log in under target user
sshpass -p <user_password> ssh <target_user>#<docker_host> "some_new_command"
I got an error Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock
What is wrong and is there any way to fix ?
My kernel version is 4.4.0, so it supports entering the pid namespace.
nsenter version: nsenter from util-linux 2.27.1
P.S. Even if I add <target_user to docker group and try to execute some_new_command I got an error: nsenter: cannot open /proc/<PID>/ns/ipc: Permission denied
P.P.S. If I use sudo some_new_command are executing fine.

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