在我的 dockerfile 中使用 ENV 指令似乎没有将其附加到 PATH 中。我在下面设置了一个最小的示例。使用
Docker 26.0.0, build 2a3903e
我有以下内容
dockerfile
FROM alpine
ENV PATH=/opt:$PATH
当我构建图像时:
docker build --no-cache -t alpine-path .
然后运行:
docker run --rm -i -t alpine-path /bin/sh --login
外壳内部:
# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
/opt 路径尚未添加到 PATH 环境变量中。
显然我在某个地方做错了,但我无法弄清楚这一点,甚至无法将其分解为这个非常简单的示例。
根据您分享的内容,问题是由于登录 shell (
/bin/sh --login
)(在 Alpine Linux 中使用 ash
)处理其环境设置的方式造成的。
Alpine Linux shell (
ash
) 的行为有所不同,具体取决于它是作为登录 shell 还是非登录 shell 启动。
如果作为登录 shell 启动,它会读取初始化脚本,如
/etc/profile
。但是,除非在这些脚本中明确说明,否则它不会自动从 Dockerfile 导入 ENV
设置。
如果作为非登录 shell 启动,它会直接从其父进程(在本例中为 Docker)继承环境,其中包括 Dockerfile 中的
ENV
设置。
要在 Dockerfile 中设置时查看
PATH
,您可以在不使用 --login
选项的情况下运行容器。这将启动一个直接继承 Docker 的 ENV
设置的非登录 shell:
docker run --rm -i -t alpine-path /bin/sh
在外壳内部,检查
PATH
:
echo $PATH
这应该反映 Dockerfile 中的
PATH
设置。
如果您需要使用 shell 作为登录 shell,您可以更新 Dockerfile 以将所需的
PATH
附加到 /etc/profile
:
FROM alpine
ENV PATH="/opt:$PATH"
RUN echo "export PATH=$PATH" >> /etc/profile
这基本上确保了当 shell 作为登录 shell 启动时,它会从
PATH
读取更新的 /etc/profile
。
更新 Dockerfile 后,重新构建映像并运行容器。
在容器内,再次检查
PATH
,现在应该在 /opt
变量中包含 PATH
。