Wie kann ich einen Docker-Container beim Systemstart automatisch starten lassen?

108

Angenommen, ich habe einen Docker-Container, den ich ausführen möchte, dann kann ich anrufen

$ docker run ...

und alles ist gut Gibt es eine integrierte Möglichkeit, einen Container so auszuführen, dass er automatisch neu gestartet wird, wenn das System abstürzt und neu startet?

Wenn ja, ist dies auch in Docker Compose verfügbar?

Golo Roden
quelle

Antworten:

129

Ja, Docker verfügt über solche Neustartrichtliniendocker run --restart=always , die dies behandeln. Dies ist auch in der Konfigurationsdatei compose.yml als verfügbar restart: always.

Peter Lyons
quelle
25
Dies ist die erste und akzeptierte Antwort, aber wahrscheinlich möchten die meisten Leute, die nach dieser Funktion suchen, ihren Container wirklich als Dienst ausführen. Die Antwort von @kon Systemdals Service Manager ist eine der besten Lösungen für diesen Zweck und erfordert mehr Upvotes.
Rémi Becheras
1
Das hat bei mir nicht funktioniert. Ich habe einen Container namens "crmpicco-mysql" und bin gelaufen docker run --restart=always crmpicco-mysqlund habe den Fehler erhalten : Unable to find image 'crmpicco-mysql:latest' locally.
Crmpicco
2
Ihr Fehler hat nichts damit zu tun. Möglicherweise möchten Sie eine separate Frage stellen, aber es sieht so aus, als würden Sie Docker-Bildnamen und Docker-Containernamen verwechseln. Der docker runBefehl erwartet den Namen eines Bildes, über das Sie auflisten können docker images.
Peter Lyons
11
Das einzige Problem dabei ist, dass "immer" den Container auch unendlich neu startet, wenn er aufgrund eines Fehlers gestoppt wurde (siehe Dokumentation). Es sollte eine Richtlinie geben, die nur beim Start des Daemons beginnt
lostiniceland
4
Ich dachte, eines der Hauptverkaufsargumente von Containern / Docker war, dass ich nicht jeden meiner Dienste in systemd installieren und verwalten muss (was schmerzhaft sein kann).
Marc
136

Wenn Sie möchten, dass der Container gestartet wird, auch wenn kein Benutzer eine Anmeldung durchgeführt hat (wie die VirtualBox-VM, die ich nur starte und nicht jedes Mal anmelden möchte). Hier sind die Schritte, die ich für Ubuntu 16.04 LTS ausgeführt habe. Als Beispiel habe ich einen Oracle DB-Container installiert:

$ docker pull alexeiled/docker-oracle-xe-11g
$ docker run -d --name=MYPROJECT_oracle_db --shm-size=2g -p 1521:1521 -p 8080:8080 alexeiled/docker-oracle-xe-11g
$ vim /etc/systemd/system/docker-MYPROJECT-oracle_db.service

und fügen Sie den folgenden Inhalt hinzu:

[Unit]
Description=Redis container
Requires=docker.service
After=docker.service

[Service]
Restart=always
ExecStart=/usr/bin/docker start -a MYPROJECT_oracle_db
ExecStop=/usr/bin/docker stop -t 2 MYPROJECT_oracle_db

[Install]
WantedBy=default.target

und aktivieren Sie den Dienst beim Start

sudo systemctl enable docker-MYPROJECT-oracle_db.service

Weitere Informationen finden Sie unter https://docs.docker.com/engine/admin/host_integration/.

kon
quelle
9
Für diejenigen, die dies mit Docker-Compose tun möchten, können Sie den dockerobigen docker-composeBefehl durch den Befehl ersetzen , indem Sie das -fFlag verwenden, um den Speicherort der Docker-Compose-Datei anzugeben:/usr/bin/docker-compose -f /path/to/docker-compose.yml up
charlesreid1
1
Wenn Sie docker-compose.ymleine .envDatei angeben möchten , verwenden Sie --project-directory /path/to zusätzlich zur expliziten Angabe Ihrer Docker- Erstellungsdatei, um zu den Aussagen von @ charlesreid1 hinzuzufügen .
whlteXbread
1
Docker verfügt über ein Protokollsystem und einen Prozessmanager. Es ist bedauerlich, dass es nicht die richtige Neustartrichtlinie gibt.
Franklin Yu
Haben Sie eine Idee, wie dies unter Windows Server 2012 funktioniert? Ich kann Docker nur ausführen, wenn ich mich anmelde ...
Alex Lord Mordor
Für einige könnte es auch interessant sein, dass es eine hilfreiche [Unit]Richtlinie gibt Before=. Insbesondere beim Starten von Dingen wie Datenbankverwaltungssystemen kann es hilfreich sein, sicherzustellen, dass diese vor bestimmten anderen Diensten gestartet werden.
Micha
90

