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

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

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

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