Interaktive Shell mit Docker Compose

271

Gibt es eine Möglichkeit, eine interaktive Shell in einem Container nur mit Docker Compose zu starten? Ich habe so etwas in meiner docker-compose.yml versucht:

myapp:
  image: alpine:latest
  entrypoint: /bin/sh

Wenn ich diesen Container mit Docker-Compose starte, wird er sofort beendet. Gibt es Flags, die ich dem Befehl entrypoint oder als zusätzliche Option zu myapp hinzufügen kann, um als interaktive Shell zu starten?

Ich weiß, dass es native Docker-Befehlsoptionen gibt, um dies zu erreichen. Ich bin nur neugierig, ob es auch möglich ist, nur Docker Compose zu verwenden.

drubb
quelle
Das soll nicht funktionieren. Wenn Sie beispielsweise mehrere Bilder mit /bin/shEinstiegspunkt in Ihrer Erstellungsdatei haben, was sollte dies tun?
Xiongbing Jin
2
Hmh, warum nicht einfach mehrere Muscheln starten? Zum Beispiel eine Shell in einen MySQL-Container, um mit MySQL-CLI zu arbeiten, und eine Shell in einen Backup-Container, um Backup-Befehle auszuführen?
Drubb
1
was ist mit docker-compose run myapp?
ivoba
1
@ibova Das Problem ist, docker-compose run myappdass die Ports nicht verfügbar gemacht werden. Man muss es also benutzen, docker-compose run --service-ports myappaber es ist immer noch nicht sehr praktisch.
Der Narr
entrypoint: /bin/shsollteentrypoint: "/bin/sh"
codentary

Antworten:

341

Sie müssen die folgenden Zeilen in Ihre docker-compose.yml aufnehmen:

version: "3"
services:
  app:
    image: app:1.2.3
    stdin_open: true # docker run -i
    tty: true        # docker run -t

Der erste entspricht -iin docker runund der zweite entspricht -t.

Leon Carlo Valencia
quelle
3
Dies stdin_openist das fehlende Glied, um mir einfach das erwartete Verhalten zu liefern, wenn ich an einen meiner Container anhänge, auf dem bereits eine Shell ausgeführt wird.
Charney Kaye
9
@ TheFool, auch ich habe das gleiche Problem. Es ist besser zu laufendocker-compose run <service_name>
Aswath K
4
Wo genau wird das hinzugefügt? Innerhalb des Dienstes?
problemofficer
Dies scheint die beste Antwort auf die Frage des OP zu sein. Da das Problem darin besteht, dass der Container ansonsten sofort beendet docker execwird, funktioniert es nicht , eine Shell darauf zu verwenden.
RoyM
Dies gibt mir einen Fehler unter Windows:colorama\win32.py, line 152, in SetConsoleTitle: ctypes.ArgumentError: ‘ValueError’: embedded null character
Cowlinator
210

Der kanonische Weg, um eine interaktive Shell mit Docker-Compose zu erhalten, besteht darin, Folgendes zu verwenden: docker-compose run --rm myapp

Sie können festlegen stdin_open: true, tty: true, dass Sie dadurch jedoch keine ordnungsgemäße Shell erhalten up, da Protokolle von allen Containern gestreamt werden.

Sie können auch verwenden

docker exec -ti <container name> /bin/bash

eine Shell auf einen laufenden Container zu bekommen.

Dnephin
quelle
16
Beachten Sie, dass Sie hinzufügen müssen, --service-portswenn Sie Ports verfügbar machen (dh für einen Webserver)
epelc
9
Ich habe meine Antwort aktualisiert, um weitere Informationen bereitzustellen und das --rmFlag hinzuzufügen, damit der Container entfernt wird. Die Antwort von @ lynx0123 ist nicht korrekt. Sie erhalten keine interaktive Shell, wenn Sie ausführen docker-compose up.
Dnephin
2
Damit dies mit Docker für Windows funktioniert, benötigte ich Docker-Compose Version 1.9.0 (siehe Github- Problem und PR ). Ab dem 19.12.16 wird dies nur mit Beta-Versionen von Docker für Windows ausgeliefert. Dann docker-compose runfunktioniert. Sie möchten auch command: /bin/bashdocker-compose.yml hinzufügen.
Joseph238
5
Dies sollte die beste Antwort sein. Das habe ich gesucht, als ich hierher kam.
Mkasberg
8
Docker-Compose-Up & Docker anhängen <Container_Name>
Aaron McMillin
58

