Ich möchte einen Docker-Container pragmatisch stoppen und löschen, wenn er ausgeführt wird. Dies ist für ein Build-Skript.
Nehmen Sie das folgende Beispiel. Wie würde ich den Docker-Container "rabbitmq" stoppen und löschen, wie in einem Bash-Skript unter der Spalte NAMES angezeigt?
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9909a5e2856f rabbitmq-image "/docker-entrypoint.s" 11 minutes ago Up 11 minutes 0.0.0.0:5672->5672/tcp, rabbitmq
8990dd1fe503 redis-image "/entrypoint.sh redis" 6 weeks ago Up 4 days 0.0.0.0:32770->6379/tcp redis
etc
Der folgende Befehl löscht den Container und macht das, was ich tun möchte
docker stop rabbitmq && docker rm -f rabbitmq
Es kämmt es jedoch in ein Skript, das ich gerne wissen würde? Ich denke, es würde ungefähr so aussehen.
#!/bin/bash
if [ /*docker ps check some value */ ]; then
docker stop rabbitmq && docker rm -f rabbitmq
fi
quelle
Error response from daemon: no such id: rabbitmq
wenn der Container bereits entfernt wurde.Ich habe ein ähnliches Problem, aber die akzeptierte Antwort hat mir nicht gefallen, da sie alle Fehler aus den Befehlen unterdrückt und nicht nur den Fehler "nicht gefunden".
docker ps -q --filter "name=rabbitmq"
Erzeugt jedoch nur eine Ausgabe, wenn tatsächlich ein Container mit diesem Namen vorhanden ist. Inspiriert von Test, wenn ein Befehl eine leere Zeichenfolge ausgibt, die ich mir ausgedacht habe:docker ps -q --filter "name=rabbitmq" | grep -q . && docker stop rabbitmq && docker rm -fv rabbitmq
Der folgende Befehl ist auch zum Testen von Filterdefinitionen hilfreich:
docker ps -q --filter "name=rabbitmq" | grep -q . && echo Found || echo Not Found
Mein eigentlicher Anwendungsfall bestand darin, ein Paar Ansible-Aufgaben zu definieren, mit denen alle derzeit vorhandenen Container (unabhängig davon, ob sie ausgeführt werden oder nicht) aus einer Liste von Namen gelöscht wurden, die in einer früheren Aufgabe generiert wurden:
- name: Check for containers that actually exist shell: 'docker ps -aq --filter "name={{ item }}"' with_items: - '{{ previous_command.stdout_lines }}' register: found_containers - name: Remove the containers found by the above command shell: 'docker stop {{ item.item }} && docker rm -fv {{ item.item }}' with_items: '{{ found_containers.results }}' when: item.stdout
quelle
docker ps -aq ...
. Die-a
Option bedeutet, dass auch Container gefunden werden, die vorhanden sind, aber derzeit nicht ausgeführt werden.ps -aq
auch verwendet, wie von @PeterBloomfield vorgeschlagen.grep -q .
auch einen Code ungleich Null und damit Ihre gesamte Zeile. Dies führt also immer noch zu einem Fehler. Was mich zwingen würde,|| echo 'not found'
etwas anzuhängen oder so etwas. Und zu diesem Zeitpunkt gibt es keinen großen Unterschied zur akzeptierten Antwortif docker ps -q --filter "name=rabbitmq" | grep -q .; then docker stop rabbitmq && docker rm -fv rabbitmq; fi
Ich benutze Docker jetzt schon eine Weile länger. Dies ist meine bevorzugte Methode, um einen Docker-Container anzuhalten und zu entfernen. Die Piping von true ist da, um sicherzustellen, dass immer ein Erfolg ausgegeben wird. Ohne sie würden Bash-Skripte beendet und fehlerhaft, wenn der Containername nicht vorhanden wäre.
docker rm -f container_name || true
quelle
docker rm -f container_name &>/dev/null && echo 'Removed old container'
Sie können verwenden:
app="rabbitmq" if docker ps | awk -v app="$app" 'NR > 1 && $NF == app{ret=1; exit} END{exit !ret}'; then docker stop "$app" && docker rm -f "$app" fi
awk
Der Befehlapp
ruft eine Befehlszeilenvariable aus der BASH-Variablen ab$app
NR>1
Überspringt die erste Kopfzeile vomdocker ps
Befehl.$(NF) == app
Die letzte Spalte vergleichenNAMES
entspricht der App-Variablen oder nichtquelle
# Stop and remove containers with names like "rabbitmq" and "rabbitmq123" if they exist CONTAINER_NAME="rabbitmq" OLD="$(docker ps --all --quiet --filter=name="$CONTAINER_NAME")" if [ -n "$OLD" ]; then docker stop $OLD && docker rm $OLD fi
quelle
Ich schlage diese Beschwörung in Bash vor:
( docker stop $CONTAINER > /dev/null && echo Stopped container $CONTAINER && \ docker rm $CONTAINER ) 2>/dev/null || true
Es wird immer mit 0 beendet, beschwert sich nicht, wenn der Container nicht ausgeführt wird, und druckt,
Stopped container $CONTAINER
wenn er tatsächlich gestoppt wurde.quelle
stop
/rm
den Behälter, wenn er gefunden wird.Eine allgemeine Form basierend auf einigen Antworten hier:
docker rm -f container_name > /dev/null 2>&1 && echo 'removed container' || echo 'nothing to remove'
quelle
Kopieren Sie diesen Code in Ihre script.sh, wenn Sie möchten
stop
undremove
alle#!/bin/sh ids=$(docker ps -a -q) for id in $ids do echo "$id" docker stop $id && docker rm $id done
quelle
Wenn Sie Ihre gestoppten Container nicht löschen, können Sie sich auch darauf verlassen
docker ps -a
, dass diese Container-ID immer zurückgegeben wird. Dann führt die Ausführungdocker stop
auf diesem gestoppten Container idempotent einfach nichts aus:docker stop $(docker ps -a --filter name= rabbitmq -q )
quelle
Um alle Container zu stoppen, müssen Sie zuerst alle Container mit stoppen
docker kill $(docker ps -q)
und alle Container zu löschen
und wenn Sie alle Bilder löschen möchten, ist dies der Befehl
quelle