Die Standardrichtlinie für den Neustart ist no.

Verwenden Sie für die erstellten Container die docker updateAktualisierungsrichtlinie.

docker update --restart=always 0576df221c0b

0576df221c0b ist die Container-ID.

Edward Young
quelle
Bedeutet das nicht, alwaysdass der Container neu gestartet wird, auch wenn ich ihn stoppe? Sicherlich gibt es eine Möglichkeit, einen Container beim Neustart ohne diese Art von dauerhaftem Start neu zu starten ...
Marc
4
@Marc: nein. Siehe die Dokumentation :If you manually stop a container, its restart policy is ignored until the Docker daemon restarts or the container is manually restarted. This is another attempt to prevent a restart loop.
SaeX
12

Sie können verwenden docker update --restart=on-failure <container ID or name> .

Zusätzlich zu dem, was der Name andeutet, on-failureZusätzlich zu dem, wird der Container nicht nur bei einem Fehler neu gestartet, sondern auch beim Systemstart.

Gemäß der Dokumentation gibt es mehrere Neustartoptionen:

Flag            Description
no              Do not automatically restart the container. (the default)
on-failure      Restart the container if it exits due to an error, which manifests as a non-zero exit code.
always          Always restart the container if it stops. If it is manually stopped, it is restarted only when Docker daemon restarts or the container itself is manually restarted. (See the second bullet listed in restart policy details)
unless-stopped  Similar to always, except that when the container is stopped (manually or otherwise), it is not restarted even after Docker daemon restarts.
SaeX
quelle
3
Wow, gute Arbeit, dies zu entdecken, wenn man bedenkt, dass es in der Dokumentation nicht erwähnt wird. Perfekte Lösung für mich.
Cameron Hudson
Eine Sache zu beachten über die Verwendung von On-Ausfall, wenn Sie einen Container haben , die auf einem anderen bereits ausgeführt , hängt es nicht zu sein scheint ein „Auftrag starten“, so eine beginnen und sofort scheitern und nie auf O Boot starten
Ferr
10

1) Zunächst müssen Sie den Docker-Dienst beim Booten aktivieren

$ sudo systemctl enable docker

2) Wenn Sie Docker-Compose .yml-Datei hinzufügen restart: alwaysoder Docker-Container hinzufügen, fügen Sie restart = immer so hinzu:

docker run --restart=always und Docker-Container ausführen

Stelle sicher

Wenn Sie einen Container manuell stoppen, wird seine Neustartrichtlinie ignoriert, bis der Docker-Dämon neu gestartet oder der Container manuell neu gestartet wird.

Siehe diese Neustartrichtlinie auf Docker offizielle Seite

3) Wenn Sie Docker-Compose starten möchten, werden alle Dienste ausgeführt, wenn Sie Ihr System neu starten. Sie führen den folgenden Befehl also nur einmal aus

$ docker-compose up -d
Abdul Basit
quelle
9

"Sanfter" Modus aus der Dokumentation:

docker run -dit --restart unless-stopped <image_name>
Rib47
quelle
2
Wenn der Docker-Daemon durch einen Neustart gestoppt wird, "stoppt" der Daemon die Container leider und markiert sie als gestoppt. Wenn das System dann startet, werden diese nicht gestartet. Es ist dumm. Hier ist der Fehler: github.com/docker/for-linux/issues/652
mlissner
Die restart=unless-stoppedOption versucht, Container zu starten, wenn die Docker-Engine neu gestartet wird. Die Ausnahmen, die ich gesehen habe, sind, wenn die Docker-Engine selbst nicht so konfiguriert ist, systemctl status dockerdass sie beim Neustart automatisch startet (stellen Sie sicher, dass sie aktiviert ist) und die Engine Container startet, bevor das Netzwerk bereit ist, was ich nur bei Overlay-Netzwerken gesehen habe. Beide würden auch brechen restart=always.
BMitch
2

Dafür ist Crontab da:

@reboot sleep 10 ; docker start <container name> 2>&1 | /usr/bin/logger -t 'docker start'

Greifen Sie auf Ihre Benutzer-Crontab zu crontab -eoder zeigen Sie sie an crontab -loder bearbeiten Sie Ihre System-Crontab unter/etc/crontab

Travis Runyard
quelle
Was ist Cron Service Start vor Docker Service ... dies würde in diesem Fall fehlschlagen ...
Akhil Jalagam
1
@AkhilJalagam Ich bin nicht sicher, ob ich Ihr Problem verstehe. Die "Schlaf-10" gibt crond genügend Zeit zum Starten und startet dann den Container nach dem Systemstart / Neustart. Diese Methode erfordert keine Anmeldung vor dem Start und vermeidet unordentliche, komplizierte System- und Serviceeinheiten. Die systemd Service Unit-Methode fühlt sich noch hackiger an als mein Beispiel.
Travis Runyard
2

