Параметры команды Docker Run

DockerBeginner
Практиковаться сейчас

Введение

В этой лабораторной работе мы сосредоточимся исключительно на команде docker run и её многочисленных параметрах. Команда docker run является фундаментальной операцией в Docker, позволяющей создавать и запускать контейнеры с заданными конфигурациями.

Освоив параметры этой команды, вы получите полный контроль над своими контейнеризированными приложениями, что значительно расширит ваши возможности по эффективному развертыванию и управлению контейнерами Docker.

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

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

Основы Docker Run и именование контейнеров

Начнем с основ docker run и разберемся, как давать имена нашим контейнерам.

Для начала запустите базовый контейнер Nginx:

docker run nginx

Эта команда запускает контейнер Nginx на переднем плане (foreground). Вы увидите поток логов прямо в терминале. Это происходит потому, что контейнер привязан к текущей сессии терминала.

Чтобы остановить этот контейнер, нажмите Ctrl+C. Вы заметите, что остановка занимает несколько секунд — это нормально, так как Docker дает контейнеру время на корректное завершение работы (graceful shutdown).

Теперь запустим его в фоновом режиме и присвоим ему имя:

docker run -d --name my-nginx nginx

Разберем эту команду по частям:

  • docker run: основная команда для запуска контейнера.
  • -d: этот флаг запускает контейнер в фоновом режиме (detached mode). Вы не увидите вывода логов в терминале.
  • --name my-nginx: назначает контейнеру имя "my-nginx". Если не указать имя, Docker присвоит ему случайное название.
  • nginx: название образа, на основе которого создается контейнер.

После выполнения этой команды вы увидите длинную строку символов. Это идентификатор контейнера (ID). Docker запустил контейнер в фоновом режиме.

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

Проброс портов

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

Запустите контейнер Nginx с пробросом портов:

docker run -d --name nginx-mapped -p 8080:80 nginx

Разберем новые части этой команды:

  • -p 8080:80: сопоставляет порт 8080 вашего хоста с портом 80 внутри контейнера. Формат записи всегда такой: порт_хоста:порт_контейнера.

Nginx по умолчанию работает на порту 80 внутри контейнера. Пробросив его на порт 8080 нашего хоста, мы можем получить к нему доступ, открыв localhost:8080 в браузере.

Теперь проверим доступность приветственной страницы Nginx. Мы воспользуемся командой curl, которая позволяет делать HTTP-запросы из командной строки:

curl http://localhost:8080

Вы должны увидеть HTML-код приветственной страницы Nginx. Если у вас не установлен curl, вы можете установить его командой:

sudo apt-get update && sudo apt-get install -y curl

Если страница все еще недоступна, проверьте следующее:

  1. Убедитесь, что контейнер запущен: docker ps | grep nginx-mapped
  2. Проверьте, действительно ли порт проброшен: docker port nginx-mapped
  3. Если вы используете облачный сервер, убедитесь, что брандмауэр (firewall) разрешает входящий трафик на порт 8080.

Монтирование томов

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

Для начала создадим простую структуру каталогов на хосте:

mkdir -p ~/project/nginx-data
echo "<html><body><h1>Hello from mounted volume</h1></body></html>" > ~/project/nginx-data/index.html

Эти команды выполняют следующее:

  1. Создают новую директорию nginx-data внутри папки project в вашем домашнем каталоге.
  2. Создают простой HTML-файл index.html внутри этой директории.

Теперь запустим контейнер Nginx и примонтируем эту директорию:

docker run -d --name nginx-volume -p 8081:80 -v ~/project/nginx-data:/usr/share/nginx/html nginx

Разберем детали команды:

  • docker run: команда запуска нового контейнера.
  • -d: запуск в фоновом режиме.
  • --name nginx-volume: присвоение имени "nginx-volume".
  • -p 8081:80: проброс порта 8081 хоста на порт 80 контейнера.
  • -v ~/project/nginx-data:/usr/share/nginx/html: монтирует папку nginx-data с хоста в папку /usr/share/nginx/html внутри контейнера. Именно там Nginx ищет файлы для отображения.
  • nginx: используемый образ.

Теперь проверим, отображается ли наша пользовательская страница:

curl http://localhost:8081

Вы должны увидеть содержимое вашего HTML-файла: "Hello from mounted volume!"

Если вы не видите этот текст, проверьте:

  1. Существует ли файл ~/project/nginx-data/index.html на вашей хост-системе.
  2. Запущен ли контейнер: docker ps | grep nginx-volume
  3. Проверьте логи Nginx на наличие ошибок: docker logs nginx-volume

Этот метод монтирования директории хоста в контейнер называется "bind mount". Это прямой способ обмена файлами. Вот несколько важных моментов:

  1. Путь к директории на хосте должен быть абсолютным.
  2. Если директория на хосте не существует, Docker создаст её автоматически.
  3. Любые изменения файлов в этой директории (как на хосте, так и в контейнере) будут мгновенно видны обеим сторонам.
  4. Будьте внимательны с правами доступа: контейнер по умолчанию работает от имени root, что может привести к созданию файлов, которые обычный пользователь хоста не сможет изменить.

Используя этот метод, мы избегаем ошибок типа "not a directory", так как монтируем целую папку. Это дает гибкость при добавлении или изменении файлов без необходимости пересоздавать контейнер.

Переменные окружения

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

Запустите контейнер с переменными окружения:

docker run -d --name nginx-env -e NGINX_HOST=mywebsite.com -e NGINX_PORT=80 nginx

Разберем новые элементы:

  • -e NGINX_HOST=mywebsite.com: устанавливает переменную окружения NGINX_HOST со значением mywebsite.com.
  • -e NGINX_PORT=80: устанавливает еще одну переменную NGINX_PORT со значением 80.

