Ich freue mich darauf, einen Docker-Container pragmatisch zu stoppen und zu 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" anhalten und löschen, wie er unter der Spalte NAMES in einem Bash-Skript angezeigt wird.
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 führt die gewünschten Aufgaben aus
docker stop rabbitmq && docker rm -f rabbitmq
Es ist jedoch so, dass ich es in ein Skript kämme, das ich gerne wissen würde - ich denke, es würde so aussehen.
#!/bin/bash
if [ /*docker ps check some value */ ]; then
docker stop rabbitmq && docker rm -f rabbitmq
fi
Wie Sie wahrscheinlich bemerkt haben, beenden sowohl docker stop
als auch docker rm
einen Statuscode, der auf einen Fehler hinweist, wenn der Container nicht vorhanden ist oder nicht läuft. Dies führt dazu, dass Ihr Build fehlschlägt.
Wenn Sie mit den Fehlermeldungen in Ihrem Buildprotokoll umgehen können, können Sie mit diesem kleinen Trick verhindern, dass der Shell-Befehl fehlschlägt:
docker stop rabbitmq || true && docker rm rabbitmq || true
Falls einer der Docker-Befehle fehlschlägt, wird true
aufgerufen, die immer mit einem Statuscode beendet wird, der den Erfolg anzeigt.
Ich habe ein ähnliches Problem, aber die akzeptierte Antwort hat mir nicht gefallen, da sie all -Fehler von den Befehlen unterdrückt und nicht nur den Fehler "nicht gefunden".
docker ps -q --filter "name=rabbitmq"
erzeugt jedoch nur dann eine Ausgabe, wenn tatsächlich ein Container mit diesem Namen vorhanden ist, also inspiriert von Test, wenn ein Befehl eine leere Zeichenfolge ausgibt ich kam mit:
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 in der Definition eines Paares von Ansible-Tasks, bei dem alle derzeit vorhandenen Container (unabhängig davon, ob sie ausgeführt wurden oder nicht) aus einer Liste von Namen gelöscht wurden, die in einer früheren Task 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
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
erhält eine Befehlszeile var app
aus der Variablen von BASH $app
.NR>1
überspringt die erste Kopfzeile des Befehls docker ps
. $(NF) == app
Letzte Spalte vergleichen NAMES
ist gleich der App-Variablen oder nichtIch benutze Docker schon länger. Dies ist meine bevorzugte Methode, um einen Docker-Container anzuhalten und zu entfernen.
docker rm -f || true
Ich schlage vor, diese Beschwörung in bash:
( 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 gibt Stopped container $CONTAINER
Aus, wenn er tatsächlich angehalten wurde.
# Stop the running "rabbitmq" container if there is one
CONTAINER_NAME="rabbitmq"
OLD="$(docker ps --all --quiet --filter=name="$CONTAINER_NAME")"
if [ -n "$OLD" ]; then
docker stop $OLD && docker rm $OLD
fi
Wenn Sie Ihre gestoppten Container nicht löschen, können Sie dies mit Hilfe von docker ps -a
tun, der diese Container-ID immer zurückgibt. Wenn Sie dann docker stop
für diesen gestoppten Container ausführen, tun Sie einfach nichts:
docker stop $(docker ps -a --filter name= rabbitmq -q )
Kopieren Sie diesen Code in Ihre script.sh, wenn Sie alle stop
und remove
möchten
#!/bin/sh
ids=$(docker ps -a -q)
for id in $ids
do
echo "$id"
docker stop $id && docker rm $id
done