Docker Compose hält den Container am Laufen

94

Ich möchte einen Dienst mit Docker-Compose starten und den Container am Laufen halten, damit ich seine IP-Adresse über 'Docker Inspect' erhalten kann. Der Container wird jedoch immer direkt nach dem Start verlassen.

Ich habe versucht, "Befehl: [" Schlaf "," 60 "]" und andere Dinge zur docker-compose.yml hinzuzufügen, aber wann immer ich die Zeile mit "Befehl: ..." hinzufüge, kann ich "Docker-compose up" nicht aufrufen. Ich erhalte die Meldung "Container kann nicht gestartet werden ..... Systemfehler: Ungültiges Zeichen 'k' sucht nach Wertanfang"

Ich habe auch versucht, "CMD sleep 60" und so weiter zur Docker-Datei selbst hinzuzufügen, aber diese Befehle scheinen nicht ausgeführt zu werden.

Gibt es eine einfache Möglichkeit, den Container am Leben zu erhalten oder eines meiner Probleme zu beheben?

EDIT: Hier ist die Compose-Datei, die ich ausführen möchte:

version: '2'
services:
  my-test:
    image: ubuntu
    command: bash -c "while true; do echo hello; sleep 2; done"

Es funktioniert gut Wenn ich dies mit Docker-Compose unter OS X beginne, aber wenn ich dasselbe unter Ubuntu 16.04 versuche, wird mir die obige Fehlermeldung angezeigt.

Wenn ich den Ansatz mit der Docker-Datei versuche, sieht die Docker-Datei folgendermaßen aus:

FROM ubuntu:latest
CMD ["sleep", "60"]

Welches scheint nichts zu tun

EDIT 2: Ich muss mich korrigieren, es stellte sich heraus, dass es das gleiche Problem mit der Docker-Datei und der Docker-compose.yml war: Jedes Mal, wenn ich entweder "CMD ..." zur Docker-Datei hinzufüge oder "Befehl ..." hinzufüge In der Compose-Datei erhalte ich oben einen Fehler mit dem ungültigen Zeichen. Wenn ich beide Befehle entferne, funktioniert es einwandfrei.

Dingoglotz
quelle
1
Bitte geben Sie die Datei docker-compose.yml, Dockerfile und alle Skripte an, die Sie debuggen möchten.
BMitch
Eine verwandte Diskussion für Interessierte: Entwicklungsworkflow für Server und Client mit Docker Compose?
Blong

Antworten:

118

docker-composeVerwenden Sie den folgenden Befehl, um einen Container beim Starten am Laufen zu halten

command: tail -F anything

So wird Ihre docker-compose.yml

version: '2'
services:
  my-test:
    image: ubuntu
    command: tail -F anything

Mit dem folgenden Befehl können Sie eine Shell ausführen, um in den Container zu gelangen

docker exec -i -t composename_my-test_1 bash

Wo composenamesteht der Name, docker-composeder Ihren Containern vorangestellt ist ?

Nick Settje
quelle
1
Wie stoppen Sie den Container, wenn Sie damit fertig sind? Gibt es einen Befehlstyp vom Typ Strg + C, Strg + Z. Im Moment muss ich das Terminal schließen, um zu beenden.
Mac10688
Wenn Sie sich innerhalb des Containers befinden, können Sie eingeben exit, um zu Ihrem Host-Computer zurückzukehren. Wenn Sie sich auf Ihrem Host befinden, können Sie den Container mit Docker ( docker stop composename_my-test_1) oder Docker Compose ( docker-compose stop) stoppen .
Nick Settje
2
@ Alexis.Rolland Wenn Sie bereit sind, eine neue SO-Frage zu stellen und weitere Details zu teilen, würde ich gerne einen Blick darauf werfen. Ich vermute, dass Ihr Fehler etwas mit den Interna eines Ihrer Container zu tun hat, im Gegensatz zu einem Problem mit Docker oder Ihrem Host-Betriebssystem.
Nick Settje
1
@ mac10688 Wenn Ihre angehängte Containersitzung keine Eingabeaufforderung enthält, versuchen Sie, sie mit Strg-D zu trennen
Stark
5
/dev/nullwäre besser anythingfür den Schwanz Befehl ref. stackoverflow.com/a/48732671/248616
Nam G VU
80

Sie können die ttyKonfigurationsoption verwenden.

version: '3'

services:
  app:
    image: node:8
    tty: true           # <-- This option

Hinweis: Wenn Sie Dockerfile für Image und CMDin Dockerfile verwenden, funktioniert diese Option nicht. Sie können jedoch die entrypointOption in CMDder Erstellungsdatei verwenden, mit der die Docker- Datei gelöscht wird.

Hochsprung
quelle
7
Dies funktioniert und scheint weniger hackig als tail -f /dev/null. Auf diese Weise kann ich eine containerisierte Entwicklungsumgebung mit einer über angeschlossenen Postgres-Datenbank ausführen docker-compose upund eine Shell über ein anderes Terminal ausführen docker exec.
Psiloc
1
Während derzeit nicht gut dokumentiert. Dies ist eine offizielle Option, die den gleichen Effekt wie tail -f /dev/nulloder erzielttail -f anything , siehe hier: docs.docker.com/compose/compose-file
b01
2
@ABMRuman & Psiloc, Es funktioniert nur, wenn Sie "Befehl" in der Datei docker-compose.yml nicht verwenden. Wenn Sie "Befehl" verwenden, benötigen Sie einen weiteren Hack - daher ist der Schwanz-Hack hier perfekt geeignet.
Asafel
Dies muss die beste Antwort sein, wenn Sie den Einstiegspunkt in der Docker-Datei verwenden.
DDKV587
53

