如何在Dockerfile中使用bash profile

5

我正在尝试使用dockerfile构建镜像。 Dockerfile中的命令如下:

FROM ubuntu:16.04
:
:
RUN pip3 install virtualenvwrapper  
RUN echo '# Python virtual environment wrapper' >> ~/.bashrc
RUN echo 'export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3' >> ~/.bashrc
RUN echo 'export WORKON_HOME=$HOME/.virtualenvs' >> ~/.bashrc
RUN echo 'source /usr/local/bin/virtualenvwrapper.sh' >> ~/.bashrc

在这些命令之后,我将使用virtualenvwrapper命令创建一些虚拟环境。
如果我只需要在~/.bashrc中处理环境变量,我会使用ARG或ENV来设置它们。
但现在我还有其他的shell脚本文件,比如virtualenvwrapper.sh,它们将设置它们自己的变量。
此外,RUN source ~/.bashrc不起作用(找不到source)。
我该怎么办?
3个回答

3
在 Dockerfile 中,您不应尝试编辑像 .bash_profile 这样的 shell dotfiles。有许多常见路径不通过 shell(例如,CMD ["python", "myapp.py"] 不会启动任何类型的 shell 并且不会读取 .bash_profile)。如果您需要在映像中全局设置环境变量,请使用 Dockerfile ENV 指令。
对于 Python 应用程序,您只需使用 pip install 将应用程序安装到映像的“全局” Python 中即可。您不需要专门的虚拟环境;Docker 提供了许多相同的隔离功能(在 Dockerfile 中使用 pip install 不会影响主机系统的全局安装包)。
典型的 Python 应用程序 Dockerfile(从 https://hub.docker.com/_/python/ 复制)可能如下所示:
FROM python:3
WORKDIR /usr/src/app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "./your-daemon-or-script.py"]

关于你的最后一个问题,source 是一种供应商扩展,只有一些 shell 提供;POSIX 标准 不要求它,而在 Debian 和 Ubuntu 中默认的 /bin/sh 也不提供它。无论如何,由于环境变量在每个 RUN 命令上都会被重置,如果在该 RUN 行中没有其他操作发生,则 RUN source ...(或更可移植地 RUN . ...)是一个无操作。


您是说环境变量在每个 RUN.. 后都会重置。这是否使用 ~/.bashrc 文件来设置它们的变量?那么,我可能不需要使用 source 了,对吗? - scipsycho
即使 /bin/sh 恰好是 bash,运行 sh -c ...(这通常是 RUN 命令所做的)也不会读取任何点文件。 - David Maze
所以,在/bin/sh中设置环境变量除了使用ENV之外别无他法。但是,ENV一次只能设置一个变量,我能否将脚本文件附加到它上面以设置环境变量呢? - scipsycho

0
  1. 避免使用 ~ => 将您的 bashrc 放在特定路径中
  2. 将 source bashrc 和您的命令放在同一行 RUN 中,用 ; 分隔

RUN 行与环境完全独立


我使用了 RUN echo 'source /usr/local/bin/virtualenvwrapper.sh' >> bashForIndy. RUN source bashForIndy; mkvirtualenv dharmesh。它显示 /bin/sh: 1: source: not found /bin/sh: 1: mkvirtualenv: not found - scipsycho
需要使用“.”而不是“source”,以便与“/bin/sh”兼容。也就是说:. ~/.bashrc(假设该文件已经编写为与基线POSIX shell兼容)。 - Charles Duffy
1
另外,您可以使用RUN ["/bin/bash", "-c", "source ~/.bashrc; mkvirtualenv dharmesh"]来明确指定bash。 - Charles Duffy

0

可能更容易通过命令行完成,而且完全避免与dockerfile混淆。只需使用-l或--login选项,强制打开在Docker映像中的shell为登录变体,该变体将源代码/etc/profile和找到的第一个文件~/.bash_profile、~/.bash_login或~/.profile。

docker run -it --rm docker_image /bin/bash -l


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接