Jak zrestartować pojedynczy pojemnik za pomocą Docker-Compose

333

Mam docker-compose.ymlplik, który zawiera 4 pojemniki: redis, postgres, api, pracownik

Podczas opracowywania pracownika często muszę go ponownie uruchamiać, aby zastosować zmiany. Czy istnieje dobry sposób na ponowne uruchomienie kontenera (np. worker) Bez ponownego uruchamiania innych kontenerów?

Bryan Chen
źródło
2
docker-compose -f docker-compose.yml uruchom ponownie robotę
Jinna Balu

Odpowiedzi:

398

To bardzo proste: użyj polecenia:

docker-compose restart worker

Możesz ustawić czas oczekiwania na zatrzymanie przed zabiciem kontenera (w sekundach)

docker-compose restart -t 30 worker

Pamiętaj, że spowoduje to ponowne uruchomienie kontenera, ale bez jego przebudowywania. Jeśli chcesz zastosować zmiany, a następnie uruchomić ponownie, spójrz na inne odpowiedzi.

bmkrio
źródło
3
dla mnie zadziałało, ale ogólne pytanie, czy jest dozwolone: ​​czy „restart” zajmuje się połączonymi kontenerami i aktualizuje / etc / hosts, czy też „restart” nie zmienia żadnych adresów IP?
michabbb 11.01.16
Kontenery są połączone według nazwy i zazwyczaj jedynym adresem IP, o który musisz się martwić, jest adres IP zewnętrznego hosta dokera (zazwyczaj 192.168.99.100). Problemem może być, powiedzmy, zrestartowanie kontenera bazy danych, do którego podłączone są inne kontenery. Zależne pojemniki będą musiały być wystarczająco sprężyste, aby ponownie się połączyć.
Ryan Kimber
20
OP stwierdza, że ​​musi „uruchomić go ponownie, aby zastosować zmiany”. Zgodnie z dokumentami docker-compose restartpolecenia NIE będą stosować żadnych zmian. „Jeśli wprowadzisz zmiany w docker-compose.ymlkonfiguracji, zmiany te nie zostaną odzwierciedlone po uruchomieniu tego polecenia.” Dlatego użyj docker-compose up -d --build. docs.docker.com/compose/reference/restart
featherbelly
5
nb, pracownik to nazwa nadana usłudze w pliku yaml, a nie cokolwiek, co widać po uruchomieniudocker ps -a
worc
2
Ta druga odpowiedź jest o wiele lepsza stackoverflow.com/a/39501539/292408 , ponieważ restartnie stosuje zmian, nawet jeśli już uruchomiłeś a docker-compose build <container name>i jest to niedziałająca / niepoprawna odpowiedź.
Elijah Lynn
170

Inne odpowiedzi na ponowne uruchomienie pojedynczego węzła są na celu, docker-compose restart worker . Spowoduje to odbicie tego kontenera, ale nie spowoduje żadnych zmian, nawet jeśli przebudujesz go osobno. Można ręcznie stop, rm, create, i start, ale są znacznie łatwiejsze sposoby.

Jeśli zaktualizowałeś kod, możesz wykonać kompilację i przeładować w jednym kroku za pomocą:

docker-compose up --detach --build

To najpierw odbuduje obrazy z dowolnego zmienionego kodu, co jest szybkie, jeśli nie ma żadnych zmian od ponownego użycia pamięci podręcznej. A następnie zastępuje tylko zmienione pojemniki. Jeśli pobrane obrazy są nieaktualne, możesz poprzedzić powyższe polecenie:

docker-compose pull

Aby najpierw pobrać zmienione obrazy (pojemniki nie zostaną ponownie uruchomione, dopóki nie uruchomisz polecenia takiego jak uppowyżej). Wykonanie pierwszego zatrzymania nie jest konieczne.

Aby to zrobić tylko w przypadku pojedynczej usługi, wykonaj polecenie w górę lub w dół, używając usług, które chcesz określić, np .:

docker-compose up --detach --build worker

