Chcę zrobić coś takiego, w którym mogę uruchamiać wiele poleceń w kolejności.
db:
image: postgres
web:
build: .
command: python manage.py migrate
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
ports:
- "8000:8000"
links:
- db
docker
yaml
docker-compose
RustyShackleford
źródło
źródło
/bin/bash
sh
zamiast tego:[sh, -c, "cd /usr/src/app && npm start"]
ash
na alpejskim :)Przed uruchomieniem uruchamiam rzeczy takie jak migracje w osobnym efemerycznym kontenerze, tak jak (uwaga, plik komponowania musi być typu „2”):
Pomaga to w utrzymaniu czystości i oddzielności. Dwie rzeczy do rozważenia:
Musisz upewnić się, że sekwencja uruchamiania jest poprawna (przy użyciu depend_on)
chcesz uniknąć wielu kompilacji, które osiąga się przez oznaczenie go za pierwszym razem przy użyciu kompilacji i obrazu; możesz wtedy odwoływać się do obrazu w innych pojemnikach
źródło
bash -c
wyżej.Polecam używanie
sh
w przeciwieństwie do,bash
ponieważ jest łatwiej dostępne na większości obrazów opartych na Uniksie (alpine itp.).Oto przykład
docker-compose.yml
:Spowoduje to wywołanie następujących poleceń w kolejności:
python manage.py wait_for_db
- poczekaj, aż baza danych będzie gotowapython manage.py migrate
- uruchom wszelkie migracjepython manage.py runserver 0.0.0.0:8000
- uruchom mój serwer programistycznyźródło
>
służy do uruchomienia wprowadzania wieloliniowego (patrz stackoverflow.com/a/3790497/2220370 )To działa dla mnie:
docker-compose próbuje wyzerować zmienne przed uruchomieniem polecenia, więc jeśli chcesz, aby bash obsługiwał zmienne, musisz uciec od znaków dolara poprzez ich podwojenie ...
... w przeciwnym razie pojawi się błąd:
źródło
$${Types}
i$${Client}
. Myślę, że zapobiegnie to interpretowaniu przez Dockera tych zmiennych i szukaniu ich wartości w dowolnej powłoce, z której wywołujesz Docker-compose, co oznacza, że nadal są w gotowości, by je odrzucić ( po przetworzeniu.env
pliku przez dokera ).Możesz użyć punktu wejścia tutaj. punkt wejścia w oknie dokowanym jest wykonywany przed poleceniem, podczas gdy polecenie jest domyślnym poleceniem, które należy uruchomić przy uruchomieniu kontenera. Tak więc większość aplikacji na ogół przeprowadza procedurę instalacji w pliku punktu wejścia, aw ostatnim zezwala na uruchomienie polecenia.
stwórz plik skryptu powłoki jako
docker-entrypoint.sh
(nazwa nie ma znaczenia) z następującą zawartością.w pliku docker-compose.yml użyj go
entrypoint: /docker-entrypoint.sh
i zarejestruj polecenie jakocommand: python manage.py runserver 0.0.0.0:8000
PS: nie zapomnij skopiowaćdocker-entrypoint.sh
wraz z kodem.źródło
docker-compose run service-name ....
Inny pomysł:
Jeśli, tak jak w tym przypadku, budujesz kontener, po prostu umieść w nim skrypt startowy i uruchom go za pomocą polecenia. Lub zamontuj skrypt startowy jako wolumin.
źródło
#!/bin/bash \n python manage.py migrate \n python manage.py runserver 0.0.0.0:8000
(brzydki oneline)* AKTUALIZACJA *
Uznałem, że najlepszym sposobem na uruchomienie niektórych poleceń jest napisanie niestandardowego pliku Docker, który robi wszystko, co chcę, zanim oficjalny plik CMD zostanie uruchomiony z obrazu.
docker-compose.yaml:
Dockerfile.mongo:
Jest to prawdopodobnie najczystszy sposób na zrobienie tego.
* STARA DROGA *
Za pomocą moich poleceń utworzyłem skrypt powłoki. W tym przypadku chciałem zacząć
mongod
i uruchomić,mongoimport
ale wywołaniemongod
blokuje ci uruchomienie pozostałych.docker-compose.yaml :
start_mongod.sh :
Więc to rozwidla mongo, wykonuje monogimport, a następnie zabija rozwidlone mongo, które jest odłączone, i uruchamia je ponownie bez odłączania. Nie jestem pewien, czy istnieje sposób na dołączenie do rozwidlonego procesu, ale to działa.
UWAGA: Jeśli chcesz ściśle załadować początkowe dane bazy danych, możesz to zrobić w następujący sposób:
mongo_import.sh
mongo_fixtures / *. json pliki zostały utworzone za pomocą komendy mongoexport.
docker-compose.yaml
źródło
Jeśli potrzebujesz uruchomić więcej niż jeden proces demona, w dokumentacji Dockera jest sugestia, aby używać Supervisord w trybie odłączonym, aby wszystkie pod-demony były wysyłane do standardowego wyjścia.
Z innego pytania SO odkryłem, że możesz przekierować dane wyjściowe procesów potomnych na standardowe wyjście. W ten sposób możesz zobaczyć wszystkie dane wyjściowe!
źródło
Aby uruchomić wiele poleceń w pliku tworzenia dokerów za pomocą
bash -c
.Źródło: https://intellipaat.com/community/19590/docker-run-multiple-commands-using-docker-compose-at-once?show=19597#a19597
źródło
Użyj narzędzia, takiego jak czekanie na niego lub dokowanie . Są to małe skrypty otoki, które można dołączyć do obrazu aplikacji. Lub napisz własny skrypt opakowania, aby wykonać polecenia bardziej specyficzne dla aplikacji. zgodnie z: https://docs.docker.com/compose/startup-order/
źródło
Natknąłem się na to, próbując skonfigurować mój kontener Jenkins, aby budować kontenery dokujące jako użytkownik Jenkins.
Musiałem dotknąć pliku docker.sock w pliku Docker, ponieważ łączę go później w pliku komponowania dokera. Chyba że najpierw go dotknąłem, jeszcze nie istniał. To zadziałało dla mnie.
Plik Docker:
docker-compose.yml:
źródło
spróbuj użyć „;” aby rozdzielić polecenia, jeśli jesteś w dwóch wersjach, np
command: "sleep 20; echo 'a'"
źródło