docker - Dockerfile: $HOME 已设置,但在使用它定义其他环境变量时变为空白
问题描述
我有一个简单的 Dockerfile,如下所示:
FROM alpine:3
RUN echo "$HOME" # Prints '/root'
ENV OTHER_HOME="$HOME"
RUN echo "$OTHER_HOME" # Prints nothing!
RUN echo "$PATH" # Prints '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
ENV OTHER_PATH="$PATH"
RUN echo "$OTHER_PATH" # Prints '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
我这样构建:
docker build . --no-cache
输出令人困惑。$OTHER_PATH
按预期打印,但$OTHER_HOME
为空白。谁能解释这种行为?
% docker build . --no-cache
Sending build context to Docker daemon 335.4kB
Step 1/7 : FROM alpine:3 AS build-stage
---> e7d92cdc71fe
Step 2/7 : RUN echo "$HOME"
---> Running in f9cd2769cd78
/root
Removing intermediate container f9cd2769cd78
---> d13f007a1fdf
Step 3/7 : ENV OTHER_HOME="$HOME"
---> Running in 7493ca43f9f3
Removing intermediate container 7493ca43f9f3
---> 2d6acfe45228
Step 4/7 : RUN echo "$OTHER_HOME"
---> Running in fb960138f43e
Removing intermediate container fb960138f43e
---> caa9719aeee5
Step 5/7 : RUN echo "$PATH"
---> Running in fe1eacf50d30
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Removing intermediate container fe1eacf50d30
---> 17267879b82e
Step 6/7 : ENV OTHER_PATH="$PATH"
---> Running in 9dd894199ea4
Removing intermediate container 9dd894199ea4
---> fa43f399604f
Step 7/7 : RUN echo "$OTHER_PATH"
---> Running in 89d67d8b6cfe
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Removing intermediate container 89d67d8b6cfe
---> 440133fc0052
Successfully built 440133fc0052
更新:更奇怪的是,如果我手动分配$HOME
,该值稍后可用!
FROM alpine:3
ENV HOME='/root'
RUN echo "$HOME"
ENV OTHER_HOME="$HOME"
RUN echo "$OTHER_HOME"
此 Dockerfile 导致:
% docker build . --no-cache
Sending build context to Docker daemon 335.4kB
Step 1/8 : FROM alpine:3 AS build-stage
---> e7d92cdc71fe
Step 2/8 : ENV HOME='/root'
---> Running in 4cb8a8e45b18
Removing intermediate container 4cb8a8e45b18
---> 40d0156fe68b
Step 3/8 : RUN echo "$HOME"
---> Running in 051cf7d138fb
/root
Removing intermediate container 051cf7d138fb
---> dc34c6859bcd
Step 4/8 : ENV OTHER_HOME="$HOME"
---> Running in 01dcc2788761
Removing intermediate container 01dcc2788761
---> 540ca4e9225a
Step 5/8 : RUN echo "$OTHER_HOME"
---> Running in 4e0d31d1f847
/root
解决方案
该$HOME
变量在容器由 RUN 步骤生成时设置。由于在之前的任何 ENV 或 ARG 步骤中未将其定义为 docker,因此您不能在新的 ENV 步骤中使用此变量。您可以通过检查基础映像来查看为 docker 定义的变量列表:
$ docker image inspect alpine:3 --format '{{json .Config.Env}}' | jq .
[
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
]
在这种情况下,唯一的变量是PATH
。如果您运行构建,您将看到其他变量被定义,当您使用字符串语法时,一些由 shell 定义,而当使用 exec 语法时,其他变量由 docker/OS 定义:
$ cat df.env
FROM alpine:3
RUN [ "env" ]
RUN env
$ DOCKER_BUILDKIT=0 docker build -t test-env -f df.env .
Sending build context to Docker daemon 25.09kB
Step 1/3 : FROM alpine:3
---> a187dde48cd2
Step 2/3 : RUN [ "env" ]
---> Running in 96b16e35b986
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=96b16e35b986
HOME=/root
Removing intermediate container 96b16e35b986
---> b11077eeb243
Step 3/3 : RUN env
---> Running in 90237b5b485f
HOSTNAME=90237b5b485f
SHLVL=1
HOME=/root
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/
Removing intermediate container 90237b5b485f
---> 2b3715def1df
Successfully built 2b3715def1df
Successfully tagged test-env:latest
在这种情况下,HOME
andHOSTNAME
在您运行 exec 时被定义,并且SHLVL
在PWD
您使用 shell ( /bin/sh
) 时被添加到其中。
推荐阅读
- ios - 在 RxSwift 中修改 behaviorRelay 数组内的属性
- powershell - 使用强身份验证方法检查启用 MFA 的管理员
- javascript - 如何修复不起作用的 Javascript 函数?
- batch-file - Cmd 脚本返回一个非零代码,ansible 得到一个零代码
- sql - 使用 Row_Number() 和/或 Cursor 更新一组记录,并在满足条件时中断 - SQL Server
- powerquery - 功率查询中的countif公式
- mysql - 减去两个子查询的结果
- python - 当我想要它时,循环不会停止重复吗?
- ruby-on-rails - 在 Rails 中创建子表时,您必须指定父键,还是关联会自动为您指定?
- mysql - 替换 SQL 数据库中的简码