Интерактивная оболочка с использованием Docker Compose

272

Есть ли способ запустить интерактивную оболочку в контейнере, используя только Docker Compose? Я пробовал что-то вроде этого, в моем docker-compose.yml:

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

Когда я запускаю этот контейнер с помощью docker-compose, он сразу же закрывается. Есть ли какие-либо флаги, которые я могу добавить к команде entrypoint или как дополнительную опцию для myapp, чтобы запускать как интерактивную оболочку?

Я знаю, что для этого есть собственные опции команды docker, просто любопытно, если это возможно, используя только Docker Compose.

drubb
источник
Это не должно работать. Например, если у вас есть несколько изображений с /bin/shточкой входа в вашем файле компоновки, что он должен делать?
Сюнбин Джин
2
Хм, почему бы просто не запустить несколько оболочек? Например, оболочка в контейнер mysql для работы с mysql cli, а оболочка в контейнер резервных копий для запуска команд резервного копирования?
drubb
1
о чем docker-compose run myapp?
ivoba
1
@ibova Проблема в docker-compose run myappтом, что он не будет выставлять порты. Таким образом, вы должны использовать, docker-compose run --service-ports myappно все же это не очень удобно.
Дурак
entrypoint: /bin/shдолжно бытьentrypoint: "/bin/sh"
добровольно

Ответы:

343

Вам нужно включить следующие строки в ваш docker-compose.yml:

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

Первый соответствует -iв, docker runа второй -t.

Леон Карло Валенсия
источник
3
это stdin_openнедостающее звено, просто для предоставления мне ожидаемого поведения, когда я присоединяюсь к одному из моих контейнеров, на котором уже запущена оболочка.
Чарни Кей
9
@TheFool, Даже у меня такая же проблема. Лучше бежатьdocker-compose run <service_name>
Aswath K
4
Где именно это добавлено? Внутри службы?
problemofficer
Похоже, что это лучший ответ на вопрос ОП ... поскольку проблема заключается в том, что контейнер сразу же завершает работу, поэтому использование оболочки docker execдля него не сработает.
RoyM
Это дает мне ошибку на Windows:colorama\win32.py, line 152, in SetConsoleTitle: ctypes.ArgumentError: ‘ValueError’: embedded null character
Cowlinator
210

Канонический способ получить интерактивную оболочку с помощью docker-compose - это использовать: docker-compose run --rm myapp

Вы можете установить stdin_open: true, tty: true, однако, что на самом деле не даст вам надлежащую оболочку up, потому что журналы передаются из всех контейнеров.

Вы также можете использовать

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

получить снаряд на работающем контейнере.

dnephin
источник
16
Обратите внимание, что вам нужно добавить, --service-portsесли вы выставите какие-либо порты (например, для веб-сервера)
epelc
9
Я обновил свой ответ, чтобы предоставить больше информации и добавить --rmфлаг, чтобы контейнер был удален. Ответ @ lynx0123 не верный. Вы не получите интерактивную оболочку, если вы запустите docker-compose up.
апреля
2
Чтобы заставить это работать с использованием Docker для Windows, мне нужно было docker-compose v. 1.9.0 (см. Выпуск Github и PR ). По состоянию на 19.12.16 он поставляется только с бета-версиями Docker для Windows. Потом docker-compose runработает. Вы также хотите добавить command: /bin/bashв docker-compose.yml.
Joseph238
5
Это должен быть главный ответ. Это то, что я искал, когда пришел сюда.
МКАСБЕРГ
8
docker-compose up -d && docker attach <
Аарон Макмиллин
58

В официальном примере начала работы ( https://docs.docker.com/compose/gettingstarted/ ) со следующим docker-compose.yml:

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

После того, как вы начнете с этого docker-compose up, вы можете легко заложить в ваш redisконтейнер или webконтейнер с помощью:

docker-compose exec redis sh
docker-compose exec web sh 
глина
источник
44

docker-compose run myapp sh должен сделать сделку.

Существует некоторая путаница с up/ run, но у docker-compose runдокументов есть отличное объяснение: https://docs.docker.com/compose/reference/run

Алекс Повар
источник
1
Огромное спасибо. Просто немного добавить, чтобы уточнить. docker-compose run [ваше-имя-службы-определено-в-докере-compose.yml] [sh или bash].
theeranitp
23

Используя docker-compose, я нашел, что самый простой способ сделать это - сделать docker ps -a(после запуска моих контейнеров с docker-compose up) и получить идентификатор контейнера, в котором я хочу иметь интерактивную оболочку (назовем это xyz123).

Тогда это просто выполнить docker exec -ti xyz123 /bin/bash

и вуаля, интерактивная оболочка.

Дэвид Херси
источник
1
Не уверен, почему за это проголосовали - это отличный способ отладки на случай, если что-то пойдет не так, и я успешно использовал этот метод, например, через минуту после прочтения этого решения.
ericmjl
4
@ericmjl Потому что это двухэтапный процесс, когда вопрос, заданный специально об использовании возможностей docker-compose, был уже
задан
19

Если кто-то из будущего также бродит здесь:

docker-compose exec container_name sh

или

docker-compose exec container_name bash

или вы можете запустить отдельные строки, такие как

docker-compose exec container_name php -v

То есть после того, как ваши контейнеры уже запущены и работают

Элеонора Иванова
источник
2

Вы можете сделать docker-compose exec SERVICE_NAME shв командной строке. Это SERVICE_NAMEопределено в вашем docker-compose.yml. Например,

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

Это SERVICE_NAMEбудет "зоопарк".

Ю. Н.
источник
2

Этот вопрос очень интересен для меня, потому что у меня есть проблемы, когда я запускаю контейнер после того, как выполнение завершается, немедленно завершается и я исправляю с помощью -it:

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

И когда я должен автоматизировать это с помощью docker compose:

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

Это делает трюк: stdin_open: true, tty: true

Это проект, созданный с помощью create-реагировать-приложение

Dockerfile.dev это выглядит так:

FROM node:alpine

WORKDIR '/app'

COPY package.json .
RUN npm install

COPY . . 

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

Надеюсь, что этот пример поможет другим запустить внешний интерфейс (например, реагировать) в контейнер докера.

Карнару Валентин
источник
0

Если ymlвызывается, docker-compose.ymlон может быть запущен с простым $ docker-compose up. Соответствующее присоединение терминала может быть простым (учтите, что ymlон указал вызываемую службу myservice):

$ docker-compose exec myservice sh

Однако, если вы используете другое ymlимя файла, например docker-compose-mycompose.yml, его следует запустить с помощью $ docker-compose -f docker-compose-mycompose.yml up. Чтобы подключить интерактивный терминал, вы также должны указать ymlфайл, например:

$ docker-compose -f docker-compose-mycompose.yml exec myservice sh
Клебер Хорхе Амарал
источник