Basierend auf dem Kommentar von @aanand auf GitHub vom 26. August 2015 könnte man tail -f /dev/nullin Docker-Compose verwenden, um den Container am Laufen zu halten.

Beispiel für docker-compose.yml

version: '3'
services:
  some-app:
    command: tail -f /dev/null

Warum dieser Befehl?

Der einzige Grund für die Wahl dieser Option war, dass sie auf GitHub viele Daumen hoch bekam, aber die Antwort mit der höchsten Stimme bedeutet nicht, dass es die beste Antwort ist. Der zweite Grund war pragmatisch, da Probleme aufgrund von Fristen so schnell wie möglich gelöst werden mussten.

030
quelle
2
warum genau dieser Befehl? Was macht es besser als andere? In meinem Fall hat auch das Starten einer Bash den Trick getan ...
N4ppeL
@ N4ppeL Gute Frage. Der einzige Grund, warum ich mich für diese Option entschieden habe, war, dass sie viele Daumen hoch auf Github erhalten hat, aber die Antwort mit der höchsten Stimme bedeutet nicht, dass es die beste Antwort ist. Der zweite Grund war pragmatisch, da ich das Problem aufgrund von Fristen so schnell wie möglich lösen musste.
030
17
  • Erstellen Sie eine Datei mit dem Namen docker-compose.yml
  • Fügen Sie der Datei Folgendes hinzu
version: "3"

services:
  ubuntu:
    image: ubuntu:latest
    tty: true
  • Bleiben Sie docker-compose up -dvom Terminal aus im selben Verzeichnis
  • Führen Sie docker psdiese Option aus , um die Container-ID oder den Namen abzurufen
  • Du kannst rennen docker inspect $container_id
  • Sie können den Container betreten und eine Bash-Shell zum Laufen bringen docker-compose exec ubuntu /bin/bashoderdocker-compose exec ubuntu /bin/sh
  • Wenn Sie fertig sind, stellen Sie sicher, dass Sie sich außerhalb des Containers befinden und laufen docker-compose down

Hier ist ein kleines Bash-Skript ( my-docker-shell.sh), mit dem Sie die Docker-Erstellungsdatei erstellen, den Container ausführen, sich beim Container anmelden und schließlich den Docker-Container und die Docker-Erstellungsdatei bereinigen können, wenn Sie sich abmelden.

#!/bin/bash

cat << 'EOF' > ./docker-compose.yml
---

version: "3"

services:
  ubuntu:
    image: ubuntu:latest
    command: /bin/bash
    # tty: true

...
EOF

printf "Now entering the container...\n"
docker-compose run ubuntu bash
docker-compose down

rm -v ./docker-compose.yml
GMaster
quelle
1
Dies war zwar keine wirkliche Antwort auf die Frage, aber ich fand sie äußerst wertvoll! Ich ging weiter, um globale bashrc-Funktionen für diesen Ansatz zu verwenden: gist.github.com/loopmode/4d59a4e9a0a2ffacaec2dd14db4ae8bd
loopmode
8

In der Docker-Datei können Sie den folgenden Befehl verwenden:

{CMD sleep infinity}
John
quelle
2

Wie der Kommentator sagte, müssten wir die betreffende Docker-Datei sehen, um eine vollständige Antwort zu erhalten, aber dies ist ein sehr häufiger Fehler. Ich kann so ziemlich garantieren, dass der Befehl, den Sie ausführen möchten, einen Hintergrundprozess startet. Dies ist möglicherweise der Befehl, den Sie in Nicht-Docker-Situationen ausführen würden, aber in einer Docker-Datei ist dies falsch. Wenn das, was Sie ausführen, normalerweise als Systemdienst definiert ist, können Sie beispielsweise "systemctl start" verwenden. Das würde den Prozess im Hintergrund starten, was nicht funktionieren wird. Sie müssen den Prozess im Vordergrund ausführen, damit der gesamte Prozess blockiert wird.

David M. Karr
quelle
0

Nur ein kurzer Hinweis

Ich habe ein einzelnes Bild basierend auf getestet. golangWenn ich docker-compose downhier anrufe, bekomme ich Folgendes:

version: "3.1"
...
command: tail -f /dev/null   # stopping container takes about 10 sec.
tty: true                    # stopping container takes about 2 sec.

Meine Systeminfo:

Ubuntu 18.04.4 LTS (64-bit)
Docker version 19.03.6, build 369ce74a3c
docker-compose version 1.26.0, build d4451659
Smokehill
quelle
-3

Okay, ich habe meinen Fehler gefunden. In der Docker-Datei für das zum Erstellen verwendete Image habe ich angegeben, dass das Basis-Image ubuntu: latest sein soll, aber ich habe zuvor selbst ein Image namens ubuntu erstellt, und dieses Image hat nicht funktioniert. Ich habe also nicht das ursprüngliche Ubuntu-Bild verwendet, sondern eine beschädigte Version meines eigenen Bildes, das auch Ubuntu genannt wird.

Dingoglotz
quelle