Im offiziellen Einstiegsbeispiel ( https://docs.docker.com/compose/gettingstarted/ ) mit folgenden Angabendocker-compose.yml :

version: '3'
services:
  web:
    build: .
    ports:
     - "5000:5000"
  redis:
    image: "redis:alpine"

Nachdem Sie mit begonnen haben docker-compose up, können Sie entweder in Ihren redisContainer oder in Ihren Container schälen webmit:

docker-compose exec redis sh
docker-compose exec web sh 
Lehm
quelle
44

docker-compose run myapp sh sollte den Deal machen.

Es gibt einige Verwechslungen mit up/ run, aber die docker-compose runDokumente haben eine gute Erklärung: https://docs.docker.com/compose/reference/run

Alex Povar
quelle
1
Ich danke dir sehr. Nur ein wenig hinzufügen, um zu klären. docker-compose run [Ihr-Dienstname-definiert-in-docker-compose.yml] [sh oder bash].
Theeranitp
23

Mit Docker-Compose habe ich festgestellt, dass der einfachste Weg, dies zu tun, darin besteht, a docker ps -a(nachdem ich meine Container mit docker-compose upgestartet habe) und die ID des Containers abzurufen, in dem ich eine interaktive Shell haben möchte (nennen wir es xyz123).

Dann ist es einfach auszuführen docker exec -ti xyz123 /bin/bash

und voila, eine interaktive Shell.

David Hersey
quelle
1
Ich bin mir nicht sicher, warum dies abgelehnt wurde - es ist eine großartige Möglichkeit, das Debuggen zu starten, falls etwas schief geht, und ich habe diese Methode mit Erfolg angewendet, etwa innerhalb einer Minute nach dem Lesen dieser Lösung.
Ericmjl
4
@ericmjl Da es sich um einen zweistufigen Prozess handelt, bei dem die Frage speziell zur Verwendung von Docker-Compose-Funktionen gestellt wurde und bereits in der anderen Antwort angegeben wurde
OneCricketeer
19

Wenn jemand aus der Zukunft auch hierher wandert:

docker-compose exec container_name sh

oder

docker-compose exec container_name bash

oder Sie können einzelne Zeilen wie ausführen

docker-compose exec container_name php -v

Das ist, nachdem Sie Ihre Container bereits in Betrieb genommen haben

Eleonora Ivanova
quelle
2

Sie können docker-compose exec SERVICE_NAME shin der Befehlszeile tun . Das SERVICE_NAMEist in Ihrem definiert docker-compose.yml. Beispielsweise,

services:
    zookeeper:
        image: wurstmeister/zookeeper
        ports:
          - "2181:2181"

Das SERVICE_NAMEwäre "Tierpfleger".

Yu N.
quelle
2

Diese Frage ist für mich sehr interessant, da ich Probleme habe, wenn ich den Container nach Abschluss der Ausführung sofort beende und mit -it behebe:

docker run -it -p 3000:3000 -v /app/node_modules -v $(pwd):/app <your_container_id>

Und wenn ich es mit Docker Compose automatisieren muss:

version: '3'
services:
    frontend:
        stdin_open: true
        tty: true
        build: 
            context: .
            dockerfile: Dockerfile.dev
        ports: 
            - "3000:3000"
        volumes: 
            - /app/node_modules
            - .:/app

Dies macht den Trick: stdin_open: true, tty: true

Dies ist ein Projekt, das mit der Create-React-App generiert wurde

Dockerfile.dev sieht so aus:

FROM node:alpine

WORKDIR '/app'

COPY package.json .
RUN npm install

COPY . . 

CMD ["npm", "run", "start"]

Hoffe, dieses Beispiel hilft anderen, ein Frontend (reagieren Sie im Beispiel) in den Docker-Container auszuführen.

Carnaru Valentin
quelle
0

Wenn das ymlaufgerufen wird docker-compose.yml, kann es mit einem einfachen gestartet werden $ docker-compose up. Der entsprechende Anhang eines Terminals kann einfach sein (bedenken Sie, dass der ymleinen angerufenen Dienst angegeben hat myservice):

$ docker-compose exec myservice sh

Wenn Sie jedoch einen anderen ymlDateinamen verwenden, z. B. docker-compose-mycompose.yml, sollte dieser mit gestartet werden $ docker-compose -f docker-compose-mycompose.yml up. Um ein interaktives Terminal anzuhängen, müssen Sie auch die ymlDatei angeben , genau wie:

$ docker-compose -f docker-compose-mycompose.yml exec myservice sh
Cleber Jorge Amaral
quelle