Переменные окружения — это пары "ключ-значение", к которым могут обращаться процессы внутри контейнера. Многие образы Docker специально спроектированы так, чтобы их можно было настраивать через такие переменные.

Вы можете проверить наличие переменных окружения:

docker exec nginx-env env | grep NGINX_

Эта команда делает следующее:

  • docker exec nginx-env: дает команду Docker выполнить действие в уже запущенном контейнере nginx-env.
  • env: команда, которая выводит список всех переменных окружения.
  • | grep NGINX_: фильтрует вывод, оставляя только строки, содержащие "NGINX_".

Вы должны увидеть обе заданные переменные.

Если переменные не отображаются, проверьте:

  1. Запущен ли контейнер? Проверьте через docker ps | grep nginx-env
  2. Правильно ли вы написали имена переменных в команде docker run?

Ограничение ресурсов

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

Запустите контейнер с ограничениями по памяти и процессору:

docker run -d --name nginx-limited --memory 256m --cpus 0.5 nginx

Разберем новые параметры:

  • --memory 256m: ограничивает объем оперативной памяти для контейнера до 256 мегабайт. Буква 'm' означает мегабайты, также можно использовать 'g' для гигабайт.
  • --cpus 0.5: ограничивает использование процессора максимум половиной одного ядра CPU.

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

Проверим, правильно ли применились ограничения:

docker inspect -f '{{.HostConfig.Memory}}' nginx-limited
docker inspect -f '{{.HostConfig.NanoCpus}}' nginx-limited

Первая команда должна вывести 268435456 (256 МБ в байтах), а вторая — 500000000 (0.5 CPU в нано-единицах).

Если вы видите другие значения, перепроверьте команду docker run.

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

Сетевые настройки

Параметр --network в docker run позволяет подключать контейнер к определенной сети. Это необходимо для взаимодействия между контейнерами и их изоляции.

Сначала создадим пользовательскую сеть типа bridge:

docker network create my-custom-network

Эта команда создает новую сеть с именем my-custom-network. Сети типа bridge являются наиболее распространенными в Docker.

Теперь запустим контейнер, подключенный к этой сети:

docker run -d --name nginx-networked --network my-custom-network nginx

Опция --network my-custom-network подключает контейнер к только что созданной сети.

Контейнеры в одной сети могут общаться друг с другом, используя свои имена в качестве имен хостов (hostnames). Это значительно упрощает связывание различных сервисов.

Если вы получили ошибку о том, что сеть не существует, убедитесь, что вы правильно выполнили команду docker network create.

Политики перезапуска

Параметр --restart в docker run позволяет задать политику автоматического перезапуска контейнера. Это гарантирует, что ваши сервисы останутся в рабочем состоянии даже после сбоя или перезагрузки демона Docker.

Запустите контейнер с политикой перезапуска:

docker run -d --name nginx-restart --restart unless-stopped nginx

Опция --restart unless-stopped означает, что контейнер будет автоматически перезапускаться всегда, за исключением случаев, когда он был остановлен пользователем вручную.

Другие политики перезапуска:

  • no: значение по умолчанию. Контейнер не перезапускается автоматически.
  • on-failure: перезапуск только в случае, если контейнер завершил работу с ошибкой (ненулевой код выхода).
  • always: всегда перезапускать контейнер независимо от причины остановки.

Проверим установленную политику:

docker inspect -f '{{.HostConfig.RestartPolicy.Name}}' nginx-restart

Вывод должен быть unless-stopped.

Если результат отличается, проверьте правильность написания параметра в команде запуска.

Рабочая директория и команды

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

Параметр -w в docker run устанавливает рабочую директорию, а саму команду можно указать сразу после имени образа.

Объединим эти концепции:

docker run -d --name nginx-custom -w /app nginx sh -c "mkdir -p /app && touch newfile.txt && nginx -g 'daemon off;'"

Разберем эту сложную команду:

  • -d: запуск в фоновом режиме.
  • --name nginx-custom: имя контейнера.
  • -w /app: устанавливает рабочую директорию внутри контейнера на /app.
  • nginx: используемый образ.
  • sh -c "...": запускает оболочку shell для выполнения строки команд.
    • mkdir -p /app: создает директорию /app, если она не существует.
    • &&: оператор "и" (выполнить следующую команду, если предыдущая успешна).
    • touch newfile.txt: создает пустой файл newfile.txt.
    • nginx -g 'daemon off;': запускает Nginx на переднем плане, чтобы контейнер не завершил работу сразу после создания файла.

Теперь проверим, что контейнер работает и файл создан:

docker ps | grep nginx-custom
docker exec nginx-custom ls -l /app/newfile.txt

Первая команда подтвердит статус контейнера, а вторая выведет информацию о созданном файле newfile.txt в директории /app внутри контейнера.

Резюме

В этой лабораторной работе мы детально изучили команду docker run, разобрав её ключевые параметры и опции. Мы научились:

  1. Запускать и именовать контейнеры.
  2. Пробрасывать порты для доступа к сервисам извне.
  3. Монтировать тома для обмена данными между хостом и контейнером.
  4. Использовать переменные окружения для гибкой настройки.
  5. Ограничивать ресурсы (CPU и RAM) для стабильности системы.
  6. Настраивать сети для взаимодействия контейнеров.
  7. Применять политики перезапуска для обеспечения отказоустойчивости.
  8. Управлять рабочей директорией и выполнять пользовательские команды при старте.

Эти параметры docker run являются мощными инструментами для конфигурирования и управления вашими Docker-контейнерами. Освоение этих опций позволит вам создавать более сложные и адаптированные под конкретные задачи окружения, контролируя взаимодействие контейнеров с хост-системой и их поведение в различных ситуациях.