Вопрос или проблема
Я хочу исследовать образ Docker, созданный кем-то другим, с указанными как entrypoint, так и cmd, например:
ENTRYPOINT ["/usr/sbin/apache2ctl"]
CMD ["-D", "FOREGROUND"]
В настоящее время я делаю:
docker run --interactive --tty --entrypoint=/bin/bash $IMAGE --login
Есть ли способ переопределить CMD, чтобы он был пустым (так что мне не нужно использовать “–login”)?
Вы можете просто зайти через docker run -it --entrypoint=/bin/bash $IMAGE -i
(вы запустите новый контейнер из образа и получите оболочку bash в интерактивном режиме), затем выполните команду entrypoint в этом контейнере.
Затем вы сможете исследовать работающий контейнер в том состоянии, в котором он должен работать.
ИЗМЕНЕНИЕ: Начиная с Docker 1.3, вы можете использовать exec
, чтобы запустить процесс в работающем контейнере. Запустите свой контейнер так, как вы обычно делаете, а затем войдите в него, выполнив:
docker exec -it $CONTAINER_ID /bin/bash
Предполагая, что bash установлен, вы получите доступ к оболочке работающего контейнера.
Смотрите: https://docs.docker.com/engine/containers/run/#overriding-image-defaults
Соответствующая часть:
CMD (Команда или параметры по умолчанию) Вспомните необязательную COMMAND в командной строке Docker:
$ docker run [OPTIONS] IMAGE[:TAG] [COMMAND] [ARG...]
Эта команда является необязательной, потому что человек, создавший IMAGE, мог уже предоставить команду по умолчанию, используя Dockerfile CMD. В качестве оператора (человека, запускающего контейнер из образа) вы можете переопределить эту CMD, просто указав новую COMMAND.
Если образ также указывает ENTRYPOINT, то CMD или COMMAND добавляются в качестве аргументов к ENTRYPOINT.
Таким образом, чтобы сделать то, что вы хотите, вам нужно только указать cmd и переопределить с помощью /bin/bash
. Не совсем “пустой”, но это выполняет задачу на 99%.
Для тех, кто приходит сюда, чтобы переопределить entrypoint И команду, чтобы передать другую команду, например, запустить bash вместо скрипта entrypoint, а затем выполнить какую-то другую команду с параметрами (это не было ясно мне из других ответов):
docker run [другие параметры] --entrypoint '/bin/sh' $IMAGE -c 'npm link gulp gulp-sass gulp-sourcemaps'
-c 'npm link ...'
— это параметр для /bin/sh
, так что здесь вы можете передать любую команду, которую хотите выполнить в контейнере. /bin/sh
предназначен для образов alpine, /bin/bash
скорее всего для других образов.
Ответ или решение
Для того чтобы переопределить команду CMD при запуске образа Docker, в ситуации, когда задан как ENTRYPOINT, так и CMD, существует несколько методов. Давайте рассмотрим, как это сделать, основываясь на вашем примере с Apache.
Понимание структуры Docker
Образ Docker может содержать инструкции ENTRYPOINT
и CMD
, которые задают точки доступа и стандартные команды или параметры, запускаемые при старте контейнера. Например:
ENTRYPOINT ["/usr/sbin/apache2ctl"]
CMD ["-D", "FOREGROUND"]
В данном случае, при запуске контейнера стандартно будет выполняться команда apache2ctl -D FOREGROUND
.
Как переопределить CMD
Если ваша цель — удалить стандартный CMD, чтобы не выполнять его, можно воспользоваться следующими методами:
1. Переопределение CMD при запуске контейнера
Docker позволяет переопределять CMD
непосредственно из командной строки. Для этого вы можете указать любую команду после имени образа. Например, чтобы запустить контейнер с оболочкой bash, вы можете выполнить команду:
docker run --interactive --tty --entrypoint=/bin/bash $IMAGE
Этот подход исключает дополнительные аргументы CMD, задаваемые в образе, и позволяет вам работать в шелле контейнера.
2. Переопределение CMD на пустую строку
Если вы хотите переопределить CMD на "пустое" значение, но это требует больше манипуляций. Это возможно с использованием параметра sh -c
, чтобы оставить CMD фактически пустым. Команда будет выглядеть следующим образом:
docker run --interactive --tty --entrypoint=/bin/bash $IMAGE -c ''
Однако, стоит отметить, что это может не всегда привести к ожидаемым результатам, в зависимости от того, как прописаны ENTRYPOINT и CMD.
3. Запуск контейнера, в котором уже запущен процесс
Если контейнер уже запущен, вы можете использовать команду docker exec
для доступа к нему:
docker exec -it $CONTAINER_ID /bin/bash
Таким образом, вы получите доступ к работающему контейнеру, начиная с того состояния, в котором он должен был быть запущен.
Пример использования
Если необходима дополнительная гибкость в использовании команд, можно добавить больше параметров, например, для запуска другого процесса:
docker run --entrypoint='/bin/sh' $IMAGE -c 'npm link gulp gulp-sass gulp-sourcemaps'
Каждое из этих решений предоставляет вам возможность обойти стандартное поведение образа, что позволяет вам глубже исследовать и настраивать окружение контейнера.
Заключение
Для тестирования и работы с образами Docker важно понимать, как работать с ENTRYPOINT
и CMD
. Опции переопределения команд позволяют вам гибко взаимодействовать с контейнерами в соответствии с вашими нуждами. Обратите внимание, что изучение документации Docker, например, документации по переопределению команд, значительно поможет разобраться со спецификой работы с образами.