我试图从秘密设置密码,但它没有拿起它。Docker Server 版本是 17.06.2-ce。我使用以下命令来设置机密:
echo "abcd" | docker secret create password -
我的码头工人撰写 yml 文件看起来像这样
version: '3.1'
...
build:
context: ./test
dockerfile: Dockerfile
environment:
user_name: admin
eureka_password: /run/secrets/password
secrets:
- password
我也有根机密标签:
secrets:
password:
external: true
当我在环境中对密码进行硬编码时,它可以工作,但是当我尝试通过机密时,它不会拾取。我试图将撰写版本更改为 3.2,但没有运气。任何指示都非常感谢!
要详细说明原始接受的答案,只需更改您的docker-compose.yml文件,使其包含以下内容作为入口点:
version: "3.7"
services:
server:
image: alpine:latest
secrets:
- test
entrypoint: [ '/bin/sh', '-c', 'export TEST=$$(cat /var/run/secrets/test) ; source /entrypoint.sh' ]
secrets:
test:
external: true
这样你就不需要任何额外的文件了!
你需要修改docker compose才能从/run/secrets
读取秘密env文件。如果要通过 bash
设置环境变量,可以覆盖docker-compose.yaml
文件,如下所示。
您可以将以下代码另存为entrypoint_overwrited.sh
:
# get your envs files and export envars
export $(egrep -v '^#' /run/secrets/* | xargs)
# if you need some specific file, where password is the secret name
# export $(egrep -v '^#' /run/secrets/password| xargs)
# call the dockerfile's entrypoint
source /docker-entrypoint.sh
在docker-compose.yaml
覆盖dockerfile
和entrypoint
键:
version: '3.1'
#...
build:
context: ./test
dockerfile: Dockerfile
entrypoint: source /data/entrypoint_overwrited.sh
tmpfs:
- /run/secrets
volumes:
- /path/your/data/where/is/the/script/:/data/
environment:
user_name: admin
eureka_password: /run/secrets/password
secrets:
- password
使用上面的代码片段,将覆盖环境变量user_name
或eureka_password
。如果您的秘密 env 文件定义了相同的 env var,那么如果您在服务中定义某些 env_file
也会发生同样的情况。
我发现了亚历杭德罗方法的巧妙扩展:使您的自定义入口点从ENV_FILE
变量加载到ENV
变量:
environment:
MYSQL_PASSWORD_FILE: /run/secrets/my_password_secret
entrypoint: /entrypoint.sh
然后在您的entrypoint.sh
:
#!/usr/bin/env bash
set -e
file_env() {
local var="$1"
local fileVar="${var}_FILE"
local def="${2:-}"
if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then
echo >&2 "error: both $var and $fileVar are set (but are exclusive)"
exit 1
fi
local val="$def"
if [ "${!var:-}" ]; then
val="${!var}"
elif [ "${!fileVar:-}" ]; then
val="$(< "${!fileVar}")"
fi
export "$var"="$val"
unset "$fileVar"
}
file_env "MYSQL_PASSWORD"
然后,当上游图像更改添加对_FILE
变量的支持时,您可以删除自定义入口点,而无需更改撰写文件。
一种选择是在运行命令之前直接映射密钥:
entrypoint: "/bin/sh -c 'eureka_password=`cat /run/secrets/password` && echo $eureka_password'"
例如节点的 MYSQL 密码:
version: "3.7"
services:
app:
image: xxx
entrypoint: "/bin/sh -c 'MYSQL_PASSWORD=`cat /run/secrets/sql-pass` npm run start'"
secrets:
- sql-pass
secrets:
sql-pass:
external: true
这是对接受答案的类似方法,只是从另一边:"如果你想让一个秘密出现在环境中,只需在其名称后附加'.env'"。符合 POSIX 标准,因此适用于每个/bin/sh,而不仅仅是 bash:
# ############################################################
# secrets2env.sh
#
# Set environment variables from secret files
#
# For every secret file ending in ".env",
# set an environment variable with the same name
# but without the ".env" suffix, and the contents
# of the file as its value.
# Then call all positional parameters (=original entrypoint).
#
# This is meant to be used in docker compose when you don't have control
# over the docker image which requires secrets in environment variables.
# Simply inject this script as a new entrypoint and name your file
# secrets as required:
#
# ------------------------------------------------------------
# docker-compose.yml
# ------------------------------------------------------------
# services:
# app:
# entrypoint: ["/run/secrets/secrets2env.sh", "/original-entrypoint-if-any"]
# secrets:
# - ADMIN_PASSWORD.env
# - source: secrets2env.sh
# target: /run/secrets/secrets2env.sh
# mode: 0777
#
# secrets:
# ADMIN_PASSWORD.env:
# file: ./secrets/ADMIN_PASSWORD.env
# secrets2env.sh:
# file: ./secrets/secrets2env.sh
# ------------------------------------------------------------
# (adding the script itself as a secret seems fitting, you may prefer it
# as a config, or even just a bind mount)
# (the file in /run/secrets/ will be named ADMIN_PASSWORD.env
# because that's the name of the secret - your original local file could
# be named differently - I'm just trying to keep it simple)
#
# The container will get an environment variable
# "ADMIN_PASSWORD" with the value being the contents
# of your file ./secrets/ADMIN_PASSWORD_ENV.env
# (in the container, the file /run/secrets/ADMIN_PASSWORD.env
# will also still exist, it is just read into the variable)
#
# Unfortunately, it's not possible to "inherit" the original
# entrypoint and command of the image. Even worse, if you set
# a new entrypoint then the original command is nulled out and needs
# to be set again. See https://stackoverflow.com/a/47063296
#
# Use docker inspect to look them both up, e.g. `docker inspect postgres:13`
# will show you in "Config" that "Cmd": ["postgres"] and
# "Entrypoint": ["docker-entrypoint.sh"] so you set
# entrypoint: ["/run/secrets/secrets2env.sh", "docker-entrypoint.sh"]
# command: postgres
# You may want to copy it to /secrets2env.sh to make the call shorter
# but I prefer it in the same directory as the secret files.
# ############################################################
for secret_file in $(find /run/secrets -name '*.env'); do
export "$(basename "${secret_file%.env}")"="$(cat "$secret_file")"
done
# Chain with existing entrypoint (if any)
exec "$@"
设置文件模式以使其可执行需要长符号,这使得它有点拗口。如果多个服务需要这个,你可以添加到你的docker-compose.yml的顶部
x-secrets2env: &secrets2env
source: secrets2env.sh
target: /run/secrets/secrets2env.sh
mode: 0777
然后,只要您有一个或多个"环境机密",就可以参考它:
services:
app:
entrypoint: ["/run/secrets/secrets2env.sh", "/entrypoint.sh"]
secrets:
- ADMIN_PASSWD.env
- DB_PASSWORD.env
- *secrets2env
因为您正在使用文件而不是值初始化eureka_password。