Como definir aliases de bash para contêineres do docker no Dockerfile?

87

Eu sou novo no docker. Descobri que podemos definir variáveis ​​de ambiente usando a instrução ENV no Dockerfile. Mas como definir aliases de bash para comandos longos no Dockerfile?

np20
fonte
aliases foram considerados essencialmente obsoletos por muito tempo. Use uma função. Já não há qualquer necessidade de sempre usar um pseudônimo. Como é que essas abordagens do final dos anos 80 persistem por tanto tempo?
William Pursell
19
Porque são convenientes e simples, é claro.
Arthur
13
@WilliamPursell Talvez você deva explicar então como usar as funções.
Eric Dela Cruz
2
Os apelidos são simples, convenientes, frágeis e sujeitos a erros. As funções são igualmente fáceis de usar, mas fornecem mais flexibilidade e robustez. Existem muitos recursos disponíveis sobre como usá-los.
William Pursell

Respostas:

144

Basicamente, como você sempre faz, adicionando-o ao .bashrc:

FROM foo
RUN echo 'alias hi="echo hello"' >> ~/.bashrc

Como de costume, isso só funcionará para shells interativos:

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

Para shells não interativos, você deve criar um pequeno script e colocá-lo em seu caminho, ou seja:

RUN echo -e '#!/bin/bash\necho hello' > /usr/bin/hi && \
    chmod +x /usr/bin/hi

Se o seu alias usar parâmetros (ou seja, hi Jim-> hello Jim), basta adicionar "$@":

RUN echo -e '#!/bin/bash\necho hello "$@"' > /usr/bin/hi && \
    chmod +x /usr/bin/hi
Erik Dannenberg
fonte
Obrigado por isso, você pode fornecer um exemplo de shell não interativo? Eu estava procurando ENTRYPOINT e CMD para resolver isso
c24b
5
O alias do Bash só funciona em shells interativos. Basta criar um pequeno script de shell e colocar em seu caminho, o mesmo efeito de um alias. Atualizou a resposta com um exemplo simples.
Erik Dannenberg
1
Observação: em stackoverflow.com/a/8467449, você deve usar printf em vez de echo para garantir um comportamento mais consistente. Então printf '#! / Bin / bash \ necho hello'> / usr / bin / hi chmod + x / usr / bin / hi
barraq
2
Amei a ideia do shell script. Estava tentando adicionar aliases, mas isso é muito melhor. Obrigado.
Blizz de
3
Você deve usar "$ @" em vez de $ * para escape de vários argumentos. Consulte unix.stackexchange.com/questions/248464/…
gnou
14

Para criar um alias de um comando existente, também pode usar ln -s:

ln -s $(which <existing_command>) /usr/bin/<my_command>

Laurent Magnin
fonte
7
Eu não chamaria isso de apelido .. é um link simbólico / link simbólico. A conveniência dos aliases é que você pode passar parâmetros para o comando, o alias ll='ls -lh'que não é possível com links simbólicos.
qwertz
3

Se você quiser usar aliases apenas no Dockerfile, mas não dentro do contêiner, o caminho mais curto é a ENVdeclaração:

ENV update='apt-get update -qq'
ENV install='apt-get install -qq'

RUN $update && $install apt-utils \
    curl \
    gnupg \
    python3.6

E para uso em container da forma já descrita:

 RUN printf '#!/bin/bash \n $(which apt-get) install -qq $@' > /usr/bin/install
 RUN chmod +x /usr/bin/install

Na maioria das vezes eu uso aliases apenas no estágio de construção e não entro em contêineres, então o primeiro exemplo é mais rápido, claro e simples para o uso diário.

Sonique
fonte
2

Acabei de adicionar isso ao meu 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"

e dentro do initbash_profile.shque apenas anexa meus aliases personalizados e não há necessidade de fornecer o arquivo .bashrc.

# add the bash aliases
cat /usr/sbin/bashrc_alias.sh >> ~/.bashrc

funcionou um deleite!

Outra opção é apenas usar o "comando docker exec -it" de fora do contêiner e apenas usar seu próprio .bashrc ou .bash_profile (o que você preferir)

por exemplo. docker exec -it docker_app_1 bash

mikoop
fonte
1

Você pode usar o entrypoint, mas não funcionará para o alias no seu Dockerfile:

ADD dev/entrypoint.sh /opt/entrypoint.sh
ENTRYPOINT ["/opt/entrypoint.sh"]

Seu entrypoint.sh

#!/bin/bash
set -e

function dev_run()
{

}

export -f dev_run

exec "$@"

(Copiar / colar rápido, desculpe)

Thomas Decaux
fonte
Preste atenção que algumas imagens do Docker já podem substituir o ponto de entrada padrão (como a imagem base phusion).
Thomas Decaux
1

Acho que a maneira mais fácil seria montar um arquivo em seu contêiner contendo seus aliases e, em seguida, especificar onde o bash deve encontrá-lo:

docker run \
    -it \
    --rm \
    -v ~/.bash_aliases:/tmp/.bash_aliases \
    [image] \
    /bin/bash --init-file /tmp/.bash_aliases

Uso de amostra:

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
Gillespie
fonte
0

Usei algumas das soluções acima, mas os aliases ainda não são reconhecidos.

Estou tentando definir aliases e usá-los nas etapas posteriores do Dockerfile e no contêiner em tempo de execução.

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;

A solução para mim foi usar variáveis ​​ENV que continham caminhos de pasta e, em seguida, adicionar o executável exato. Eu poderia ter usado ARG também, mas para mais dos meus cenários, eu precisava dos aliases tanto no estágio de construção quanto mais tarde no tempo de execução.

Usou as variáveis ​​ENV em conjunto com um script bash que é executado uma vez que as dependências foram acionadas e definiu a origem do bash, definiu mais algumas variáveis ​​env e permite que mais comandos sejam transmitidos.

alanionita
fonte
Cada RUNinstrução é executada em um novo shell, portanto, em seu exemplo, o arquivo de alias não é mais carregado quando você tenta usar o alias.
Erik Dannenberg
100% @ErikDannenberg obrigado pelo comentário e também por me lembrar que preciso postar uma atualização para isso - descobri uma solução e é muito parecido com o que você sugeriu.
alanionita
0

Esta é uma função Bash para ter seus aliases em cada contêiner que você usa interativamente.

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
}

Etapa necessária antes:

grep ^alias ~/.zshrc > ~/bin/alias.sh
DjAlan
fonte
-1
  1. edite este arquivo ~ / .bash_aliases vi ~/.bash_aliases
  2. fonte deste arquivo ~ / .bash_aliases source ~/.bash_aliases
  3. feito.
Eddy Ferreira
fonte
Isso é bom sempre que você acionar seu contêiner do docker, mas os aliases não permanecerão na próxima vez. se você não se importar em adicioná-los novamente a cada vez, esta solução é adequada.
mikoop
Esta não é uma resposta, mas zombando da pessoa que está fazendo a pergunta.
bhuvin