So starten Sie einen einzelnen Container mit Docker-Compose neu

332

Ich habe eine docker-compose.ymlDatei, die 4 Container enthält: Redis, Postgres, API, Worker

Während der Entwicklung von Worker muss ich es häufig neu starten, um Änderungen zu übernehmen. Gibt es eine gute Möglichkeit, einen Container neu zu starten (z. B. worker), ohne die anderen Container neu zu starten?

Bryan Chen
quelle
2
docker-compose -f docker-compose.yml Neustart Arbeiter
Jinna Balu

Antworten:

395

Es ist sehr einfach: Verwenden Sie den Befehl:

docker-compose restart worker

Sie können die Wartezeit bis zum Stoppen einstellen, bevor Sie den Container beenden (in Sekunden).

docker-compose restart -t 30 worker

Beachten Sie, dass dadurch der Container neu gestartet wird, ohne ihn jedoch neu zu erstellen. Wenn Sie Ihre Änderungen übernehmen und anschließend neu starten möchten, sehen Sie sich die anderen Antworten an.

bmkrio
quelle
3
Für mich hat es funktioniert, aber eine allgemeine Frage, wenn hier erlaubt: kümmert sich 'Neustart' um verknüpfte Container und aktualisiert die / etc / hosts oder ändert ein 'Neustart' überhaupt keine IPs?
Michabbb
Die Container sind nach Namen verknüpft. In der Regel ist die einzige IP-Adresse, über die Sie sich Sorgen machen müssen, die externe Docker-Host-IP (normalerweise 192.168.99.100). Probleme können auftreten, wenn Sie beispielsweise einen Datenbankcontainer neu starten, mit dem andere Container verbunden sind. Die abhängigen Container müssen stabil genug sein, um die Verbindung wiederherzustellen.
Ryan Kimber
20
Das OP gibt an, dass er "es neu starten muss, um Änderungen zu übernehmen". Gemäß den Dokumenten werden die docker-compose restartBefehle KEINE Änderungen übernehmen. "Wenn Sie Änderungen an Ihrer docker-compose.ymlKonfiguration vornehmen, werden diese Änderungen nach dem Ausführen dieses Befehls nicht mehr berücksichtigt." Verwenden Sie daher docker-compose up -d --build. docs.docker.com/compose/reference/restart
featherbelly
5
nb, worker ist der Name des Dienstes in der yaml-Datei und nichts, was Sie beim Ausführen sehendocker ps -a
worc
2
Diese andere Antwort ist viel besser stackoverflow.com/a/39501539/292408 , da restartkeine Änderungen angewendet werden , selbst wenn Sie bereits eine ausgeführt haben docker-compose build <container name>und dies eine nicht funktionierende / falsche Antwort ist.
Elijah Lynn
170

Die anderen Antworten zum Neustart eines einzelnen Knotens sind zielgerichtet docker-compose restart worker. Dadurch wird dieser Container zurückgeworfen, es werden jedoch keine Änderungen vorgenommen, selbst wenn Sie ihn separat neu erstellt haben. Sie können manuell stop, rm, create, undstart , aber es gibt viel einfacher Methoden.

Wenn Sie Ihren Code aktualisiert haben, können Sie das Erstellen und Neuladen in einem einzigen Schritt durchführen mit:

docker-compose up --detach --build

Dadurch werden Ihre Bilder zunächst aus geändertem Code neu erstellt. Dies ist schnell, wenn seit der Wiederverwendung des Caches keine Änderungen vorgenommen wurden. Und dann ersetzt es nur die geänderten Container. Wenn Ihre heruntergeladenen Bilder veraltet sind, können Sie dem obigen Befehl Folgendes voranstellen:

docker-compose pull

Um zuerst geänderte Bilder herunterzuladen (die Container werden erst neu gestartet, wenn Sie einen Befehl wie upoben ausführen ). Ein erster Stopp ist nicht erforderlich.

Um dies nur für einen einzelnen Dienst zu tun, folgen Sie dem Befehl up oder pull mit den Diensten, die Sie angeben möchten, z.

docker-compose up --detach --build worker

Hier ist ein kurzes Beispiel für die erste Option: Die Docker-Datei ist so strukturiert, dass die häufig wechselnden Teile des Codes am Ende bleiben. Tatsächlich werden die Anforderungen für die separat abgerufen, pip installda sich diese Datei selten ändert. Und da die Nginx- und Redis-Container auf dem neuesten Stand waren, wurden sie nicht neu gestartet. Die Gesamtzeit für den gesamten Prozess betrug weniger als 6 Sekunden:

$ 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
quelle
Das ist interessant, aber könnte es zusammen mit der -no-cacheOption verwendet werden? Angenommen, ich habe etwas zu meinem hinzugefügt package.jsonund muss es erneut ändern, RUN npm installaber das Dockerfileselbst hat sich nicht geändert
Augustin Riedinger,
2
@augustinriedinger Wenn Ihre Eingabedatei geändert wird und Sie diese in einen COPYBefehl einfügen , wird der Cache automatisch beschädigt .
BMitch
1
@augustinriedinger danke. Ich bin mobil und kann die verknüpften Fragen nicht sehen. Von den Schritten in Ihrer Frage sollten Sie bereits einen COPYBefehl in Ihrer Docker-Datei haben. Das git pullaktualisiert die Datei package.json und der Build-Cache wird unterbrochen, wenn Docker sieht, dass Sie in eine andere Datei kopieren.
BMitch
1
Danke wusste nichts über dieses Verhalten! Ich habe ADDstattdessen verwendet, COPYaber anscheinend ist Letzteres eine bewährte Methode, also werde ich es versuchen!
Augustin Riedinger
1
@augustinriedinger ADDhat das gleiche Ergebnis wie COPYbeim Cache-Bust, aber (wie im Link zu den Best Practices vorgeschlagen) benötigen die meisten keine zusätzlichen Funktionen, sodass ich mich nicht einmal darum kümmere, es zu erwähnen.
BMitch
28

