在您的示例中,环境变量是从秘密中设置的,但仅适用于该进程。
如果您想要运行时环境变量从秘密中设置,您需要挂载包含秘密的卷,或通过docker-compose传递秘密,在任何情况下,然后利用入口点脚本根据秘密位置设置秘密。
注意:秘密文件需要对将运行dockerfile的任何人/服务都可用。
向您的Dockerfile添加入口点脚本
Dockerfile:
FROM alpine
RUN apk upgrade --update-cache --available && \
apk add bash \
&& rm -rf /var/cache/apk/*
COPY ./docker_entrypoint /usr/local/bin/docker_entrypoint
RUN chmod +x /usr/local/bin/docker_entrypoint
ENTRYPOINT [ "docker_entrypoint"]
CMD ["printenv"]
这个脚本将查找格式为ENVAR_FILE
的环境变量,以找到存储密钥的路径 - 将密钥导出到一个没有_FILE
的环境变量中,然后调用剩余的命令。
docker_entrypoint:
#!/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 "ENVAR1"
file_env "ENVAR2"
exec "$@"
现在您可以传递格式为ENVAR_FILE=/mnt/path/to/secret的环境变量 - 上述entrypoint脚本将读取该文件的内容并生成变量ENVAR=whateverYourSecretIs。
使用docker-compose的示例:
services:
someService:
image: <imageFromDockerFileAbove>
environment:
- ENVAR1_FILE=/run/secrets/envar1
- ENVAR2_FILE=/run/secrets/envar2
secrets:
- envar1
- envar2
secrets:
envar1:
file: /pth/to/secret
envar2:
file: /pth/to/secret
期望输出:
someService_1 | HOSTNAME=<containerID>
someService_1 | ENVAR1=mysecret1
someService_1 | ENVAR2=mysecret2
someService_1 | PWD=/
someService_1 | HOME=/root
someService_1 | SHLVL=0
someService_1 | PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
而
docker inspect --format='{{json .Config.Env}}' <containerID>
会返回:
["ENVAR1_FILE=/run/secrets/envar1","ENVAR2_FILE=/run/secrets/envar2","PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"]
docker inspect
中可见。 - anemyte