Введение
В этом практическом занятии мы сосредоточимся исключительно на команде docker run и её параметрах. Эта команда — одна из основ работы с Docker: с её помощью можно создавать и запускать контейнеры с заданной конфигурацией.
Освоив параметры docker run, вы сможете лучше управлять приложениями в контейнерах и эффективнее развертывать контейнеры Docker.
Мы рассмотрим широкий набор параметров: для задания имени контейнера, запуска в фоновом режиме, сопоставления портов, подключения томов, настройки переменных окружения, ограничения ресурсов и не только.
Некоторые параметры вам уже могут быть знакомы, а другие вы встретите впервые.
Запуск Docker и присвоение имени контейнеру
На этом этапе вы познакомитесь с основами команды docker run и научитесь задавать имя контейнеру.
Сначала запустите простой контейнер Nginx:
docker run nginx
Эта команда запускает контейнер Nginx в интерактивном режиме, на переднем плане. В терминале появится поток журналов: поскольку контейнер работает на переднем плане, его журналы выводятся прямо в терминал.
Чтобы остановить контейнер, нажмите Ctrl+C. Остановка может занять несколько секунд — это нормально: Docker дает контейнеру время на корректное завершение работы.
Теперь запустите контейнер в фоновом режиме и задайте ему имя:
docker run -d --name my-nginx nginx
Разберем команду:
docker run— основная команда для запуска контейнера.-d— параметр, который запускает контейнер в фоновом режиме. Вы не увидите его вывод в терминале.--name my-nginx— задает контейнеру имяmy-nginx. Если имя не указать, Docker присвоит контейнеру случайное имя.nginx— имя образа, из которого создается контейнер.
После выполнения команды вы увидите длинную строку символов — это идентификатор контейнера. Docker запустил контейнер в фоновом режиме.
Если появится сообщение об ошибке, что имя уже используется, значит, контейнер с таким именем уже существует. Выберите другое имя или удалите существующий контейнер. Как это сделать, вы узнаете в следующих практических занятиях.
Сопоставление портов
На этом этапе вы используете параметр -p команды docker run, чтобы сопоставить порт контейнера с портом хоста. Это необходимо, чтобы обращаться с хост-компьютера к службам, работающим внутри контейнера.
Запустите контейнер Nginx с сопоставлением портов:
docker run -d --name nginx-mapped -p 8080:80 nginx
Разберем новую часть команды:
-p 8080:80— сопоставляет порт 8080 на хосте с портом 80 в контейнере. Формат всегда такой:host_port:container_port.
По умолчанию Nginx работает в контейнере на порту 80. Сопоставив этот порт с портом 8080 на хосте, вы сможете открыть Nginx в браузере по адресу localhost:8080.
Проверьте, что открывается приветственная страница Nginx. Для этого выполните команду curl, которая отправляет HTTP-запросы из командной строки:
curl --retry 5 --retry-all-errors --retry-delay 1 http://localhost:8080
В ответе должно появиться HTML-содержимое приветственной страницы Nginx. Если утилита curl не установлена, установите ее командой:
sudo apt-get update && sudo apt-get install -y curl
Если страница по-прежнему недоступна, проверьте следующее:
- Убедитесь, что контейнер запущен:
docker ps | grep nginx-mapped - Проверьте, сопоставлен ли порт:
docker port nginx-mapped - Если вы используете облачный сервер, убедитесь, что брандмауэр разрешает трафик на порт 8080.
Подключение тома
На этом этапе вы используете параметр -v команды docker run, чтобы подключить том и обмениваться данными между хостом и контейнером. Это удобно для сохранения данных и передачи контейнеру файлов конфигурации.
Сначала создайте на хосте каталог и HTML-файл:
mkdir -p ~/project/nginx-data
echo "<html><body><h1>Hello from mounted volume</h1></body></html>" > ~/project/nginx-data/index.html
Эти команды выполняют следующие действия:
- Создают каталог
nginx-dataвнутри каталогаprojectв вашей домашней директории. - Создают в этом каталоге простой 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— имя образа, из которого создается контейнер.
Проверьте, что Nginx отправляет вашу страницу:
curl --retry 5 --retry-all-errors --retry-delay 1 http://localhost:8081
В ответе должно появиться содержимое созданного вами HTML-файла: «Hello from mounted volume!».
Если вместо него вы не видите ожидаемое содержимое, проверьте следующее:
- Убедитесь, что файл
~/project/nginx-data/index.htmlсуществует на хосте. - Проверьте, что контейнер запущен:
docker ps | grep nginx-volume - Посмотрите, нет ли ошибок в журналах Nginx:
docker logs nginx-volume
Такой способ подключения каталога с хоста к контейнеру называется bind mount. Это простой способ обмениваться файлами между хостом и контейнером. Запомните несколько важных особенностей:
- Путь к каталогу на хосте должен быть абсолютным.
- Если такого каталога на хосте нет, Docker создаст его автоматически.
- Изменения файлов в подключенном каталоге сразу видны и на хосте, и в контейнере.
- Учитывайте права доступа: по умолчанию контейнер работает от имени 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_.
В выводе должны появиться обе заданные переменные окружения.
Если переменные не отображаются, проверьте следующее:
- Работает ли контейнер? Проверьте командой
docker ps | grep nginx-env - Правильно ли указаны имена переменных окружения в команде
docker run?
Ограничения ресурсов
На этом этапе вы зададите ограничения ресурсов контейнера с помощью параметров docker run. Это особенно важно для управления производительностью и стабильностью хоста, если на нем работает несколько контейнеров.
Запустите контейнер с ограничениями по памяти и процессору:
docker run -d --name nginx-limited --memory 256m --cpus 0.5 nginx
Разберем новые параметры:
--memory 256m— ограничивает объем памяти контейнера до 256 мегабайт. Букваmозначает мегабайты. Также можно использоватьgдля гигабайтов.--cpus 0.5— ограничивает использование процессора половиной одного ядра.
Эти ограничения не позволяют контейнеру использовать больше заданных ресурсов и помогают избежать ситуации, когда один контейнер занимает все ресурсы хоста.
Проверьте, что ограничения применены правильно:
docker inspect -f '{{.HostConfig.Memory}}' nginx-limited
docker inspect -f '{{.HostConfig.NanoCpus}}' nginx-limited
Первая команда должна вывести 268435456 (256 МБ в байтах), а вторая — 500000000 (0,5 процессорного ядра в наноединицах).
Если вы видите другие значения, проверьте команду docker run и убедитесь, что правильно задали ограничения.
Примечание. Слишком низкие ограничения ресурсов могут ухудшить работу контейнера или даже привести к его аварийному завершению. Если возникли проблемы, попробуйте увеличить эти ограничения.
Настройка сети
На этом этапе вы используете параметр --network команды docker run, чтобы подключить контейнер к сети. Это удобно для обмена данными между контейнерами и изоляции групп контейнеров.
Сначала создайте пользовательскую bridge-сеть:
docker network create my-custom-network
Команда создаст bridge-сеть с именем my-custom-network. В Docker сети типа bridge встречаются чаще всего.
Теперь запустите контейнер и подключите его к этой сети:
docker run -d --name nginx-networked --network my-custom-network nginx
Параметр --network my-custom-network подключает контейнер к созданной вами сети.
Контейнеры в одной сети могут взаимодействовать друг с другом, используя имена контейнеров в качестве имен хостов. Так удобно соединять службы.
Если появится ошибка о том, что сеть не существует, убедитесь, что вы правильно создали ее командой docker network create.
Политики перезапуска
На этом этапе вы используете параметр --restart команды docker run, чтобы задать политику перезапуска контейнера. Это помогает поддерживать работу контейнеров после сбоя или перезапуска демона Docker.
Запустите контейнер с политикой перезапуска:
docker run -d --name nginx-restart --restart unless-stopped nginx
Параметр --restart unless-stopped задает политику unless-stopped: контейнер будет перезапускаться автоматически, пока пользователь явно его не остановит.
Другие варианты политики перезапуска:
no— значение по умолчанию. Контейнер не перезапускается автоматически.on-failure— контейнер перезапускается, только если завершился с ненулевым кодом возврата.always— контейнер всегда перезапускается независимо от кода завершения.
Проверьте заданную политику перезапуска:
docker inspect -f '{{.HostConfig.RestartPolicy.Name}}' nginx-restart
Команда должна вывести unless-stopped.
Если вывод отличается от ожидаемого, проверьте команду docker run и убедитесь, что правильно задали политику перезапуска.
Рабочий каталог и команда
На этом этапе вы узнаете, как задать рабочий каталог внутри контейнера и выполнить собственные команды при его запуске.
Параметр -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— задает контейнеру имяnginx-custom.-w /app— задает/appв качестве рабочего каталога внутри контейнера.nginx— имя используемого образа.sh -c "..."— выполняет команду оболочки.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 и ее параметры. Мы рассмотрели:
- Основы запуска контейнера и присвоения ему имени
- Сопоставление портов для доступа с хоста к службам контейнера
- Подключение томов для обмена данными между хостом и контейнером
- Настройку переменных окружения для конфигурации контейнера
- Ограничение ресурсов, используемых контейнером
- Настройку сети для обмена данными между контейнерами
- Политики перезапуска для обеспечения надежной работы контейнера
- Задание рабочего каталога и команды, выполняемой при запуске контейнера
Параметры команды docker run дают гибкие возможности для настройки контейнеров Docker и управления ими. Освоив эти параметры, вы сможете создавать более сложные конфигурации контейнеров, адаптированные к конкретным задачам. Вы сможете управлять взаимодействием контейнеров с хостом, объемом потребляемых ресурсов и поведением контейнеров в разных ситуациях.