Um einen Dienst mit Änderungen neu zu starten, habe ich folgende Schritte ausgeführt:

docker-compose stop -t 1 worker
docker-compose build worker
docker-compose create worker
docker-compose start worker
Jeff
quelle
10
Wenn Sie Änderungen benötigen, um sie mit einem Build zu übernehmen, können Sie einfach a docker-compose up -d --buildausführen. Dadurch wird alles neu erstellt und alle geänderten Container neu gestartet. Es ist nicht erforderlich, zuerst anzuhalten, da Ausfallzeiten auftreten und separate Befehle zum Erstellen und Starten erforderlich sind.
BMitch
4
Ja, wenn Sie alle Dienste neu starten möchten, aber das OP nur einen einzelnen Dienst neu starten möchte und nicht die anderen
Jeff
3
Siehe die Antwort, die ich gepostet habe. Im Beispiel wurde upnur der Container neu erstellt, der geändert wurde und daher einen Neustart benötigte.
BMitch
18

Befolgen Sie den Befehl

docker-compose restart worker

stoppt und startet einfach den Container. dh ohne Änderungen aus der Datei docker-compose.xml zu laden

STOP ähnelt dem Ruhezustand im PC. Daher sucht stop / start nicht nach Änderungen in der Konfigurationsdatei. Um aus dem Rezept des Containers (docker-compose.xml) neu zu laden, müssen wir den Container entfernen und erstellen (ähnliche Analogie zum Neustart des PCs).

Die Befehle lauten also wie folgt

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
Herr Coder
quelle
+1, vielen Dank! Die rmOption für die Zeile ist -fpraktisch (keine Eingabeaufforderung) und mit dem aktuellen Docker createund startwird zusammengeführt als up(also haben wir insgesamt 3 Befehle, nicht 4), und für die upOption -dist nützlich (die Ausführung erfolgt im Hintergrund).
Astrowalker
10

Starten Sie den Dienst mit der Docker-Compose-Datei neu

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

Anwendungsfall 1: Wenn COMPOSE_FILE_NAME docker-compose.ymlund Service Worker ist

docker-compose restart worker

Anwendungsfall 2: Wenn der Dateiname lautet sample.ymlund der Dienst Worker ist

docker-compose -f sample.yml restart worker

Standardmäßig sucht Docker-Compose nach dem, docker-compose.ymlwenn wir den docker-composeBefehl ausführen , andernfalls haben wir ein Flag, mit dem wir einen bestimmten Dateinamen angeben können-f [FILE_NAME].yml

Jinna Balu
quelle
7

Der einfache Befehl 'docker' weiß nichts über den 'Arbeiter'-Container. Verwenden Sie einen solchen Befehl

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

Shtlzut
quelle
4
funktioniert nicht - neue Änderungen an der coker-compose.yml wurden beim Neustart nicht angewendet
jlee
3

Container neu starten

Wenn Sie Ihren Container einfach neu starten möchten:

docker-compose restart servicename

Stellen Sie sich diesen Befehl als "Starten Sie den Container einfach mit seinem Namen neu" vor, was äquivalent zu ist docker restart Befehl entspricht.

Vorsichtsmaßnahmen beachten:

  1. Wenn Sie ENV-Variablen geändert haben, werden diese im Container nicht aktualisiert. Sie müssen es stoppen und erneut starten. Mit einem einzigen Befehl docker-compose upwerden Änderungen erkannt und der Container neu erstellt.

  2. Wie viele andere bereits erwähnt, werden docker-compose.ymldiese Änderungen beim einfachen Neustart nicht angewendet , wenn Sie die Datei selbst geändert haben.

  3. Wenn Sie Ihren Code in der Erstellungsphase in den Container kopieren (mit Dockerfileusing ADDoder COPYbefehlen), müssen Sie den Container jedes Mal neu erstellen, wenn sich der Code ändert ( docker-compose build).

Korrelation zu Ihrem Code

docker-compose restartsollte einwandfrei funktionieren, wenn Ihr Code durch die Volume-Direktive docker-compose.ymlwie folgt in den Container abgebildet wird :

services:

  servicename:
    volumes:
      - .:/code

Ich würde jedoch empfehlen, das Neuladen von Live-Code zu verwenden, das wahrscheinlich von Ihrem Framework im DEBUG-Modus bereitgestellt wird (alternativ können Sie nach Paketen zum automatischen Neuladen in der Sprache Ihrer Wahl suchen). Wenn Sie dies hinzufügen, müssen Sie den Container nicht jedes Mal neu starten, nachdem sich Ihr Code geändert hat, und stattdessen den darin enthaltenen Prozess neu laden.

Lev Rubel
quelle
1

Die Antwort hier spricht über die Reflexion der Änderung in der Datei docker-compose.yml.

Aber was ist, wenn ich die Änderungen, die ich vorgenommen habe, in meinen Code integrieren möchte und ich glaube, dass dies nur durch die Neuerstellung des Images möglich ist und dass ich die folgenden Befehle verwende

1. Docker Container Stop

docker stop container-id

2. Entfernen des Docker-Containers

docker rm container-id

3. Docker-Image-Entfernung

docker rmi image-id

4. Stellen Sie den Behälter erneut zusammen

docker-compose up container-name
Anshul Sharma
quelle