Der richtige Weg, um den Docker-Container zu starten, wenn er für regelmäßige Aufgaben verwendet wird

Ich habe einen Docker-Container mit installierter und konfigurierter Software.

Es gibt kein Programm, das ständig gestartet / ausgeführt werden soll.

Was ich will - seine Fähigkeit, abhängig von externen Ereignissen einen Befehl zu starten. wie:

docker exec mysupercont /path/to/mycommand -bla -for

und

docker exec mysupercont /path/to/myothercommand 

Aber "exec" ist unmöglich, wenn der Container gestoppt wird, und auch dieser Container enthält einige "funktionierende" Daten, die für diese Befehle verwendet wurden, sodass ich sie nicht verwenden kann

docker run ...

jedes Mal, weil es Container aus Image neu erstellt und meine Daten zerstört.

Was ist der "richtige" und der "beste" Weg, um einen solchen Container am Laufen zu halten? Welchen Befehl kann ich drinnen starten?

Sie müssen nicht jedes Mal ausführen docker run.

docker run ist eigentlich eine Folge von zwei Befehlen: "Erstellen" und "Starten".

Wenn Sie den Container ausführen, müssen Sie die "-it":

-i, --interactive = false STDIN offen halten, auch wenn es nicht angehängt ist
-t, --tty=false Weist ein Pseudo-TTY zu

Beispiel:

docker run -it debian:stable bash

Nachdem die Arbeit abgeschlossen war, wurde der Befehl beim Start angegeben (in meinem Beispiel bash). Zum Beispiel führen Sie den "Exit" durch. Containerstopps:

CONTAINER ID        IMAGE                      COMMAND                CREATED             STATUS                     PORTS               NAMES1329c99a831b        debian:stable              "bash"                 51 seconds ago      Exited (0) 1 seconds ago                       goofy_bardeen

Jetzt können Sie es erneut starten

docker start 1329c99a831b

Der Container wird gestartet und führt erneut den Befehl "bash" aus.
Verbinden Sie sich mit dieser Sitzung "bash" mit dem Befehl

docker attach 1329c99a831b

Summieren: Sie müssen den Unterschied zwischen den run und start Container.
Schauen Sie sich außerdem die Dokumentation für die Rolle der Parameter "-i t" und "-d" für den "Lauf"

Da Sie periodische Aufgaben erwähnt haben und Sie wahrscheinlich so etwas wie cron verwenden, weil Sie es verwenden möchten docker exec, Ich habe nur die Medizin für dich. Zumindest bin ich dazu gekommen, so etwas zu tun.

  1. Dockerfile

    FROM <some base>CMD tail -f /dev/null
  2. Lauf mit dem Üblichen docker run -d .... (Ich habe verwendet docker-compose)

  3. Richten Sie zum Beispiel die Crontab für Hostcomputer ein:

    * * * * * docker exec mysupercont foo >> /var/log/foo.log 2>&1* * * * * docker exec mysupercont bar >> /var/log/bar.log 2>&1

Ich finde diese Lösung schön, da wir uns in einer hübschen Standard-Linux-Umgebung auf die alte und bewährte Crontab verlassen können, während Docker die exotischeren Deps und Umgebungsvariablen Ihrer Geschäftslogik verarbeitet. Sie können auch einige Grenzwerte festlegen, wenn Ihre regelmäßigen Aufgaben hängen bleiben und Speicherlecks haben oder was auch immer.

Diese ganze Angelegenheit, ob Sie einen angehaltenen Container starten können oder nicht, hängt davon ab, wie der Container ursprünglich erstellt, dh ausgeführt wurde. Wenn Sie einen Befehl ausgeführt haben, der beendet wurde, oder einen interaktiven Befehl, z. B. bash , beenden, können Sie den gestoppten Container nicht starten, neu starten oder ausführen. Alles, was Sie tun können, ist es zu entfernen. Es ist Schrott.

Aber taranakis letzter Kommentar, use '-itd' , scheint das zu sein, was der Docker bestellt hat.

Der Container läuft weiter und Sie können ausführen, was Sie möchten, und Sie können den Container stoppen, starten oder neu starten. Dies ist natürlich nur ein vorläufiger Befund, der auf dem Alpenbild basiert. Beachten Sie, wenn Sie an den Container anhängen, stoppt er beim Beenden, aber Sie können ihn erneut starten.

Ich habe alle vorgeschlagenen Lösungen hier selbst verwendet, aber alle verarbeiten keine SIGTERM-Signale, die vom Docker-Daemon kommen, wenn er den Container herunterfahren möchte (z. docker stop $containername).

Also schlage ich Folgendes vor:

FROM base:image# ...CMD sh -c 'trap "exit" TERM; while true; do sleep 1; done'

Es ist im Grunde ein kurzes Shell-Skript, das zuerst SIGTERM-Signale abfängt ("abfängt") und dann in einer Endlosschleife für eine Sekunde in den Ruhezustand wechselt.

Ich benutze es hauptsächlich zusammen mit docker-compose und Ophelia bereitstellung von Seitenwagencontainern zum Sichern eines anderen Dienstes in einem anderen Container (z. B. MariaDB-Datenbanken).

docker run -d --name = Name Container Schwanz -f / dev / null

Dies ist eine sehr gut erklärte Frage. Siehe einen anderen ähnlichen Beitrag here.