Dockerfile中修改新用户PATH未在构建阶段生效的原因咨询
问题:Docker构建时修改PATH不生效,但运行容器后正常的原因
提供的Dockerfile
FROM ubuntu:focal RUN adduser carlos --disabled-password --gecos GECOS USER carlos RUN echo "export PATH=\"/var/www/:$PATH\"" >> /home/carlos/.bashrc RUN id RUN echo $PATH
构建日志
Sending build context to Docker daemon 14.85kB Step 1/6 : FROM ubuntu:focal ---> a0ce5a295b63 Step 2/6 : RUN adduser carlos --disabled-password --gecos GECOS ---> Running in b8f855a48225 Adding user `carlos' ... Adding new group `carlos' (1000) ... Adding new user `carlos' (1000) with group `carlos' ... Creating home directory `/home/carlos' ... Copying files from `/etc/skel' ... Removing intermediate container b8f855a48225 ---> 1ed7829e2b12 Step 3/6 : USER carlos ---> Running in 556f98167d89 Removing intermediate container 556f98167d89 ---> e41d82f717b0 Step 4/6 : RUN echo "export PATH=\"/var/www/:$PATH\"" >> /home/carlos/.bashrc ---> Running in a4a0f3f3b96b Removing intermediate container a4a0f3f3b96b ---> 512f42df7dfb Step 5/6 : RUN id ---> Running in b5f12c0926f0 uid=1000(carlos) gid=1000(carlos) groups=1000(carlos) Removing intermediate container b5f12c0926f0 ---> a97a4b0b476d Step 6/6 : RUN echo $PATH ---> Running in 5b4e844c87ec /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin Removing intermediate container 5b4e844c87ec ---> ef977ae5591d Successfully built ef977ae5591d Successfully tagged myimage:latest
补充现象
运行容器(docker run -it <容器ID>)后,进入carlos的bash环境执行echo $PATH,能看到已修改的正确PATH。请问这是什么原因?
原因及解决方案
核心原因
- Docker的
RUN命令用的是非交互式shell:每个RUN指令都会启动一个独立的、非登录的非交互式shell,这种shell默认不会加载用户的.bashrc配置文件。.bashrc只有在启动交互式登录shell(比如docker run -it启动的bash)时才会自动加载。 - PATH变量的展开时机:你在
RUN echo "export PATH=\"/var/www/:$PATH\"" >> /home/carlos/.bashrc这条命令里,双引号中的$PATH会在执行该RUN命令时直接展开成当时的系统默认PATH,而不是保留变量形式等到bash启动时再解析。如果要避免这个问题,应该用单引号包裹:RUN echo 'export PATH="/var/www/:$PATH"' >> /home/carlos/.bashrc。
解决办法
如果想在构建阶段就让修改后的PATH生效,或者让容器运行时更可靠地生效,可以选下面两种方式:
方式1:构建时显式加载.bashrc
在需要使用修改后PATH的RUN命令中,先加载.bashrc再执行命令:
RUN source /home/carlos/.bashrc && echo $PATH
方式2:用ENV指令全局设置PATH
Docker的ENV指令设置的环境变量会作用于所有后续的RUN命令,以及容器运行时的所有进程,比修改.bashrc更通用可靠:
FROM ubuntu:focal RUN adduser carlos --disabled-password --gecos GECOS USER carlos ENV PATH="/var/www/:$PATH" RUN id RUN echo $PATH
内容的提问来源于stack exchange,提问作者floupinette
相关产品推荐
相关产品推荐