Oto szybki przykład pierwszej opcji, Dockerfile ma strukturę, która utrzymuje często zmieniające się części kodu pod koniec. W rzeczywistości wymagania są pobierane osobno, pip installponieważ plik ten rzadko się zmienia. A ponieważ kontenery nginx i redis były aktualne, nie zostały ponownie uruchomione. Całkowity czas całego procesu wynosił poniżej 6 sekund:

$ time docker-compose -f docker-compose.nginx-proxy.yml up --detach --build
Building counter
Step 1 : FROM python:2.7-alpine
 ---> fc479af56697
Step 2 : WORKDIR /app
 ---> Using cache
 ---> d04d0d6d98f1
Step 3 : ADD requirements.txt /app/requirements.txt
 ---> Using cache
 ---> 9c4e311f3f0c
Step 4 : RUN pip install -r requirements.txt
 ---> Using cache
 ---> 85b878795479
Step 5 : ADD . /app
 ---> 63e3d4e6b539
Removing intermediate container 9af53c35d8fe
Step 6 : EXPOSE 80
 ---> Running in a5b3d3f80cd4
 ---> 4ce3750610a9
Removing intermediate container a5b3d3f80cd4
Step 7 : CMD gunicorn app:app -b 0.0.0.0:80 --log-file - --access-logfile - --workers 4 --keep-alive 0
 ---> Running in 0d69957bda4c
 ---> d41ff1635cb7
Removing intermediate container 0d69957bda4c
Successfully built d41ff1635cb7
counter_nginx_1 is up-to-date
counter_redis_1 is up-to-date
Recreating counter_counter_1

real    0m5.959s
user    0m0.508s
sys     0m0.076s
BMitch
źródło
Jest to interesujące, ale czy można go używać wraz z -no-cacheopcją? Powiedzmy, że dodałem coś do siebie package.jsoni muszę ponownie, RUN npm installale Dockerfilesamo się nie zmieniło
Augustin Riedinger
2
@ augustinriedinger Jeśli plik wejściowy zostanie zmieniony i zostanie dołączony do niego COPYpolecenie, spowoduje to automatyczne uszkodzenie pamięci podręcznej.
BMitch
1
@augustinriedinger dzięki. Jestem mobilny, więc nie widzę powiązanych pytań. Z kroków w swoim pytaniu powinieneś już mieć COPYpolecenie w swoim Dockerfile. git pullZaktualizuje plik package.json i cache budować złamie gdy doker widzi kopiowanie w innym pliku.
BMitch
1
Dzięki nie wiedziałem o tym zachowaniu! Używałem ADDzamiast, COPYale najwyraźniej ta ostatnia jest najlepszą praktyką, więc pójdę po nią!
Augustin Riedinger
1
@ augustinriedinger ADDbędzie miał taki sam wynik jak COPYw przypadku awarii pamięci podręcznej, ale (jak sugeruje link do najlepszych praktyk) większość nie potrzebuje dodatkowych możliwości, więc nawet nie zawracam sobie tym głowy.
BMitch
28

Aby ponownie uruchomić usługę ze zmianami tutaj, wykonaj następujące kroki:

docker-compose stop -t 1 worker
docker-compose build worker
docker-compose create worker
docker-compose start worker
Jeff
źródło
10
Jeśli potrzebujesz zmian, aby zastosować się do kompilacji, możesz łatwo zrobić a, docker-compose up -d --builda wszystko odbuduje i zrestartuje zmienione kontenery. Najpierw nie ma potrzeby zatrzymywania, z przestojami i osobnymi poleceniami tworzenia i uruchamiania.
BMitch
4
Tak, jeśli chcesz zrestartować wszystkie usługi, ale OP chce zrestartować tylko jedną usługę, a nie restartować pozostałe
Jeff
3
Zobacz odpowiedź, którą opublikowałem, w tym przykładzie upodtworzy tylko kontener, który został zmieniony i dlatego wymagał ponownego uruchomienia.
BMitch
18

Po poleceniu

docker-compose restart worker

po prostu ZATRZYMA i uruchomi pojemnik. tzn. bez ładowania żadnych zmian z pliku docker-compose.xml

