Как выполнить команду в уже существующем контейнере Docker?

Я создал контейнер с -d, чтобы он не был интерактивным.

docker run -d shykes/pybuilder bin/bash

Я вижу, что контейнер вышел:

CONTAINER ID        IMAGE                     COMMAND             CREATED             STATUS                      PORTS               NAMES
d6c45e8cc5f0        shykes/pybuilder:latest   "bin/bash"          41 minutes ago      Exited (0) 2 seconds ago                        clever_bardeen

Теперь я хотел бы запустить случайные команды на машине и выйти. Просто чтобы получить ответ.

Я попытался запустить машину. Я попытался установить. Я думал, что могу вызвать run с контейнером, но это, похоже, не разрешено. Использование start просто запускается, а затем существует быстро.

Я хочу вернуться в интерактивный режим после выхода.

Я пробовал:

docker attach d6c45e8cc5f0

Но я получаю:

2014/10/01 22:33:34 You cannot attach to a stopped container, start it first

Но если я начну, он все равно выйдет. Поймать 22. Я не могу победить.

Ответ 1

В октябре 2014 года команда представила команду docker exec: https://docs.docker.com/engine/reference/commandline/exec/

Итак, теперь вы можете запускать любую команду в запущенном контейнере, просто зная его идентификатор (или имя):

docker exec -it <container_id_or_name> echo "Hello from container!"

Обратите внимание, что команда exec работает только на уже запущенном контейнере. Если контейнер в настоящий момент остановлен, вам нужно сначала запустить его с помощью следующей команды:

docker run -it -d shykes/pybuilder /bin/bash

Самое главное здесь - опция -d, которая обозначает detached. Это означает, что команда, которую вы первоначально предоставили контейнеру (/bin/bash), будет запущена в фоновом режиме, и контейнер не будет немедленно останавливаться.

Ответ 2

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

  • -i Держите STDIN открытым, даже если он не подключен.
  • -t Выделить псевдотематику.

Итак, ваша новая команда run:

docker run -it -d shykes/pybuilder bin/bash

Если вы хотите подключиться к уже запущенному контейнеру:

docker exec -it CONTAINER_ID /bin/bash

В этих примерах /bin/bash используется как команда.

Ответ 3

Поэтому я думаю, что ответ проще, чем многие вводящие в заблуждение ответы выше.

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

docker start <container-name/ID>

Чтобы остановить работающий контейнер

docker stop <container-name/ID>

Затем войти в интерактивную оболочку контейнера

docker exec -it <container-name/ID> bash

Чтобы запустить существующий контейнер и присоединить к нему одной командой

docker start -ai <container-name/ID>

Осторожно, это остановит контейнер при выходе. Но в целом вам нужно запустить контейнер, прикрепить и остановить его после того, как вы закончите.

Ответ 4

Чтобы расширить ответ на katrmr, если контейнер остановлен и не может быть запущен из-за ошибки, вам нужно будет commit его на изображение. Затем вы можете запустить bash в новом изображении:

docker commit [CONTAINER_ID] temporary_image
docker run --entrypoint=bash -it temporary_image

Ответ 5

Некоторые из ответов здесь вводят в заблуждение, поскольку они относятся к работающим контейнерам, а не к остановке.

