Shell interactivo con Docker Compose


271

¿Hay alguna manera de iniciar un shell interactivo en un contenedor usando Docker Compose solamente? He intentado algo como esto, en mi docker-compose.yml:

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

Cuando comienzo este contenedor usando docker-compose, sale inmediatamente. ¿Hay alguna bandera que pueda agregar al comando de punto de entrada, o como una opción adicional para myapp, para comenzar como shell interactivo?

Sé que hay opciones de comando de Docker nativas para lograr esto, solo tengo curiosidad por saber si es posible usar solo Docker Compose también.


Esto no se supone que funcione. Por ejemplo, si tiene varias imágenes con punto de /bin/shentrada en su archivo de redacción, ¿qué debe hacer?
Xiongbing Jin

2
Hmh, ¿por qué no simplemente iniciar múltiples proyectiles? Por ejemplo, ¿un shell en un contenedor mysql para trabajar con mysql cli y un shell en un contenedor de respaldo para ejecutar comandos de respaldo?
drubb

1
¿qué pasa docker-compose run myapp?
ivoba

1
@ibova El problema es docker-compose run myappque no expondrá los puertos. Así que tienes que usarlo, docker-compose run --service-ports myapppero aún así no es muy conveniente.
The Fool

entrypoint: /bin/shdebería serentrypoint: "/bin/sh"
codentary

Respuestas:


342

Debe incluir las siguientes líneas en su docker-compose.yml:

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

El primero corresponde a -iin docker runy el segundo a -t.


3
ese stdin_openes el enlace que falta, simplemente por proporcionarme el comportamiento esperado cuando lo adjunto a uno de mis contenedores que ya está ejecutando un shell.
Charney Kaye

9
@ TheFool, incluso tengo el mismo problema. Es mejor correrdocker-compose run <service_name>
Aswath K

44
¿Dónde se agrega exactamente esto? Dentro del servicio?
problemofficer

Esta parece ser la mejor respuesta a la pregunta del OP ... ya que el problema es que el contenedor se cierra inmediatamente de lo contrario, por lo que obtener un shell que lo use docker execno funcionará.
RoyM

Esto me da un error en Windows:colorama\win32.py, line 152, in SetConsoleTitle: ctypes.ArgumentError: ‘ValueError’: embedded null character
cowlinator

210

La forma canónica de obtener un shell interactivo con docker-compose es usar: docker-compose run --rm myapp

Puede configurar stdin_open: true, tty: true, sin embargo, eso en realidad no le dará un caparazón adecuado up, porque los registros se transmiten desde todos los contenedores.

También puedes usar

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

para obtener un shell en un contenedor en ejecución.


16
Tenga en cuenta que debe agregar --service-portssi expone algún puerto (es decir, para un servidor web)
epelc

9
He actualizado mi respuesta para proporcionar más información y agregar la --rmbandera para que se elimine el contenedor. La respuesta de @ lynx0123 no es correcta. No obtendrá un shell interactivo si ejecuta docker-compose up.
dnephin

2
Para que esto funcione con Docker para Windows, necesitaba docker-compose v. 1.9.0 (vea el problema de Github y PR ). A partir del 19/12/16, esto solo se entrega con versiones beta de Docker para Windows. Entonces docker-compose runfunciona. También querrás agregar command: /bin/basha docker-compose.yml.
Joseph238

55
Esta debería ser la mejor respuesta. Esto es lo que estaba buscando cuando vine aquí.
mkasberg

8
docker-compose up -d && docker attach <container_name>
Aaron McMillin

58

En el ejemplo oficial de inicio ( https://docs.docker.com/compose/gettingstarted/ ) con lo siguiente docker-compose.yml:

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

Después de comenzar con esto docker-compose up, puede cambiar fácilmente a su rediscontenedor o su webcontenedor con:

docker-compose exec redis sh
docker-compose exec web sh 

44

docker-compose run myapp sh Debería hacer el trato.

Existe cierta confusión con up/ run, pero los docker-compose rundocumentos tienen una gran explicación: https://docs.docker.com/compose/reference/run


1
Muchas gracias. Solo un pequeño complemento para aclarar. docker-compose ejecute [su-nombre-servicio-definido-en-docker-compose.yml] [sh o bash].
theeranitp

23

Usando docker-compose, encontré que la forma más fácil de hacer esto es hacer un docker ps -a(después de comenzar con mis contenedores docker-compose up) y obtener la ID del contenedor en el que quiero tener un shell interactivo (llamémoslo xyz123).

Entonces es un asunto simple de ejecutar docker exec -ti xyz123 /bin/bash

y voila, un caparazón interactivo.


1
No estoy seguro de por qué esto fue rechazado: es una excelente manera de depurar en caso de que algo salga mal, y usé este método con éxito, como, un minuto después de leer esta solución.
ericmjl

44
@ericmjl Debido a que es un proceso de dos pasos en el que la pregunta se hizo específicamente sobre el uso de las funciones de
compilación

19

Si alguien del futuro también deambula por aquí:

docker-compose exec container_name sh

o

docker-compose exec container_name bash

o puedes correr líneas simples como

docker-compose exec container_name php -v

Eso es después de que ya tienes tus contenedores en funcionamiento


2

Puedes hacerlo docker-compose exec SERVICE_NAME shen la línea de comando. El SERVICE_NAMEse define en su docker-compose.yml. Por ejemplo,

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

El SERVICE_NAMEsería "cuidador del zoológico".


2

Esta pregunta es muy interesante para mí porque tengo problemas, cuando ejecuto el contenedor después de que finaliza la ejecución, salgo inmediatamente y lo solucioné con -it:

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

Y cuando debo automatizarlo con Docker compose:

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

Esto hace el truco: stdin_open: true, tty: true

Este es un proyecto generado con create-react-app

Dockerfile.dev se ve esto que:

FROM node:alpine

WORKDIR '/app'

COPY package.json .
RUN npm install

COPY . . 

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

Espero que este ejemplo ayude a otros a ejecutar una interfaz (reaccionar en el ejemplo) en el contenedor docker.


0

Si ymlse llama, docker-compose.ymlse puede iniciar con un simple $ docker-compose up. La conexión correspondiente de un terminal puede ser simplemente (considere que ymlha especificado un servicio llamado myservice):

$ docker-compose exec myservice sh

Sin embargo, si está usando un ymlnombre de archivo diferente , por ejemplo docker-compose-mycompose.yml, debe iniciarse usando $ docker-compose -f docker-compose-mycompose.yml up. Para adjuntar un terminal interactivo, también debe especificar el ymlarchivo, como:

$ docker-compose -f docker-compose-mycompose.yml exec myservice sh
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.