Sie können einen Container ausführen , der immer neu gestartet wird, indem Sie:

$ docker run -dit --restart unless-stopped <image name OR image hash>

Wenn Sie die Konfigurationen eines laufenden Containers ändern möchten, sollten Sie diese aktualisieren durch:

$ docker update --restart=<options> <container ID OR name>

Wenn Sie die aktuelle Richtlinie des Containers anzeigen möchten, führen Sie zunächst den folgenden Befehl aus:

docker inspect gateway | grep RestartPolicy -A 3

Nicht zu vergessen, dass der installierte Docker-Daemon beim Systemstart aktiviert wird durch:

$ systemctl enable docker

Um eine vollständige Liste der Neustart Politik zu sehen, siehe: Restart Richtlinien

Mohsen Abasi
quelle
1

Ich wollte einen Start des Startcontainers unter Windows erreichen.

Daher habe ich gerade eine geplante Aufgabe erstellt, die beim Systemstart gestartet wird. Diese Aufgabe startet einfach "Docker für Windows.exe" (oder wie auch immer der Name Ihrer ausführbaren Docker-Datei lautet).

Dann werden alle Container mit der Neustartrichtlinie "immer" gestartet.

TostMaster
quelle
1

Ich habe ein ähnliches Problem beim Ausführen von Linux-Systemen. Nach dem Booten des Systems wurde ein Container mit der Neustartrichtlinie "sofern nicht gestoppt" nicht automatisch neu gestartet, es sei denn, ich gab einen Befehl ein, der Docker auf irgendeine Weise verwendete, z. B. "Docker ps". Ich war überrascht, als ich erwartete, dass dieser Befehl nur einige Statusinformationen meldet. Als nächstes habe ich den Befehl "systemctl status docker" ausprobiert. Auf einem System, auf dem keine Docker-Befehle ausgeführt wurden, meldete dieser Befehl Folgendes:

● docker.service - Docker Application Container Engine

   Loaded: loaded (/lib/systemd/system/docker.service; disabled; vendor preset: enabled)

     Active: inactive (dead)    TriggeredBy: ● docker.socket
       Docs: https://docs.docker.com

Auf einem System, auf dem "Docker ps" ohne andere Docker-Befehle ausgeführt wurde, wurde Folgendes angezeigt:

● docker.service - Docker Application Container Engine
    Loaded: loaded (/lib/systemd/system/docker.service; disabled; vendor preset: enabled)

    Active: active (running) since Sun 2020-11-22 08:33:23 PST; 1h 25min ago

TriggeredBy: ● docker.socket
       Docs: https://docs.docker.com

   Main PID: 3135 (dockerd)
      Tasks: 13

    Memory: 116.9M
     CGroup: /system.slice/docker.service
             └─3135 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
 ... [various messages not shown ]

Die wahrscheinlichste Erklärung ist, dass Docker auf einen Docker-Befehl wartet, bevor Container vollständig initialisiert und gestartet werden. Sie könnten vermutlich "Docker ps" in einer systemd-Einheitendatei zu einem Zeitpunkt ausführen, nachdem alle Dienste, die Ihre Container benötigen, initialisiert wurden. Ich habe dies getestet, indem ich eine Datei mit dem Namen docker-onboot.service in das Verzeichnis / lib / systemd / system mit folgendem Inhalt gestellt habe:

[Unit]
# This service is provided to force Docker containers
# that should automatically restart to restart when the system
# is booted. While the Docker daemon will start automatically,
# it will not be fully initialized until some Docker command
# is actually run.  This unit merely runs "docker ps": any
# Docker command will result in the Docker daemon completing
# its initialization, at which point all containers that can be
# automatically restarted after booting will be restarted.
#
Description=Docker-Container Startup on Boot
Requires=docker.socket
After=docker.socket network-online.target containerd.service

[Service]
Type=oneshot
ExecStart=/usr/bin/docker ps

[Install]

WantedBy = multi-user.target

Bisher (ein Test mit aktiviertem Dienst) wurde der Container beim Booten des Computers gestartet. Ich habe keine Abhängigkeit von docker.service versucht, da docker.service erst gestartet wird, wenn ein Docker-Befehl ausgeführt wird. Der nächste Test wird mit deaktiviertem Docker-Onboot durchgeführt (um festzustellen, ob die WantedBy-Abhängigkeit sie automatisch startet).

Bill Zaumen
quelle