Próbuję stworzyć skrypt powłoki do konfigurowania kontenera dockera. Mój plik skryptu wygląda następująco:
#!bin/bash
docker run -t -i -p 5902:5902 --name "mycontainer" --privileged myImage:new /bin/bash
Uruchomienie tego pliku skryptu spowoduje uruchomienie kontenera w nowo wywołanym bash.
Teraz muszę uruchomić plik skryptu (test.sh), który jest już w kontenerze z podanego powyżej skryptu powłoki. (Np .: cd /path/to/test.sh && ./test.sh) Jak to zrobić?
WORKDIR
iCMD
?Odpowiedzi:
Możesz uruchomić polecenie w działającym kontenerze za pomocą
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
:docker exec mycontainer /path/to/test.sh
Aby uruchomić z sesji bash:
docker exec -it mycontainer /bin/bash
Stamtąd możesz uruchomić swój skrypt.
źródło
docker exec -i mycontainer bash < mylocal.sh
Czyta skrypt lokalnego hosta i uruchamia go w kontenerze. Możesz to zrobić z innymi rzeczami (takimi jak pliki .tgz przesłane potokiem do tar) - po prostu użyj '-i', aby przesłać potok do wejścia standardowego procesu kontenera.Get-Content mylocal.sh | docker exec -i mycontainer bash
. Nie wiem, czy to działa.Zakładając, że Twój kontener Docker jest uruchomiony i działa, możesz uruchamiać polecenia jako:
docker exec mycontainer /bin/sh -c "cmd1;cmd2;...;cmdn"
źródło
/bin/sh -c "cmd1; cmd2; ...; cmdn"
) jako wartość zmiennej powłoki? Pytam, ponieważ „docker run” wydaje się oczekiwać pojedynczego polecenia i pojedynczych niecytowanych argumentów, a nie cytowanego ciągu.cmd1
, muszę zdać się na całej pętli - ale spodziewa się;
po pętli oświadczenia i zrobić oświadczenie. Jak mogę uruchomić całą pętlę for jako jedno polecenie, tj.cmd1
? Czy to możliwe?Szukałem odpowiedzi na to samo pytanie i znalazłem ENTRYPOINT w rozwiązaniu Dockerfile .
Dockerfile
Teraz skrypty są wykonywane, kiedy uruchamiam kontener, a po wykonaniu skryptów pojawia się monit bash.
źródło
Możesz także zamontować katalog lokalny w obrazie Dockera i umieścić skrypt w swoim
.bashrc
. Nie zapominaj, że skrypt musi składać się z funkcji, chyba że chcesz, aby był wykonywany na każdej nowej powłoce. (To jest nieaktualne, zobacz informację o aktualizacji).Używam tego rozwiązania, aby móc zaktualizować skrypt poza instancją dockera. W ten sposób nie muszę ponownie uruchamiać obrazu, jeśli nastąpią zmiany, po prostu otwieram nową powłokę. (Pozbyłem się ponownego otwierania powłoki - zobacz informację o aktualizacji)
Oto jak wiążesz swój bieżący katalog:
docker run -it -v $PWD:/scripts $my_docker_build /bin/bash
Teraz twój bieżący katalog jest powiązany
/scripts
z twoją instancją dockera.(Nieaktualne) Aby zapisać
.bashrc
zmiany, zatwierdź obraz roboczy za pomocą tego polecenia:docker commit $container_id $my_docker_build
Aktualizacja
Aby rozwiązać problem otwierania nowej powłoki dla każdej zmiany, teraz wykonuję następujące czynności:
W samym dockerfile dodaję
RUN echo "/scripts/bashrc" > /root/.bashrc"
. Wewnątrzzshrc
eksportuję katalog skryptów do ścieżki. Katalog scripts zawiera teraz wiele plików zamiast jednego. Teraz mogę bezpośrednio wywoływać wszystkie skrypty bez otwierania powłoki podrzędnej przy każdej zmianie.BTW, możesz również zdefiniować plik historii poza kontenerem. W ten sposób nie jest już konieczne zatwierdzanie zmiany bash.
źródło
Jeśli nie chcesz (lub nie masz) uruchomionego kontenera, możesz wywołać swój skrypt bezpośrednio za pomocą
run
polecenia.Usuń iteracyjne
-i -t
argumenty tty i użyj tego:To zadziała (nie testowane) również dla innych skryptów:
źródło
Spójrz też na punkty wejścia. Będziesz mógł korzystać z wielu CMD https://docs.docker.com/engine/reference/builder/#/entrypoint
źródło
Jeśli chcesz uruchomić to samo polecenie w wielu instancjach, możesz to zrobić:
for i in c1 dm1 dm2 ds1 ds2 gtm_m gtm_sl; do docker exec -it $i /bin/bash -c "service sshd start"; done
źródło