STOP jest podobny do hibernacji na PC. Dlatego stop / start nie będzie szukał żadnych zmian dokonanych w pliku konfiguracyjnym. Aby ponownie załadować z receptury kontenera (docker-compose.xml), musimy usunąć i utworzyć kontener (analogicznie do ponownego uruchomienia komputera)

Więc polecenia będą następujące

docker-compose stop worker       // go to hibernate
docker-compose rm worker        // shutdown the PC 
docker-compose create worker     // create the container from image and put it in hibernate

docker-compose start worker //bring container to life from hibernation
Pan Coder
źródło
+1, wielkie dzięki! Dla rmlinii opcja -fjest przydatna (bez monitu) i z bieżącym dokerem createi startjest scalana jako up(więc w sumie mamy 3 polecenia, a nie 4), a dla upopcji -djest przydatna (wykonanie jest w tle).
astrowalker
10

Uruchom ponownie usługę z plikiem skompilowania dokera

docker-compose -f [COMPOSE_FILE_NAME].yml restart [SERVICE_NAME]

Użyj przypadku nr 1: jeśli plik COMPOSE_FILE_NAME jest, docker-compose.ymla usługa jest pracownikiem

docker-compose restart worker

Przykład 2: jeśli nazwa pliku to sample.ymlusługa jest pracownikiem

docker-compose -f sample.yml restart worker

Domyślnie docker-compose szuka, docker-compose.ymljeśli uruchomimy docker-composepolecenie, w przeciwnym razie mamy flagę, za pomocą której można podać konkretną nazwę pliku-f [FILE_NAME].yml

Jinna Balu
źródło
7

Proste polecenie „dokera” nic nie wie o kontenerze „pracownika”. Użyj polecenia w ten sposób

docker-compose -f docker-compose.yml restart worker

Shtlzut
źródło
4
nie działa - nowe zmiany do koksowania-compose.yml nie zostanie zastosowana na restart
jlee
3

Uruchom ponownie pojemnik

Jeśli chcesz ponownie uruchomić kontener:

docker-compose restart servicename

Pomyśl o tym poleceniu jako „po prostu uruchom ponownie kontener według jego nazwy”, co jest równoważne z docker restart poleceniu.

Uwaga:

  1. Jeśli zmieniłeś zmienne ENV, nie zostaną zaktualizowane w kontenerze. Musisz to zatrzymać i zacząć od nowa. Lub za pomocą pojedynczego polecenia docker-compose upwykryje zmiany i ponownie utworzy kontener.

  2. Jak wielu innych wspomniało, jeśli zmieniłeś docker-compose.ymlsam plik, proste ponowne uruchomienie nie zastosuje tych zmian.

  3. Jeśli skopiujesz kod do kontenera na etapie kompilacji (przy Dockerfileużyciu ADDlub COPYpoleceń), za każdym razem, gdy kod się zmieni, musisz odbudować kontener ( docker-compose build).

Korelacja z twoim kodem

docker-compose restartpowinien działać idealnie dobrze, jeśli twój kod zostanie zmapowany do kontenera według dyrektywy woluminu w następujący docker-compose.ymlsposób:

services:

  servicename:
    volumes:
      - .:/code

Ale zalecam użycie przeładowania kodu na żywo, który zapewne zapewniony jest przez wybrany przez ciebie framework w trybie DEBUG (alternatywnie możesz wyszukać pakiety automatycznego przeładowania w wybranym języku). Dodanie tego powinno wyeliminować potrzebę ponownego uruchamiania kontenera za każdym razem po zmianie kodu, zamiast przeładowywania procesu w środku.

Lew Rubel
źródło
1

Odpowiedzi tutaj mówią o odzwierciedleniu zmiany w pliku docker-compose.yml.

Ale co, jeśli chcę uwzględnić zmiany, które wprowadziłem w kodzie, i wierzę, że będzie to możliwe tylko poprzez odbudowę obrazu i że wykonam następujące polecenia

1. przystanek kontenera dokującego

docker stop container-id

2. usunięcie pojemnika dokera

docker rm container-id

3. usuwanie obrazu dokera

docker rmi image-id

4. skomponuj pojemnik ponownie

docker-compose up container-name
Anshul Sharma
źródło