启动容器时加载 shell 配置文件

3

问题

我想在使用docker run -it container_name进入Docker容器时加载自定义的.zshrc文件,假设.zshrc文件已经在容器中。

描述

我有一个具有以下结构的Dockerfile:

FROM archlinux:latest

# Install things...
# Install zsh & oh-my-zsh
# Retrieve custom .zshrc from a repository and place it at ~/.zshrc
# Clone extensions for oh-my-zsh

# Run zsh on container start
CMD [ "zsh" ]

这一切都有效。如果我进入容器,我可以看到我的自定义.zshrc文件在应该在的位置,并且如果我运行source ~/.zshrc,它会被加载并且所有扩展都起作用。

尝试

我尝试在CMD步骤中直接源化配置文件,但是它找不到指定的文件。更新后的行如下所示:CMD [ "zsh && source ~/.zshrc" ]

我知道这可能不是使用Docker容器的预期方式,但这更像是一个学习经验,我想看看是否能够完成。


你可以映射你的目录。https://docs.docker.com/storage/volumes/ - undefined
我真的不太明白那是如何工作的。这难道不意味着我必须在我的主机上有本地文件吗?我想知道是否可以使用已经克隆到 Docker 容器中的文件。 - undefined
@alexHexan :我对Docker的知识不够,但是你能在Docker配置中设置一个环境变量吗?然后在zsh启动之前,这个环境变量就会被建立起来。如果你设置了变量ZDOTDIR,它必须指定一个目录,而.zshrc文件将从该目录而不是$HOME加载。 - undefined
3个回答

2
问题并不完全出在 Dockerfile 上。是的,正如 @Exadra37 提到的那样,CMD [ "zsh && source ~/.zshrc" ] 无法工作是因为执行顺序的问题。然而,问题出在我的 .zshrc 配置上。
在我自己的机器上再次测试后,我意识到它也没有自动加载。
结论
在我的 Dockerfile 中,将 CMD [ "/bin/zsh" ] 作为最后一行可以自动加载位于 /root/.zshrc.zshrc 文件,我只需要确保我的配置文件编写正确即可。

2

DOCKERFILE

为了将ZSH shell添加为容器中用户的默认shell,您需要添加命令chsh -s /path/to/shell

FROM archlinux:latest

# Install things...
# Install zsh & oh-my-zsh
# Retrieve custom .zshrc from a repository and place it at ~/.zshrc
# Clone extensions for oh-my-zsh

# Make ZSH the default shell for the current user in the container
# To check that the shell was indeed added: `chsh -l` and you should see it in the  list.
RUN chsh -s ~/.zshrc

# Run zsh on container start
CMD [ "zsh" ]

其他方法

Dockerfile CMD

这种方法不可行,因为执行顺序的原因:

CMD [ "zsh && source ~/.zshrc" ]

但这应该可以运行(未测试):

# using `root` user, adjust as needed for your case
CMD [ "source /root/.zshrc", "zsh"]

Docker入口点

如果您不想将其添加到Dockerfile中,则可以将其用作入口点:

docker run --rm -it --entrypoint "chsh -s /root/.zshrc" image-name

请注意,此示例假定容器中的用户为root,请根据您的情况进行相应调整。

1
我认为你应该更新$HOME/.profile的内容。以下是一个例子。
.profile文件:
source .zshrc

.zshrc文件:

echo "I'm getting executed!!!!"
echo "I'm getting executed!!!!"
echo "I'm getting executed!!!!"
echo "I'm getting executed!!!!"
echo "I'm getting executed!!!!"
echo "I'm getting executed!!!!"
echo "I'm getting executed!!!!"
echo "I'm getting executed!!!!"
echo "I'm getting executed!!!!"
echo "I'm getting executed!!!!"
echo "I'm getting executed!!!!"
echo "I'm getting executed!!!!"
echo "I'm getting executed!!!!"
echo "I'm getting executed!!!!"
echo "I'm getting executed!!!!"
echo "I'm getting executed!!!!"
echo "I'm getting executed!!!!"
echo "I'm getting executed!!!!"
echo "I'm getting executed!!!!"
echo "I'm getting executed!!!!"
echo "I'm getting executed!!!!"
echo "I'm getting executed!!!!"
echo "I'm getting executed!!!!"
echo "I'm getting executed!!!!"
echo "I'm getting executed!!!!"
echo "I'm getting executed!!!!"
echo "I'm getting executed!!!!"

Dockerfile的内容如下:
FROM ubuntu:18.04

RUN apt update \
    && apt install -yyq zsh curl git

RUN sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"

COPY .profile /root/.profile
COPY .zshrc /root/.zshrc

CMD ["zsh"]

然后你可以尝试使用它,带有HTML标记


docker build -t zsh:latest .
docker run --rm -it zsh:latest

编辑:

如果您不想复制新的.profile文件,您可以在现有文件中添加内容。例如:

FROM ubuntu:18.04

RUN apt update \
    && apt install -yyq zsh curl git

RUN sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"

RUN curl -fsSL https://www/.zshrc -o /root/.yet_another_zshrc_file \
    && echo 'source /root/.yet_another_zshrc_file' | tee -a /root/.profile

CMD ["zsh"]

这是有效的。顺便说一下,我想知道是否可以使用已经在容器内部的文件来完成它。是否可能使用curl命令获取.profile和.zshrc文件,而不是将它们复制到容器中? - undefined
当然可以。我已经更新了答案,提供了一个示例。 - undefined
然而,@Exadra37的方法更简洁。 - undefined

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