Как запустить команду для уже существующего контейнера 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. Я не могу победить.

21 ответ

Решение

В октябре 2014 года команда Docker представила 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) будет запущен в фоновом режиме, и контейнер не остановится немедленно.

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

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

Так что твой новый run команда:

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

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

docker exec -it CONTAINER_ID /bin/bash

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

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

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

docker start <container-name/ID>

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

docker stop <container-name/ID>

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

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

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

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

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

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

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

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

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

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

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

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

Хочу заметить, что главный ответ немного вводит в заблуждение.

Проблема с выполнением docker runзаключается в том, что каждый раз создается новый контейнер. Однако бывают случаи, когда мы хотели бы пересмотреть старые контейнеры или не занимать место новыми контейнерами.

(Дано clever_bardeen это имя созданного контейнера...)

В случае OP убедитесь, что сначала запущен образ докера, выполнив следующую команду:

docker start clever_bardeen

Затем запустите контейнер докера, используя следующую команду:

docker exec -it clever_bardeen /bin/bash

Это комбинированный ответ, который я составил, используя ответ 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"

Это все.

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

Необходимо удалить -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.

Обычно я использую это:

    docker exec -it my-container-name bash

для постоянного взаимодействия с работающим контейнером.

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

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

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

Для Mac:

$ docker exec -it <container-name> sh

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

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

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

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

не забудьте изменить <CONTAINER_ID/CONTAINER_NAME>

# docker exec -d container_id command 

Пример:

# docker exec -d xcdefrdtt service jira stop 

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

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

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

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

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

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

Быстрый способ возобновить работу и получить доступ к последнему закрытому контейнеру:

docker start -a -i `docker ps -q -l`

Простое решение, которое решило аналогичную проблему для меня:

      docker run --interactive --tty <name_of_image>
Другие вопросы по тегам