我是Docker的新手。我发现我们可以使用Dockerfile中的ENV指令设置环境变量。但是,如何在Dockerfile中为长命令设置bash别名?
Answers:
基本上就像您经常做的那样,将其添加到用户的.bashrc
:
FROM foo
RUN echo 'alias hi="echo hello"' >> ~/.bashrc
和往常一样,这仅适用于交互式外壳:
docker build -t test .
docker run -it --rm --entrypoint /bin/bash test hi
/bin/bash: hi: No such file or directory
docker run -it --rm test bash
$ hi
hello
对于非交互式外壳,您应该创建一个小脚本并将其放在路径中,即:
RUN echo -e '#!/bin/bash\necho hello' > /usr/bin/hi && \
chmod +x /usr/bin/hi
如果您的别名使用参数(即hi Jim
-> hello Jim
),则只需添加"$@"
:
RUN echo -e '#!/bin/bash\necho hello "$@"' > /usr/bin/hi && \
chmod +x /usr/bin/hi
如果只想在Dockerfile中使用别名,而不是在容器中使用别名,那么最简单的方法就是ENV
声明:
ENV update='apt-get update -qq'
ENV install='apt-get install -qq'
RUN $update && $install apt-utils \
curl \
gnupg \
python3.6
并以已描述的方式用于容器中:
RUN printf '#!/bin/bash \n $(which apt-get) install -qq $@' > /usr/bin/install
RUN chmod +x /usr/bin/install
大多数时候,我只是在构建阶段使用别名,而不是将其放入容器中,因此第一个示例对于每天的使用来说更加快捷,清晰和简单。
我刚刚将此添加到我的app.dockerfile
# setup aliases
ADD ./bashrc_alias.sh /usr/sbin/bashrc_alias.sh
ADD ./initbash_profile.sh /usr/sbin/initbash_profile
RUN chmod +x /usr/sbin/initbash_profile
RUN /bin/bash -C "/usr/sbin/initbash_profile"
并在initbash_profile.sh
其中添加我的自定义别名,而无需获取.bashrc文件的来源。
# add the bash aliases
cat /usr/sbin/bashrc_alias.sh >> ~/.bashrc
工作了请客!
另一个选择是仅从容器外部使用“ docker exec -it命令”,然后仅使用自己的.bashrc或.bash_profile(无论您喜欢什么)
例如。 docker exec -it docker_app_1 bash
您可以在Dockerfile中使用入口点,但不适用于别名:
ADD dev/entrypoint.sh /opt/entrypoint.sh
ENTRYPOINT ["/opt/entrypoint.sh"]
您的 entrypoint.sh
#!/bin/bash
set -e
function dev_run()
{
}
export -f dev_run
exec "$@"
(快速复制/粘贴,对不起)
我认为最简单的方法是将文件装载到包含别名的容器中,然后指定bash应该在哪里找到它:
docker run \
-it \
--rm \
-v ~/.bash_aliases:/tmp/.bash_aliases \
[image] \
/bin/bash --init-file /tmp/.bash_aliases
用法示例:
user@cobalt:~$ echo 'alias what="echo it works"' > my_aliases
user@cobalt:~$ docker run -it --rm -v ~/my_aliases:/tmp/my_aliases ubuntu:18.04 /bin/bash --init-file /tmp/my_aliases
root@565e4a1bdcc0:/# alias
alias what='echo it works'
root@565e4a1bdcc0:/# what
it works
使用了上述某些解决方案,但仍无法识别别名。
我试图设置别名,并在以后的Dockerfile步骤中以及运行时在容器中使用它们。
RUN echo "alias model-downloader='python3 ${MODEL_DL_PATH}/downloader.py'" >> ~/.bash_aliases && \
echo "alias model-converter='python3 ${MODEL_DL_PATH}/converter.py'" >> ~/.bash_aliases && \
source ~/.bash_aliases
# Download the model
RUN model-downloader --name $MODEL_NAME -o $MODEL_DIR --precisions $MODEL_PRECISION;
对我来说,解决方案是使用保存文件夹路径的ENV变量,然后添加确切的可执行文件。我也可以使用ARG,但是对于我的更多场景,在构建阶段以及稍后的运行时都需要使用别名。
将ENV变量与bash脚本结合使用,该bash脚本在依赖项被触发并设置bash源,设置更多env变量并允许其他命令通过时运行。
RUN
指令都在新的外壳中执行,因此在您的示例中,当您尝试使用别名时不再加载别名文件。
这是一个Bash函数,用于在您交互使用的每个容器中使用别名。
ducker_it() {
docker cp ~/bin/alias.sh "$1":/tmp
docker exec -it "$1" /bin/bash -c "[[ ! -f /tmp/alias.sh.done ]] \
&& [[ -w /root/.bashrc ]] \
&& cat /tmp/alias.sh >> /root/.bashrc \
&& touch /tmp/alias.sh.done"
docker exec -it "$1" /bin/bash
}
之前需要执行的步骤:
grep ^alias ~/.zshrc > ~/bin/alias.sh