如何在启动alpine docker容器时加载shell别名

4

我编写了一个DOCKER文件,使用的是一个私有适应的alpine镜像,其中包含一个nginx服务器。 注意:alpine使用zsh而不是bash。

当在容器中工作时,我希望有一些shell别名可用,如果它们缺失会让我抓狂。因此,我将一个小的预先准备好的文件复制到/root/.profile,这是有效的。我可以查看文件及其内容。但是只有在我手动执行“~/.profile”命令后,该文件才会被加载,然后我的别名才可以使用。

我应该怎么做才能在启动容器并连接到其shell后自动加载我的配置文件?

FROM myprivatealpineimage/base-image-php:7.4.13

ARG TIMEZONE

COPY ./docker/shared/bashrc /root/.profile

COPY ./docker/shared/ /tmp/scripts/
RUN chmod +x -R /tmp/scripts/ \
    && /tmp/scripts/set_timezone.sh ${TIMEZONE}\
    && apk update\
    && apk add --no-cache git

RUN install-ext pecl/apcu pecl/imagick pecl/zip pecl/redis
RUN apk add --no-cache --repository http://dl-3.alpinelinux.org/alpine/edge/testing gnu-libiconv
ENV LD_PRELOAD /usr/lib/preloadable_libiconv.so php

WORKDIR /var/www

1
发现这里使用的不是zsh,而是sh。 - Calamity Jane
你最终解决了这个问题吗? - Saeed Neamati
请查看我的回答,确认是否对您有效? - Calamity Jane
我最终在 Dockerfile 中添加了 PATH 并通过名称调用该路径中的脚本。 - Saeed Neamati
你能否请发布你的解决方案? - Calamity Jane
发布成功,谢谢。 - Saeed Neamati
5个回答

3

对我而言,这个方法行得通:

  1. 为每个别名创建一个shell脚本。例如,backup.shcompile.shdblogin.sh

  2. 将所有这些脚本放在一个目录中。例如 scripts

  3. Dockerfile中将该目录添加到PATH环境变量中。例如:

    ENV PATH="${PATH}:/temp/scripts"

  4. 在你的docker-compose.yml文件中挂载这个目录。例如:

        volumes: 
            - /path/to/scripts/on/local/machine:/temp/scripts
  1. 确保你添加到PATH的路径与你在docker-compose.yml中挂载的路径匹配。例如,两者都应该是/temp/scripts

  2. 现在在你的Docker交互式Shell中,你可以通过它们的名称简单地调用你的脚本文件,例如compiledblogin


3
默认情况下,Docker启动的是非登录shell。要读取.profile文件,您需要启动一个登录shell:docker exec -it <container> ash -l
要每次读取/etc/profile(或其他启动文件),您需要设置ENV变量。
以下是示例Dockerfile:
ARG PHPVERSION=7.4
FROM php:$PHPVERSION-fpm-alpine

ARG PHPVERSION=7.4
ENV PHPVERSION_ENV=$PHPVERSION

# copy composer from official image
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

#set $ENV
ENV ENV=/etc/profile
#copy aliases definition
COPY /assets/alias.sh /etc/profile.d/alias.sh



什么是-l标志? - AH.Pooladvand
@AH.Pooladvand,-l标志激活登录shell模式。 - Sergei Kuraksin

2
您可以在 Docker 构建过程中添加别名,方法如下:
# Making our command line life a little easier...
RUN echo 'alias ll="ls -l"' >> ~/.bashrc
RUN echo 'alias la="ls -la"' >> ~/.bashrc

这与在构建期间复制整个文件有何不同? - Calamity Jane
在我看来,它更像是“所见即所得”。而且.bashrc文件会在所有shell中执行,而不仅仅是像.profile那样的登录shell。因此,区别就在于你最终会在你的主目录下拥有一个.bashrc文件,而不是一个.profile文件。使用~也与运行用户无关。当然,在复制文件时也可以这样做。 - Ralf

1
将您的文件命名为 .bashrc 并放置在用户目录下: COPY docker/shared/bashrc /home/{YOUR_USER}/.bashrc

这就是我正在做的事情。在Docker容器中,我是root用户。Alpine使用zsh而不是bash,因此我将复制内容到.profile文件而不是.bashrc文件。 - Calamity Jane
你确定要使用zsh吗?我有一个Alpine容器,.bashrc正常工作。bash-5.0$ cat /etc/alpine-release 3.12.3 - Tania Petsouka
@CalamityJane,如果您使用的是zsh,那么像.bashrc.profile这样的bash配置文件将不起作用。要么您需要切换到使用bash,要么更容易的方法是在.zshrc中定义别名。 - Ralf
3
顺便提一下,官方的纯净版 Alpine 镜像默认使用 ash 作为其默认 shell。 - Ralf
相当确定它不是bash,因为我已经和同事讨论过了。但是我不太确定它是ash还是zsh。我会去查一下的。 - Calamity Jane
显示剩余2条评论

-1

这似乎可以运行:

FROM myprivatealpineimage/base-image-php:8.0.3

ARG TIMEZONE
ARG WITH_XDEBUG=false

COPY ./docker/shared/bashrc /root/.profile
COPY ./docker/shared/bashrc /root/.ashrc

COPY ./docker/shared/ /tmp/scripts/
RUN chmod +x -R /tmp/scripts/ \
    && /tmp/scripts/set_timezone.sh ${TIMEZONE} \
    && apk add --no-cache git  

WORKDIR /var/www

我刚刚重新构建了我的容器,当我登录时,我的别名还在。如果有人可以确认这个设置是有效的,我会将其标记为正确答案。不过我不知道为什么它有效而另一个则无效。


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