Dockerfile CMD exec form如何定位binary
How does Dockerfile CMD exec form locate the binary
如果我有这样的 Dockerfile:
FROM ubuntu
CMD [ "ps", "-ef" ]
如果我构建并运行图像,我得到
$ docker run -it 156a9f959f43
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 07:12 pts/0 00:00:00 ps -ef
与文档一致。
问题:当容器 运行 时,二进制文件 ps
如何定位到第一位?
exec 语法使用在父映像 (ubuntu:latest
) 中定义的 PATH
环境变量。
$ docker image inspect ubuntu:latest
[
{
...
"Config": {
...
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/bash"
],
....
如果您查看 Dockerfile for this base image...,您实际上会发现 PATH 变量未在此处定义。我们可以查看 scratch
但那是一个虚拟图像。
因此,让我们在 scratch
上构建一个镜像,不查看定义了哪些变量:
$ cat df.scratch
FROM scratch
$ docker build -t test-scratch -f df.scratch .
...
$ docker image inspect test-scratch:latest
[
{
...
"Config": {
...
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
...
因此在 scratch
映像中创建了 PATH。 This old issue and associated PR 表明 docker 包含开箱即用的 PATH。
如何调整该路径?您需要使用 ENV
行。如果您在 RUN
行中设置变量,则在 RUN
行完成后它不会被保留。如果您附加到容器中的 .bashrc
,则不适用于非 bash shell,如 /bin/sh
,任何使用不带 [=42 的 exec 语法的东西=],以及任何非交互式 bash shells(因为 .bashrc
在非交互式 shells 中途停止处理)。这是一个不同的 image/build:
的例子
$ cat df.path
FROM ubuntu
# before state from the base image
RUN [ "env" ]
# attempting to modify the .bashrc
RUN echo "export PATH="$PATH:/my/custom/bin/dir"" >> ~/.bashrc
RUN [ "env" ]
# modifying the image environment variable directly
ENV PATH=${PATH}:/opt/custom/bin
RUN [ "env" ]
$ docker build -t test-path -f df.path .
Sending build context to Docker daemon 31.23kB
Step 1/6 : FROM ubuntu
---> 4e5021d210f6
Step 2/6 : RUN [ "env" ]
---> Running in 5bb72abb386d
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=5bb72abb386d
HOME=/root
Removing intermediate container 5bb72abb386d
---> c438fb269c70
Step 3/6 : RUN echo "export PATH="$PATH:/my/custom/bin/dir"" >> ~/.bashrc
---> Running in 127b10aff046
Removing intermediate container 127b10aff046
---> 4af50595c271
Step 4/6 : RUN [ "env" ]
---> Running in c5ff46ba3b82
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=c5ff46ba3b82
HOME=/root
Removing intermediate container c5ff46ba3b82
---> 455325a5e484
Step 5/6 : ENV PATH=${PATH}:/opt/custom/bin
---> Running in e7960d9ce18a
Removing intermediate container e7960d9ce18a
---> ed532bff78b4
Step 6/6 : RUN [ "env" ]
---> Running in 9c1558a61ab7
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/custom/bin
HOSTNAME=9c1558a61ab7
HOME=/root
Removing intermediate container 9c1558a61ab7
---> f08993f21b97
Successfully built f08993f21b97
Successfully tagged test-path:latest
注意第2步路径的原始值,第4步没有改变,第6步有定义的值
在 docker 容器中(与大多数操作系统类似)有一个 $PATH
环境变量,它包含可执行文件所在的目录路径(由 :
分隔) ).
例如,$PATH
变量可能包含一个像 /usr/local/bin:/usr/bin:/home/ubuntu/bin
这样的值,这意味着当你 运行 执行一个像 ps
这样的命令时,它会寻找一个这些目录中的可执行文件。
您可以在此处了解有关 $PATH 变量的更多信息 https://en.wikipedia.org/wiki/PATH_(variable)
注意:$PATH
变量将因容器而异(因为它们是独立的单元)并且很可能保存 docker 图像使用的基本发行版的默认值.
要在基于 linux 的系统上更改 $PATH 变量,您可以 运行 export PATH="$PATH:/custom/bin/dir"
并且它会将 /custom/bin/dir
附加到变量。
要使此更改永久生效,您应该将此命令添加到您的 .bashrc、.profile、.zshrc 或类似文件(取决于您使用的 shell)
因此,要更新 docker 容器中的变量,您应该将类似的内容添加到 Docker 文件
FROM ubuntu
RUN echo "export PATH="$PATH:/my/custom/bin/dir"" >> ~/.bashrc
如果我有这样的 Dockerfile:
FROM ubuntu
CMD [ "ps", "-ef" ]
如果我构建并运行图像,我得到
$ docker run -it 156a9f959f43
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 07:12 pts/0 00:00:00 ps -ef
与文档一致。
问题:当容器 运行 时,二进制文件 ps
如何定位到第一位?
exec 语法使用在父映像 (ubuntu:latest
) 中定义的 PATH
环境变量。
$ docker image inspect ubuntu:latest
[
{
...
"Config": {
...
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/bash"
],
....
如果您查看 Dockerfile for this base image...,您实际上会发现 PATH 变量未在此处定义。我们可以查看 scratch
但那是一个虚拟图像。
因此,让我们在 scratch
上构建一个镜像,不查看定义了哪些变量:
$ cat df.scratch
FROM scratch
$ docker build -t test-scratch -f df.scratch .
...
$ docker image inspect test-scratch:latest
[
{
...
"Config": {
...
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
...
因此在 scratch
映像中创建了 PATH。 This old issue and associated PR 表明 docker 包含开箱即用的 PATH。
如何调整该路径?您需要使用 ENV
行。如果您在 RUN
行中设置变量,则在 RUN
行完成后它不会被保留。如果您附加到容器中的 .bashrc
,则不适用于非 bash shell,如 /bin/sh
,任何使用不带 [=42 的 exec 语法的东西=],以及任何非交互式 bash shells(因为 .bashrc
在非交互式 shells 中途停止处理)。这是一个不同的 image/build:
$ cat df.path
FROM ubuntu
# before state from the base image
RUN [ "env" ]
# attempting to modify the .bashrc
RUN echo "export PATH="$PATH:/my/custom/bin/dir"" >> ~/.bashrc
RUN [ "env" ]
# modifying the image environment variable directly
ENV PATH=${PATH}:/opt/custom/bin
RUN [ "env" ]
$ docker build -t test-path -f df.path .
Sending build context to Docker daemon 31.23kB
Step 1/6 : FROM ubuntu
---> 4e5021d210f6
Step 2/6 : RUN [ "env" ]
---> Running in 5bb72abb386d
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=5bb72abb386d
HOME=/root
Removing intermediate container 5bb72abb386d
---> c438fb269c70
Step 3/6 : RUN echo "export PATH="$PATH:/my/custom/bin/dir"" >> ~/.bashrc
---> Running in 127b10aff046
Removing intermediate container 127b10aff046
---> 4af50595c271
Step 4/6 : RUN [ "env" ]
---> Running in c5ff46ba3b82
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=c5ff46ba3b82
HOME=/root
Removing intermediate container c5ff46ba3b82
---> 455325a5e484
Step 5/6 : ENV PATH=${PATH}:/opt/custom/bin
---> Running in e7960d9ce18a
Removing intermediate container e7960d9ce18a
---> ed532bff78b4
Step 6/6 : RUN [ "env" ]
---> Running in 9c1558a61ab7
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/custom/bin
HOSTNAME=9c1558a61ab7
HOME=/root
Removing intermediate container 9c1558a61ab7
---> f08993f21b97
Successfully built f08993f21b97
Successfully tagged test-path:latest
注意第2步路径的原始值,第4步没有改变,第6步有定义的值
在 docker 容器中(与大多数操作系统类似)有一个 $PATH
环境变量,它包含可执行文件所在的目录路径(由 :
分隔) ).
例如,$PATH
变量可能包含一个像 /usr/local/bin:/usr/bin:/home/ubuntu/bin
这样的值,这意味着当你 运行 执行一个像 ps
这样的命令时,它会寻找一个这些目录中的可执行文件。
您可以在此处了解有关 $PATH 变量的更多信息 https://en.wikipedia.org/wiki/PATH_(variable)
注意:$PATH
变量将因容器而异(因为它们是独立的单元)并且很可能保存 docker 图像使用的基本发行版的默认值.
要在基于 linux 的系统上更改 $PATH 变量,您可以 运行 export PATH="$PATH:/custom/bin/dir"
并且它会将 /custom/bin/dir
附加到变量。
要使此更改永久生效,您应该将此命令添加到您的 .bashrc、.profile、.zshrc 或类似文件(取决于您使用的 shell)
因此,要更新 docker 容器中的变量,您应该将类似的内容添加到 Docker 文件
FROM ubuntu
RUN echo "export PATH="$PATH:/my/custom/bin/dir"" >> ~/.bashrc