Jak ustawić aliasy bash dla kontenerów platformy Docker w pliku Dockerfile?

85

Jestem nowy w dockerze. Odkryłem, że możemy ustawić zmienne środowiskowe za pomocą instrukcji ENV w pliku Dockerfile. Ale jak ustawić aliasy bash dla długich poleceń w pliku Dockerfile?

np20
źródło
aliasy były uważane za przestarzałe od bardzo dawna. Użyj funkcji. Nie ma już potrzeby, aby zawsze używać aliasu. Jak to się dzieje, że te podejścia z końca lat 80. utrzymują się tak długo?
William Pursell,
19
Oczywiście, ponieważ są wygodne i proste.
Arthur
13
@WilliamPursell Może powinieneś wyjaśnić, jak zamiast tego używać funkcji.
Eric Dela Cruz
2
Aliasy są proste, wygodne, delikatne i podatne na błędy. Funkcje są równie łatwe w użyciu, ale zapewniają większą elastyczność i solidność. Dostępnych jest wiele zasobów, jak z nich korzystać.
William Pursell

Odpowiedzi:

141

Zasadniczo tak, jak zawsze, dodając go do użytkownika .bashrc:

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

Jak zwykle zadziała to tylko dla powłok interaktywnych:

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

W przypadku powłok nieinteraktywnych należy utworzyć mały skrypt i umieścić go w swojej ścieżce, tj .:

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

Jeśli twój alias używa parametrów (np. hi Jim-> hello Jim), po prostu dodaj "$@":

RUN echo -e '#!/bin/bash\necho hello "$@"' > /usr/bin/hi && \
    chmod +x /usr/bin/hi
Erik Dannenberg
źródło
Dzięki za to, czy możesz podać przykład nieinteraktywnej powłoki? Szukałem ENTRYPOINT i CMD, aby rozwiązać ten problem
c24b
5
Alias ​​Bash działa tylko w powłokach interaktywnych. Po prostu stwórz mały skrypt powłoki i umieść w swojej ścieżce taki sam efekt jak alias. Zaktualizowałem odpowiedź prostym przykładem.
Erik Dannenberg
1
Uwaga: ze stackoverflow.com/a/8467449 powinieneś raczej używać printf zamiast echo, aby zapewnić bardziej spójne zachowanie. Więc printf '#! / Bin / bash \ necho hello'> / usr / bin / hi chmod + x / usr / bin / hi
barraq
2
Uwielbiam pomysł na skrypt powłoki. Chciałem dodać aliasy, ale jest to znacznie lepsze. Dzięki.
Blizz
3
Powinieneś użyć „$ @” zamiast $ * dla wielu argumentów ucieczki. Zobacz unix.stackexchange.com/questions/248464/…
gnou
14

Aby utworzyć alias istniejącego polecenia, możesz również użyć ln -s:

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

Laurent Magnin
źródło
7
Nie nazwałbym tego aliasem ... to jest miękki link / dowiązanie symboliczne. Wygoda aliasów polega na tym, że można przekazywać parametry do polecenia, alias ll='ls -lh'co nie jest możliwe w przypadku dowiązań symbolicznych.
qwertz
3

Jeśli chcesz używać aliasów tylko w Dockerfile, ale nie w kontenerze, najkrótszym sposobem jest ENVdeklaracja:

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

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

I do użycia w kontenerze w sposób już opisany:

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

Przez większość czasu używam aliasów tylko na etapie budowy i nie wchodzę do kontenerów, więc pierwszy przykład jest szybszy, czytelniejszy i prostszy do codziennego użytku.

Sonique
źródło
2

Właśnie dodałem to do mojego pliku 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"

a wewnątrz, initbash_profile.shktóry po prostu dodaje moje niestandardowe aliasy i nie ma potrzeby pobierania źródła pliku .bashrc.

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

działał świetnie!

Inną opcją jest użycie polecenia "docker exec -it" spoza kontenera i użycie własnego .bashrc lub .bash_profile (cokolwiek wolisz)

na przykład. docker exec -it docker_app_1 bash

mikoop
źródło
1

Możesz użyć punktu wejścia, ale nie będzie to działać dla aliasu w pliku Dockerfile:

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

Twój entrypoint.sh

#!/bin/bash
set -e

function dev_run()
{

}

export -f dev_run

exec "$@"

(Szybkie kopiowanie / wklejanie, przepraszam)

Thomas Decaux
źródło
Zwróć uwagę, że niektóre obrazy Dockera mogą już przesłonić domyślny punkt wejścia (na przykład obraz podstawowy phusion).
Thomas Decaux,
1

Myślę, że najłatwiejszym sposobem byłoby zamontowanie pliku w kontenerze zawierającym aliasy, a następnie określenie, gdzie bash powinien go znaleźć:

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

Przykładowe użycie:

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
źródło
0
  1. edytuj ten plik ~ / .bash_aliases vi ~/.bash_aliases
  2. źródło tego pliku ~ / .bash_aliases source ~/.bash_aliases
  3. Gotowe.
Eddy Ferreira
źródło
Jest to w porządku za każdym razem, gdy uruchamiasz kontener Dockera, ale aliasy nie pozostaną na następny raz. jeśli nie masz nic przeciwko dodawaniu ich za każdym razem, to rozwiązanie jest w porządku.
mikoop
0

Zastosowano niektóre z powyższych rozwiązań, ale aliasy nadal nie są rozpoznawane.

Próbuję ustawić aliasy i używać ich zarówno w późniejszych krokach Dockerfile, jak iw kontenerze w czasie wykonywania.

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;

Rozwiązaniem dla mnie było użycie zmiennych ENV, które zawierały ścieżki folderów, a następnie dodanie dokładnego pliku wykonywalnego. Mógłbym też użyć ARG, ale w przypadku większej liczby moich scenariuszy potrzebowałem aliasów zarówno na etapie kompilacji, jak i później w środowisku wykonawczym.

Użyto zmiennych ENV w połączeniu ze skryptem bash, który jest uruchamiany, gdy zależności już się sparują i ustawiają źródło bash, ustawia więcej zmiennych env i pozwala na przepuszczanie kolejnych poleceń.

alanionita
źródło
Każda RUNinstrukcja jest wykonywana w nowej powłoce, więc w twoim przykładzie plik aliasów nie jest już ładowany, gdy próbujesz użyć aliasu.
Erik Dannenberg
100% @ErikDannenberg dziękuję za komentarz, a także za przypomnienie mi, że muszę opublikować aktualizację - odkryłem rozwiązanie i jest bardzo podobne do sugestii.
alanionita
0

Oto funkcja Bash, która ma twoje aliasy w każdym kontenerze, którego używasz interaktywnie.

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
}

Wymagany krok przed:

grep ^alias ~/.zshrc > ~/bin/alias.sh
DjAlan
źródło