使用新的docker build增强功能时是否有一种设置环境变量的方法?
尝试了
RUN --mount=type=secret,id=secret export SECRET=/run/secrets/secret
RUN --mount=type=secret,id=secret ENV SECRET=/run/secrets/secret
两者都不起作用。还是在dockerfile不好的环境变量上设置秘密?由于将docker history
运行到ENV VAR以纯文本设置。如果是这样,将尽可能固定的设置设置env var设置的最佳方法是什么?
要从秘密设置一个变量,您可以在Shell中使用$(cat /filename)
语法。这会影响该单个步骤内的外壳,因此您对该变量的所有用途都需要在同一步骤内。您不能从运行步骤中提取变量到ENV步骤。如果您需要它持续到其他运行步骤,则需要将变量写入文件系统并包含在图像中,这是不希望的(而是在以后的运行步骤中第二次安装秘密(。
这是一个工作示例,您也可以用export secret_var
导出该秘密:
$ cat df.secret
FROM busybox
RUN --mount=type=secret,id=secret
secret_var="$(cat /run/secrets/secret)"
&& echo ${secret_var}
$ cat secret.txt
my_secret
$ docker build --progress=plain --secret id=secret,src=$(pwd)/secret.txt -f df.secret .
#1 [internal] load build definition from df.secret
#1 sha256:85a18e77d3e60159b744d6ee3d96908a6fed0bd4f6a46d038e2aa0201a1028de
#1 DONE 0.0s
#1 [internal] load build definition from df.secret
#1 sha256:85a18e77d3e60159b744d6ee3d96908a6fed0bd4f6a46d038e2aa0201a1028de
#1 transferring dockerfile: 152B done
#1 DONE 0.0s
#2 [internal] load .dockerignore
#2 sha256:a5a676bca3eaa2c757a3ae40d8d5d5e91b980822056c5b3b6c5b3169fc65f0f1
#2 transferring context: 49B done
#2 DONE 0.0s
#3 [internal] load metadata for docker.io/library/busybox:latest
#3 sha256:da853382a7535e068feae4d80bdd0ad2567df3d5cd484fd68f919294d091b053
#3 DONE 0.0s
#5 [1/2] FROM docker.io/library/busybox
#5 sha256:08a03f3ffe5fba421a6403c31e153425ced631d108868f30e04985f99d69326e
#5 DONE 0.0s
#4 [2/2] RUN --mount=type=secret,id=secret secret=$(cat /run/secrets/secret) && echo ${secret}
#4 sha256:6ef91a8a7daf012253f58dba292a0bd86af1d1a33a90838b6a99aba5abd4cfaf
#4 0.587 my_secret
#4 DONE 0.7s
#6 exporting to image
#6 sha256:e8c613e07b0b7ff33893b694f7759a10d42e180f2b4dc349fb57dc6b71dcab00
#6 exporting layers 0.0s done
#6 writing image sha256:a52db3458ad88481406cd60627e2ed6f55b6720c1614f65fa8f453247a9aa4de done
#6 DONE 0.0s
请注意,显示秘密的线#4 0.587 my_secret
是输出的。
在您的示例中,环境变量是从秘密设置的,但仅用于该过程。
如果要从秘密设置运行的时间环境变量,则需要安装包含秘密的卷,或者通过docker-compose传递秘密,然后在任何一种情况下都使用入门点脚本来设置基于秘密位置的秘密。
注意:任何将运行Dockerfile的任何人/服务都需要提供秘密文件。
将入门点脚本添加到您的Dockerfile
dockerfile:
FROM alpine
# Bash is needed for the script to set env_vars based on secrets
RUN apk upgrade --update-cache --available &&
apk add bash
&& rm -rf /var/cache/apk/*
# Adding entrypoint script to image
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"
}
# Explicitly list the environment variables you want to
# set from secrets
file_env "ENVAR1"
file_env "ENVAR2"
exec "$@"
现在,您可以通过格式的环境变量envar_file =/mnt/path/to/secret-,上面的入口点脚本将读取该文件的内容并生成变量evar = 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"]