Sven Dowideit объяснил на форуме Docker, что контейнеры привязаны к их процессу (и Docker не может изменить процесс остановленного контейнера, по-видимому, по крайней мере по своей внутренней структуре: https://github.com/docker/docker/issues/1437). Таким образом, в основном единственным вариантом является commit контейнер для изображения и run он с другой командой.

См. https://forums.docker.com/t/run-command-in-stopped-container/343
(Я считаю, что подход "ENTRYPOINT с аргументами" тоже не сработает, поскольку вы все равно не сможете изменить аргументы в остановленном контейнере.)

Ответ 6

Мне пришлось использовать bash -c для выполнения моей команды: docker exec -it CONTAINER_ID bash -c "mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql mysql"

Ответ 7

Создание контейнера и отправка ему команд один за другим:

docker create --name=my_new_container -it ubuntu
docker start my_new_container
// ps -a says 'Up X seconds'
docker exec my_new_container /path/to/my/command
// ps -a still says 'Up X+Y seconds'
docker exec my_new_container /path/to/another/command

Ответ 8

Это комбинированный ответ, который я составил с помощью ответа CDR LDN выше, и ответ, который я нашел здесь.

Следующий пример запускает контейнер Arch Linux из образа, а затем устанавливает git в этом контейнере с помощью инструмента pacman:

sudo docker run -it -d archlinux /bin/bash
sudo docker ps -l
sudo docker exec -it [container_ID] script /dev/null -c "pacman -S git --noconfirm"

Вот и все.

Ответ 9

Предполагая, что изображение использует точку входа по умолчанию /bin/sh -c, запуск /bin/bash немедленно выйдет в режиме демона (-d). Если вы хотите, чтобы этот контейнер запускал интерактивную оболочку, используйте -it вместо -d. Если вы хотите выполнить произвольные команды в контейнере, обычно выполняющем другой процесс, вы можете попробовать nsenter или nsinit. Посмотрите https://blog.codecentric.de/en/2014/07/enter-docker-container/ для деталей.

Ответ 10

К сожалению, для достижения этой цели невозможно переопределить ENTRYPOINT с аргументами с docker run --entrypoint.

Примечание. Вы можете переопределить настройку ENTRYPOINT с помощью --entrypoint, но это может только установить двоичный код для exec (no sh -c будет использоваться).

Ответ 11

Передайте команду на стандартный ввод

Необходимо удалить -t чтобы он работал:

echo 'touch myfile' | sudo docker exec -i CONTAINER_NAME bash

Это может быть более удобным, чем использование параметров CLI.

Протестировано с:

sudo docker run --name ub16 -it ubuntu:16.04 bash

затем на другой оболочке:

echo 'touch myfile' | sudo docker exec -i ub16 bash

Затем на первой оболочке:

ls -l myfile

Протестировано на Docker 1.13.1, хост Ubuntu 16.04.

Ответ 12

Если вы пытаетесь запустить скрипт оболочки, вам нужно запустить его как bash.

docker exec -it containerid bash -c /path/to/your/script.sh

Ответ 13

Простой ответ: начните и присоедините в одно и то же время. В этом случае вы делаете именно то, что вы просили.

docker start <CONTAINER_ID/CONTAINER_NAME> && docker attach <CONTAINER_ID/CONTAINER_NAME> 

обязательно измените <CONTAINER_ID/CONTAINER_NAME>

Ответ 14

Для Mac:

$ docker exec -it <container-name> sh

если вы хотите подключиться как пользователь root:

$ docker exec -u 0 -it <container-name> sh

Ответ 15

Я сделал это для моего контейнера красного узла и решил мою проблему:

NODEREDNAME=mynodered
# Create a new node red container
docker run -it -p 1880:1880 -v "$(pwd)/data":/data --name $NODEREDNAME -d nodered/node-red-docker

# Open a shell in the container (THAT ANSWERS THE QUESTION)
docker exec -it $NODEREDNAME bash -c "cd /data & npm install node-red-node-mongodb"

# Restart the container to load the new nodes
docker stop $NODEREDNAME
docker start $NODEREDNAME

Ответ 16

# docker exec -d container_id command 

Пример:

# docker exec -d xcdefrdtt service jira stop 

Ответ 17

Я использую контейнер Windows, и мне нужно искать в контейнере Docker файлы и папки, созданные и скопированные.

Для этого я использовал следующую команду docker entrypoint, чтобы запустить командную строку внутри контейнера или присоединить к контейнеру.

ENTRYPOINT ["C:\\Windows\\System32\\cmd.exe", "-D", "FOREGROUND"]

Это помогло мне как присоединить командную строку к контейнеру, так и сохранить контейнер в рабочем состоянии. :)