Как выполнить команду в уже существующем контейнере 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"]
Это помогло мне как присоединить командную строку к контейнеру, так и сохранить контейнер в рабочем состоянии. :)