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