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?
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:
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.
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:
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.
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:/# aliasalias what='echo it works'
root@565e4a1bdcc0:/# what
it works
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.
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.
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.
Respostas:
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
fonte
Para criar um alias de um comando existente, também pode usar
ln -s
:ln -s $(which <existing_command>) /usr/bin/<my_command>
fonte
alias ll='ls -lh'
que não é possível com links simbólicos.Se você quiser usar aliases apenas no Dockerfile, mas não dentro do contêiner, o caminho mais curto é a
ENV
declaraçã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.
fonte
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.sh
que 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
fonte
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)
fonte
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:
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
fonte
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.
fonte
RUN
instrução é executada em um novo shell, portanto, em seu exemplo, o arquivo de alias não é mais carregado quando você tenta usar o alias.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
fonte
vi ~/.bash_aliases
source ~/.bash_aliases
fonte