如何让 /etc/profile 在 Alpine / Docker 中自动运行

Posted

技术标签:

【中文标题】如何让 /etc/profile 在 Alpine / Docker 中自动运行【英文标题】:How to get /etc/profile to run automatically in Alpine / Docker 【发布时间】:2016-10-27 17:00:24 【问题描述】:

如何让/etc/profile 在交互式启动 Alpine Docker 容器时自动运行?我在aliases.sh 文件中添加了一些别名并将其放在/etc/profile.d 中,但是当我使用docker run -it [my_container] sh 启动容器时,我的别名不活动。我每次都必须从命令行手动输入. /etc/profile

是否需要一些其他配置才能让/etc/profile 在登录时运行?我在使用~/.profile 文件时也遇到了问题。任何见解都值得赞赏!

编辑:

根据 VonC 的回答,我提取并运行了他的示例 ruby 容器。这是我得到的:

$ docker run --rm --name ruby -it codeclimate/alpine-ruby:b42
/ # more /etc/profile.d/rubygems.sh
export PATH=$PATH:/usr/lib/ruby/gems/2.0.0/bin
/ # env
no_proxy=*.local, 169.254/16
HOSTNAME=6c7e93ebc5a1
SHLVL=1
HOME=/root
TERM=xterm
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/
/ # exit

虽然/etc/profile.d/rubygems.sh 文件存在,但在我登录时它并没有运行,我的PATH 环境变量也没有更新。我是否使用了错误的docker run 命令?还缺少什么吗?有没有人得到~/.profile/etc/profile.d/ 文件在Docker 上使用Alpine?谢谢!

【问题讨论】:

你试过用ADD .profile /etc/.profile构建Alpine Images吗? 不,我实际上从未听说过尝试使用/etc/.profile。我一直认为.profile 属于您的HOME 目录,而profile(无点)属于/etc 【参考方案1】:

Jinesh 之前提到过,Alpine Linux 中默认的 shell 是 ash

localhost:~$ echo $SHELL
/bin/ash
localhost:~$ 

因此,简单的解决方案就是在 .profile 中添加您的别名。在这种情况下,我将所有别名都放在 ~/.ash_aliases 中

localhost:~$ cat .profile 
# ~/.profile

# Alias
if [ -f ~/.ash_aliases ]; then
    . ~/.ash_aliases
fi

localhost:~$ 

.ash_aliases 文件

localhost:~$ cat .ash_aliases
alias a=alias
alias c=clear
alias f=file
alias g=grep
alias l='ls -lh'
localhost:~$

它有效:)

【讨论】:

是否有等效于 /etc/profile.d 扫描 *.sh 文件的方法?我必须以编程方式设置一些环境变量。目前我已经采用了 Jinesh 的解决方案,但我更喜欢尽可能采用最合适的方式。【参考方案2】:

Alpine Linux 中的默认 shell 是 ash

如果 Ash 作为登录 shell sh -l 启动,它只会读取 /etc/profile~/.profile 文件。

要强制 Ash 在作为非登录 shell 调用时获取 /etc/profile 或您想要的任何其他脚本,您需要在启动 Ash 之前设置一个名为 ENV 的环境变量。

例如在你的 Dockerfile 中

FROM alpine:3.5

ENV ENV="/root/.ashrc"

RUN echo "echo 'Hello, world!'" > "$ENV"

当您构建时,您会得到:

deployer@ubuntu-1604-amd64:~/blah$ docker build --tag test .
Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM alpine:3.5
3.5: Pulling from library/alpine
627beaf3eaaf: Pull complete
Digest: sha256:58e1a1bb75db1b5a24a462dd5e2915277ea06438c3f105138f97eb53149673c4
Status: Downloaded newer image for alpine:3.5
 ---> 4a415e366388
Step 2/3 : ENV ENV "/root/.ashrc"
 ---> Running in a9b6ff7303c2
 ---> 8d4af0b7839d
Removing intermediate container a9b6ff7303c2
Step 3/3 : RUN echo "echo 'Hello, world!'" > "$ENV"
 ---> Running in 57c2fd3353f3
 ---> 2cee6e034546
Removing intermediate container 57c2fd3353f3
Successfully built 2cee6e034546

最后,当你运行新生成的容器时,你会得到:

deployer@ubuntu-1604-amd64:~/blah$ docker run -ti test /bin/sh
Hello, world!
/ # exit

请注意,Ash shell 没有作为登录 shell 运行。

所以要回答您的问题,请替换

ENV ENV="/root/.ashrc"

与:

ENV ENV="/etc/profile"

Alpine Linux 的 Ash shell 会在每次启动 shell 时自动获取 /etc/profile 脚本。

问题: /etc/profile 通常意味着只能获取一次!所以,我建议你不要使用它,而是使用 /root/.somercfile。

来源:https://***.com/a/40538356

【讨论】:

这应该是公认的答案。谢谢【参考方案3】:

你仍然可以在你的 Dockerfile 中尝试:

RUN echo '\
        . /etc/profile ; \
    ' >> /root/.profile

(假设当前用户是root。如果不是,则将/root替换为完整的主路径)

话虽如此,那些 /etc/profile.d/xx.sh 应该运行。 以codeclimate/docker-alpine-ruby为例:

COPY files /

使用 'files/etc" 包括 files/etc/profile.d/rubygems.sh 运行良好。


在OP projectDockerfile中有一个

COPY aliases.sh /etc/profile.d/

但是默认的shell不是登录shell(sh -l),意思是profile files (or those in /etc/profile.d) are not sourced。

添加sh -l 会起作用:

docker@default:~$ docker run --rm --name ruby -it codeclimate/alpine-ruby:b42 sh -l
87a58e26b744:/# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/lib/ruby/gems/2.0.0/bin

【讨论】:

VonC:我也尝试过使用/root/.profile 文件,其别名定义与我放入/etc/profile.d/aliases.sh 文件中的别名定义相同。实际上,这是我尝试的第一件事。我想也许我错过了 Alpine 上的 ashsh 有所不同 - 某些原因我的 .profile 没有被阅读。我会看看你的例子。谢谢! 顺便说一下,这是一个基本的Node 容器,我在其中使用aliases.sh 文件。也许有人可以拉这个容器,看看他们登录时别名和颜色提示是否正常工作......https://hub.docker.com/r/jkilbride/node-npm-alpine/ @JeffKilbride 我已经编辑了我的答案。也许缺少 chmod? VonC:感谢您的快速更新!请参阅我对上面的原始帖子所做的编辑。我拉并运行codeclimate/docker-alpine-ruby 并遇到了同样的问题。我的PATH 变量没有被/etc/profile.d 中的rubygems.sh 文件更新。 @JeffKilbride 你能做一个ls -alrt /etc/profile.d 看看那个 sh 脚本是否可执行吗?

以上是关于如何让 /etc/profile 在 Alpine / Docker 中自动运行的主要内容,如果未能解决你的问题,请参考以下文章

docker alpine中遇到 sh: ./go: not found

如何使/etc/profile文件修改后立即生效

如何使/etc/profile文件修改后立即生效

如何让/etc/security/user做的修改马上生效

如何让文件魔术模块在 Alpine Linux 上运行?

如何让History命令的显示带时间