Запуск контейнера Docker и команда docker run - Академия Selectel

Запуск контейнера Docker и команда docker run

Разбираемся, как изолировать приложения и их зависимости в контейнерах, а также какие параметры важны при работе с docker run.

Как работают контейнеры в Docker

Контейнер — это своего рода коробка, в которой находится все необходимое для работы приложения: код, библиотеки, файлы и настройки. Эта коробка полностью изолирована от остальной системы, поэтому приложение внутри нее работает одинаково на любом компьютере — будь то ваш личный ноутбук или сервер в облаке.

Но в чем разница между контейнером и виртуальной машиной? Виртуальные машины эмулируют целую операционную систему со своим ядром, тогда как контейнеры используют ядро уже установленной ОС. Это делает их:

  • более быстрыми — контейнеры запускаются почти мгновенно, так как не требуют загрузки отдельной ОС;
  • менее ресурсоемкими — несколько контейнеров на одном сервере могут совместно использовать одно ядро;
  • легче переносимыми — контейнеры можно быстро упаковать в образ и развернуть на любой системе.

Как создать контейнер Docker

Для начала работы с контейнером его необходимо создать. Контейнер создается на основе образа, в котором уже есть все необходимое для работы приложения. Образ формируется на основе Dockerfile — инструкции, где описаны все этапы его сборки:

  • базовый образ,
  • установка зависимостей,
  • копирование файлов,
  • запуск команд и настройка параметров среды.

Образы хранятся в специальном репозитории, например, Docker Hub — это большая библиотека готовых решений.

Скачать образ можно с помощью команды:


    docker pull <имя_образа>

Например, чтобы загрузить образ с Nginx, выполните:


    docker pull nginx

После этого образ появится в локальном хранилище и будет готов к использованию.

Проверить список загруженных образов можно командой:


    docker images

Для создания контейнера из загруженного образа используйте команду:


    docker create <имя_образа>

Эта команда создаст контейнер, но не запустит его. Он будет находиться в неактивном состоянии до момента запуска.

Просмотреть список созданных контейнеров можно с помощью команды:


    docker ps -a

Как запустить контейнер

Запустить контейнер можно двумя способами.

Первый — запустить ранее созданный контейнер. Если контейнер уже был создан, но еще не запущен, используйте команду:


    docker start <container_ID>

Идентификатор контейнера можно узнать с помощью команды docker ps -a.

Второй — создать и запустить контейнер одной командой. Вместо docker create и docker start можно сразу использовать команду:


    docker run <имя_образа>

По умолчанию контейнер запускается в интерактивном режиме, и если процесс внутри него завершится (например, Nginx остановится), сам контейнер тоже выключится. Чтобы запустить его в фоновом режиме, используют параметр -d (о нем поговорим в следующем разделе).

Синтаксис команды docker run

Команда docker run не только создает и запускает контейнер, но и позволяет настроить его поведение с помощью множества опций.

Общий синтаксис:


    docker run [опции] <имя_образа> [аргументы]

Где:

  • [опции] — параметры, которые определяют, как будет работать контейнер;
  • <имя_образа> — образ, на основе которого создается контейнер;
  • [аргументы] — дополнительные команды, передаваемые внутрь контейнера.

Наиболее популярные опции

Запуск в фоновом режиме (-d)

По умолчанию контейнер работает в активном режиме и завершает работу, как только завершается его основной процесс. Чтобы контейнер оставался активным в фоне, существует флаг -d:


    docker run -d nginx

Интерактивный режим (-it)

Если контейнер требует ввода команд, его можно запустить в интерактивном режиме:


    docker run -it ubuntu bash

В этом случае откроется терминал внутри контейнера.

Автоматическое удаление контейнера (—rm)

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


    docker run --rm ubuntu echo "Hello, Docker!"

После выполнения команды контейнер удалится.

Задание имени контейнера (—name)

Задать собственное название Docker-контейнеру вместо автоматически присваемого можно командой:


    docker run --name my_nginx nginx

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

Допускается ограничение использования контейнером ядер процессора (—cpus) и оперативной памяти (—memory):


    docker run --memory=512m --cpus=1 nginx

Этот контейнер сможет использовать не более 512 МБ оперативной памяти и одного ядра процессора.

Ознакомиться с полным списком опций команды docker run вы можете в официальной документации.

Подключение к контейнеру

Иногда требуется зайти внутрь работающего контейнера, чтобы выполнить команды, проверить настройки или устранить проблемы. В Docker есть несколько способов подключения к контейнеру:

  • С помощью docker exec

docker exec позволяет выполнить команду внутри работающего контейнера.

Чтобы запустить интерактивную консоль внутри контейнера, выполните:


    docker exec -it <container_ID> bash

Если контейнер работает на Ubuntu или другой системе с bash, это запустит оболочку.

В контейнерах на Alpine Linux или других минималистичных дистрибутивах bash может отсутствовать. В таком случае попробуйте использовать sh:


    docker exec -it <container_ID> sh

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


    docker exec <container_ID> ls /
  • С помощью docker attach

Если контейнер запущен в интерактивном режиме, можно подключиться к его основному процессу с помощью команды docker attach:


    docker attach <container_ID>

При этом вы получите прямой доступ к терминалу контейнера, как если бы запускали его с docker run -it.

Важно

Если закрыть сессию docker attach с помощью Ctrl + C, контейнер остановится. Чтобы выйти, не прерывая работу контейнера, нажмите Ctrl + P, а затем Ctrl + Q.

Переменные окружения и изменение настроек контейнера

Передача переменных окружения при запуске контейнера

Переменные окружения можно передавать контейнеру с помощью опции -e:


    docker run -e "DB_USER=admin" -e "DB_PASS=secret" mysql

