Shell interactif utilisant Docker Compose

271

Existe-t-il un moyen de démarrer un shell interactif dans un conteneur à l'aide de Docker Compose uniquement? J'ai essayé quelque chose comme ça, dans mon docker-compose.yml:

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

Lorsque je démarre ce conteneur en utilisant docker-compose up, il se ferme immédiatement. Existe-t-il des indicateurs que je peux ajouter à la commande entrypoint, ou en tant qu'option supplémentaire à myapp, pour démarrer en tant que shell interactif?

Je sais qu'il existe des options de commande native docker pour y parvenir, juste curieux de savoir s'il est possible d'utiliser uniquement Docker Compose également.

drubb
la source
Ce n'est pas censé fonctionner. Par exemple, si vous avez plusieurs images avec /bin/shpoint d' entrée dans votre fichier de composition, que doit-il faire?
Xiongbing Jin
2
Hmh, pourquoi ne pas simplement lancer plusieurs obus? Par exemple, un shell dans un conteneur mysql pour travailler avec mysql cli, et un shell dans un conteneur de sauvegarde pour exécuter des commandes de sauvegarde?
drubb
1
qu'en est-il docker-compose run myapp?
ivoba
1
@ibova Le problème, docker-compose run myappc'est qu'il n'exposera pas les ports. Il faut donc utiliser docker-compose run --service-ports myappmais ce n'est pas très pratique.
The Fool
entrypoint: /bin/shdevrait êtreentrypoint: "/bin/sh"
codentaire

Réponses:

342

Vous devez inclure les lignes suivantes dans votre docker-compose.yml:

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

Le premier correspond à -iin docker runet le second à -t.

Leon Carlo Valencia
la source
3
c'est stdin_openle lien manquant, pour me fournir simplement le comportement attendu lorsque je me connecte à l'un de mes conteneurs qui exécute déjà un shell.
Charney Kaye
9
@TheFool, même j'ai le même problème. Il vaut mieux courirdocker-compose run <service_name>
Aswath K
4
Où exactement cela est-il ajouté? À l'intérieur du service?
problemofficer
Cela semble être la meilleure réponse à la question de l'OP .. car le problème est que le conteneur se ferme immédiatement dans le cas contraire, donc l'utilisation d'un shell docker execdessus ne fonctionnera pas.
RoyM
Cela me donne une erreur sur Windows:colorama\win32.py, line 152, in SetConsoleTitle: ctypes.ArgumentError: ‘ValueError’: embedded null character
cowlinator
210

La manière canonique d'obtenir un shell interactif avec docker-compose est d'utiliser: docker-compose run --rm myapp

Vous pouvez définir stdin_open: true, tty: true, cependant, cela ne vous donnera pas un shell approprié up, car les journaux sont diffusés à partir de tous les conteneurs.

Vous pouvez aussi utiliser

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

pour obtenir un shell sur un conteneur en cours d'exécution.

dnephin
la source
16
Notez que vous devez ajouter --service-portssi vous exposez des ports (par exemple pour un serveur Web)
epelc
9
J'ai mis à jour ma réponse pour fournir plus d'informations et ajouter l' --rmindicateur afin que le conteneur soit supprimé. La réponse de @ lynx0123 n'est pas correcte. Vous n'obtiendrez pas de shell interactif si vous exécutez docker-compose up.
dnephin
2
Pour que cela fonctionne avec Docker pour Windows, j'avais besoin de docker-compose v. 1.9.0 (voir problème Github et PR ). À partir du 19/12/16, cela n'est livré qu'avec les versions bêta de Docker pour Windows. Fonctionne ensuite docker-compose run. Vous souhaiterez également ajouter command: /bin/bashà docker-compose.yml.
Joseph238
5
Cela devrait être la meilleure réponse. C'est ce que je cherchais quand je suis venu ici.
mkasberg
8
docker-compose up -d && docker attach <nom_conteneur>
Aaron McMillin
58

Dans l'exemple de démarrage officiel ( https://docs.docker.com/compose/gettingstarted/ ) avec ce qui suit docker-compose.yml:

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

Après avoir commencé avec docker-compose up, vous pouvez facilement décortiquer dans votre redisconteneur ou votre webconteneur avec:

docker-compose exec redis sh
docker-compose exec web sh 
argile
la source
44

docker-compose run myapp sh devrait faire l'affaire.

Il y a une certaine confusion avec up/ run, mais les docker-compose rundocuments ont une bonne explication: https://docs.docker.com/compose/reference/run

Alex Povar
la source
1
Merci beaucoup. Juste un petit ajout pour clarifier. docker-compose run [nom-de-votre-service-defini-dans-docker-compose.yml] [sh ou bash].
theeranitp
23

En utilisant docker-compose, j'ai trouvé que la façon la plus simple de le faire est de faire un docker ps -a(après avoir démarré mes conteneurs avec docker-compose up) et d'obtenir l'ID du conteneur dans lequel je veux avoir un shell interactif (appelons-le xyz123).

Ensuite, c'est une question simple à exécuter docker exec -ti xyz123 /bin/bash

et le tour est joué, un shell interactif.

David Hersey
la source
1
Je ne sais pas pourquoi cela a été rejeté - c'est un excellent moyen d'obtenir le débogage en cas de problème, et j'ai utilisé cette méthode avec succès, comme, dans la minute qui suit la lecture de cette solution.
ericmjl
4
@ericmjl Parce que c'est un processus en deux étapes où la question posée spécifiquement sur l'utilisation des fonctionnalités de docker-compose, et était déjà indiquée dans l'autre réponse
OneCricketeer
19

Si quelqu'un du futur erre aussi ici:

docker-compose exec container_name sh

ou

docker-compose exec container_name bash

ou vous pouvez exécuter des lignes simples comme

docker-compose exec container_name php -v

C'est après que vous ayez déjà vos conteneurs opérationnels

Eleonora Ivanova
la source
2

Vous pouvez le faire docker-compose exec SERVICE_NAME shsur la ligne de commande. Le SERVICE_NAMEest défini dans votre docker-compose.yml. Par exemple,

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

Ce SERVICE_NAMEserait "gardien de zoo".

Yu N.
la source
2

Cette question est très intéressante pour moi car j'ai des problèmes, lorsque j'exécute le conteneur une fois l'exécution terminée, quittez immédiatement et j'ai corrigé avec -it:

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

Et quand je dois l'automatiser avec Docker, composez:

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

Cela rend l'astuce: stdin_open: true, tty: true

Ceci est un projet généré avec create-react-app

Dockerfile.dev il semble que:

FROM node:alpine

WORKDIR '/app'

COPY package.json .
RUN npm install

COPY . . 

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

J'espère que cet exemple aidera d'autres à exécuter un frontend (réagir dans l'exemple) dans le conteneur docker.

Carnaru Valentin
la source
0

Si le ymlest appelé, docker-compose.ymlil peut être lancé avec un simple $ docker-compose up. L'attachement correspondant d'un terminal peut être simple (considérons que le ymla spécifié un service appelé myservice):

$ docker-compose exec myservice sh

Cependant, si vous utilisez un ymlnom de fichier différent , tel que docker-compose-mycompose.yml, il doit être lancé à l'aide de $ docker-compose -f docker-compose-mycompose.yml up. Pour attacher un terminal interactif, vous devez également spécifier le ymlfichier, tout comme:

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