docker 在 bash 脚本中复制并 chown

docker copy and chown in bash script

我正在使用 docker compose 和一些 bash 脚本构建网络,但在此过程中我遇到了问题。基本上我有一些容器和卷。 在其中一个容器中,我必须重命名一个文件并将其复制到一个卷中,以使其可供其他容器访问。 问题是每次我启动网络时都会用不同的名称重新生成这个文件(这是因为它是一个密钥)所以我不知道它的名字。 如果我在容器中尝试使用此命令:

docker exec -it containerName cp /path_in_container/* /volume/key.pem

docker给我一个路径相关的错误。如果我使用

也会发生同样的事情
docker exec -it containerName cp /path_in_container/. /volume/key.pem

如果我这样输入真实姓名:

docker exec -it containerName cp /path_in_container/2164921649_sk /volume/key.pem

我没问题,但是,我已经解释过了,我不知道它的名字。

我试图解决直接从系统中的链接卷文件夹复制文件的问题,但是由于该文件夹受到保护,我需要使用:

sudo chown -R user:user /tmp/path/*

在这种情况下,问题是如果我在 bash 脚本中输入 chown 命令,然后我必须输入密码并且它并不总是有效。

所以我想尝试通过复制文件夹中的所有文件直接从容器中复制文件,或者使用里面的 chown 命令制作 bash 脚本 运行,在进行各种复制操作之前,无需输入密码。 有人能帮我吗? 谢谢

编辑: 这是有助于理解问题的代码的一部分

#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

在您显示的脚本中,您在现有容器中 运行 一系列 one-off 命令,然后需要管理容器文件系统。编写一系列 docker run 命令的脚本可能更直接,可以使用 docker run -v bind mounts 将输入文件注入容器并取回输出文件。

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

如果此调用将 TLS CA 证书用作 ./cacerts 中的输入,并将生成的 TLS 服务器证书用作 ./certs 中的输出,那么您已经“逃脱”了 Docker space;你可以在这里使用普通的 shell 命令。

mv ./certs/*_sk ./certs/key.pem

根据 fabric-ca-client enroll 命令的实际作用,可能 运行 它与主机上的用户 ID 相同

docker run \
  -u $(id -u) \
  -v "$PWD/certs:/certs" \
  ...

只要主机./cacerts目录是world-readable并且./certs目录对当前用户是可写的,主容器进程将运行一样(数字)主机上的用户 ID,文件无需 chown.

即可读取

一般来说,我建议避免在脚本中使用 docker execdocker cp,这与您不使用像 gdb 这样的调试器来执行诸如生成 CA 之类的常规任务的方式大致相同证书。

还要考虑您可能需要 运行 这个脚本作为 root 的可能性。 TLS 私钥通常不能被其所有者(模式 0600 或 0400)以外的人读取,您可能需要 chown 将文件提供给最终的容器用户,这将需要 root 访问权限。另请注意,在上次 docker run 调用中,没有什么可以阻止您指定 -u root 或挂载“系统”主机目录 -v /host-etc:/etc,因此使用 docker run 根目录非常容易主持人;在许多系统上,对 Docker 套接字的访问将被非常合理地限制为需要 sudo 访问权限。