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?
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 .:
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.
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:
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.
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
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ń.
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.
Odpowiedzi:
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
źródło
Aby utworzyć alias istniejącego polecenia, możesz również użyć
ln -s
:ln -s $(which <existing_command>) /usr/bin/<my_command>
źródło
alias ll='ls -lh'
co nie jest możliwe w przypadku dowiązań symbolicznych.Jeśli chcesz używać aliasów tylko w Dockerfile, ale nie w kontenerze, najkrótszym sposobem jest
ENV
deklaracja: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.
źródło
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.sh
któ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
źródło
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)
źródło
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źć:
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
źródło
vi ~/.bash_aliases
source ~/.bash_aliases
źródło
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ń.
źródło
RUN
instrukcja 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.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
źródło