Если переменных много, удобнее использовать файл .env, чтобы не передавать их вручную в командной строке. Для этого нужно выполнить следующее.

Создать файл .env:


    DB_USER=admin
DB_PASS=secret

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


    docker run --env-file .env mysql

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

Изменение настроек работающего контейнера

Некоторые параметры можно менять даже после запуска контейнера.

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

Команда docker update позволяет изменить лимиты процессора и памяти:


    docker update --memory=512m --cpus=1 <container_ID>

Изменение переменных окружения в контейнере

Переменные окружения нельзя изменить «на лету», но можно:

  • остановить контейнер:

    docker stop <container_ID>
  • перезапустить его с новыми переменными:

    docker run -e "NEW_VAR=value" <container_ID>

Создание нового образа с измененными настройками

Если нужно сохранить внесенные в контейнер изменения, можно собрать новый образ с помощью команды docker commit.

Например, изменим что-то внутри контейнера:


    docker exec -it <container_ID> bash
apt update && apt install -y nano
exit

Теперь контейнер содержит новую установленную программу (nano), но если он будет удален, изменения пропадут. Чтобы сохранить их, создадим новый образ:


    docker commit <container_ID> my_custom_image

Теперь можно поднять Docker-контейнер из этого образа:


    docker run -it my_custom_image bash

Такой метод удобен, если нужно подготовить кастомный образ с предустановленными настройками и программами.

Монтирование папок

Когда контейнеру нужны файлы с хостовой машины, их можно примонтировать — подключить папку или отдельный файл из хоста внутрь контейнера. Это удобно для работы с конфигурациями, логами или исходным кодом. Например, если вы разрабатываете веб-приложение, можно хранить его файлы на хосте, а контейнер будет автоматически использовать их, не требуя пересборки.

Самый простой способ монтирования — опция -v, где указывается путь к папке на хосте и путь, по которому она будет доступна в контейнере:


    docker run -d -v ~/projects:/app ubuntu

Теперь файлы из ~/projects будут доступны в контейнере по пути /app. Можно сразу запускать сервер или компилировать код внутри контейнера, а изменения, внесенные снаружи, тут же применятся.

Иногда файлы нужно просто читать, но не изменять. В таком случае добавляется параметр :ro (read-only), запрещающий запись:


    docker run -d -v ~/projects:/app:ro ubuntu

Хранилища и монтирование виртуального диска

Монтирование папок подходит не во всех случаях. Иногда контейнеру нужно собственное, независимое хранилище, которое сохраняется даже после удаления контейнера. Для таких задач Docker предлагает тома (volumes).

В отличие от обычного монтирования, тома создаются и управляются самим Docker. Они хранятся в специальной директории внутри Docker (/var/lib/docker/volumes/) и не зависят от конкретного контейнера.

Создать том можно командой:


    docker volume create my_data

После этого его можно использовать в контейнере:


    docker run -d -v my_data:/data ubuntu

Данные, записанные в /data внутри контейнера, сохраняются в my_data, и даже если контейнер будет удален, этот том можно подключить к другому контейнеру.

Список всех томов можно просмотреть командой:


    docker volume ls

А если том больше не нужен, его можно удалить:


    docker volume rm my_data

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

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

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

Контейнеры в Docker изолированы друг от друга, но часто им нужно взаимодействовать. Например, веб-приложение в одном контейнере может обращаться к базе данных в другом. Для этого Docker предлагает несколько способов связи между контейнерами.

Доступ к контейнеру по порту

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

Допустим, у нас есть контейнер с веб-сервером Nginx. Чтобы сделать его доступным на порту 8080 хостовой машины, запустим:


    docker run -d -p 8080:80 nginx

Теперь, если открыть в браузере http://localhost:8080, мы увидим страницу, обслуживаемую сервером внутри контейнера на порту 80.

Также можно явно указать IP-адрес:


    docker run -d -p 192.168.1.100:8080:80 nginx

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

Связывание контейнеров через сеть

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

Создание сети и запуск контейнеров

Создадим сеть с именем my_network:


    docker network create my_network

Теперь запустим базу данных MySQL и укажем, что она должна быть в этой сети:


    docker run -d --name db --network=my_network mysql

А теперь запустим контейнер с приложением, которое должно обращаться к базе данных:


    docker run -d --name app --network=my_network my_app_image

Теперь приложение app может подключаться к MySQL, используя db как адрес сервера базы данных:


    mysql -h db -u root -p

Контейнеры внутри одной сети могут взаимодействовать друг с другом, но остаются невидимыми для остальных.

Далее приведены некоторые команды для работы с сетями.

Посмотреть список всех сетей:


    docker network ls

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


    docker network inspect my_network

Подключить контейнер к сети после запуска:


    docker network connect my_network <container_ID>

Отключить контейнер от сети:


    docker network disconnect my_network <container_ID>

Удалить сеть, если в ней нет контейнеров:


    docker network rm my_network

Хранение образов в облаке Selectel

Когда работа с контейнерами входит в повседневную практику, возникает вопрос: где хранить все эти образы? Можно загружать их в публичные реестры вроде Docker Hub, но что если нужно безопасное, быстрое и удобное частное хранилище?

Selectel Container Registry — это полностью готовый к использованию реестр, который позволяет хранить, управлять и развертывать Docker-образы без лишних сложностей. Все данные хранятся в изолированной облачной инфраструктуре Selectel, где каждый образ проходит тройную репликацию. Это означает, что даже в случае сбоя ваши контейнеры останутся в безопасности. Работать с реестром можно через удобную панель управления или с использованием инструментов автоматизации, таких как API или Terraform.

Заключение

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