20 полезных команд для работы с Docker в Linux
Docker Container – технология, которая позволяет автоматизировать процесс развертывания и управления приложениями в среде виртуализации на уровне операционной системы. В основном Docker-контейнеры используются для СI/CD cистем.
В статье рассмотрим 20 самых часто используемых Docker команд на примере Linux-систем.
1.Проверка версии Docker
Прежде, чем приступать к работе, необходимо знать, какая версия Docker используется. Для этого достаточно ввести
2.Получение информации об инсталляции
Также важно знать основную информацию об инсталляции, что можно сделать с помощью команды « docker info»
3. Поиск Docker образов (images) на сервере регистра
Используя команду «docker search», можно запустить поиск Docker образов на сервере регистра с терминала. Предположим, необходимо найти последние Docker образы Debian.
Вывод должен выглядеть примерно так
4. Скачивание образов Docker-контейнеров
С помощью команды docker pull можно загружать образы Docker-контейнера с сервера регистра или репозитория.
Синтаксис: # docker pull
Команда docker pull всегда загружает последнюю версию образа, но есть возможность указать конкретный образ. Например, необходимо загрузить последнюю версию Debian Docker image
Загрузка конкретной версии ОС образа Docker-контейнера
Если, к примеру, мы хотим скачать образ Docker-контейнера для Ubuntu 14.04.
5. Список всех загруженных образов Docker-контейнера
Всякий раз, когда мы загружаем образы докеров с помощью команды «docker pull», сохраняются локальные образы докеров (/var/lib/docker) на Docker сервере. Можно также перечислить все загруженные образы докеров с помощью команды «docker images»,
6. Запуск Docker-контейнера
Контейнеры запускаются с помощью команды «docker run». Например, мы хотим запустить контейнер с образом Debian.
Эта команда запускает контейнер с именем «debian_container1», далее нужно установить pat rule таким образом, что если какой-либо запрос приходит к 9000 порту на хосте docker, то он будет перенаправлен на контейнер debian на 80-порту. Мы получаем консоль сразу после выполнения команды. Чтобы остановить/закрыть контейнер, нужно ввести exit либо «ctrl + p + q» (закрывает контейнер без выхода).
7. Запуск контейнера в режиме демона
8. Получение контейнерной консоли с ‘docker attach’
В приведенном выше примере у нас есть контейнер в режиме демона, мы можем использовать его консоль с помощью команды «docker attach».
Синтаксис: # docker attach
9. Список контейнеров по команде «docker ps»
Чтобы перечислить все запущенные контейнеры, необходимо помощью ввести команду «docker ps».
10. Запуск, остановка, перезагрузка и уничтожение контейнеров
Как и виртуальные машины, мы можем запускать, останавливать и перезапускать Docker-контейнеры.
Для остановки запущенного контейнера используется команда
Для запуска контейнера необходимо ввести
Команда, которая используется для перезапуска контейнера
Мы также можем уничтожить процесс Docker-контейнера
11. Удалить/переместить Docker-контейнер
Команда «docker rm» используется для перемещения или удаления контейнера. Работает только тогда, когда Docker остановлен / выключен.
Синтаксис: # docker rm
12. Удаление/перемещение образов Docker-контейнера
Подобно контейнерам мы также можем удалить или переместить образы контейнеров командой «docker rmi». Предположим, нужно удалить образ ‘Ubuntu: 14.04’
В приведенной выше команде вместо названия образа можно использовать его id.
13. Сохранить и загрузить образ контейнера Docker в/из файла tar
Предположим, что мы сделали некоторые изменения в debian-образе и хотим экспортировать его как tar-файл. Это можно сделать с помощью команды «docker save».
14. Экспорт и импорт контейнера в/из tar-архива
Контейнер можно экспортировать в файл tar с помощью команды «docker export». Синтаксис показан ниже
Например, необходимо экспортировать web_container в tar-файл.
Команда «docker import» используется для импорта контейнера из файла tar
15. Отображение истории образа Docker-контейнера
Используя команду «docker history», можно посмотреть, какие команды выполнялись при построении образа Docker-контейнера, как на примере, показанном ниже.
Синтаксис: # история докера
16. Извлечение журналов из контейнера
Можно извлекать журналы из контейнеров без входа в систему, используя команду «docker logs»
Синтаксис: docker logs
17. Статистика использования ресурсов Docker-контейнера
Для отображения ресурсов центрального процессора, памяти и сетевого ввода-вывода всех контейнеров применяется команда «docker stats»
18. Вывод IP-адреса контейнера
Информация о низкоуровневом контейнере отображается с помощью команды «docker inspect». Мы можем получить IP-адрес контейнера из вывода команды. Пример показан ниже.
19. Создание образов Docker-контейнеров с помощью Dockerfile
Команда «docker build» позволяет создать образ контейнера с помощью DockerFile.
20. Задать тег/название для образа Docker-контейнера
Команда «docker tag» используется для установки тега или названия образа Docker-контейнера в репозитории.
Синтаксис: # tag docker source_image <: tag>target_image
Предположим, мы хотим установить название образа ‘centos: 7’ как ‘MyCentOS7: v1’
Теперь образ контейнера имеет название
Подробно об использовании и настройке Docker изучайте на нашем курсе « Администрирование Docker»!
wtw24 / docker_rus.md
Шпаргалка с командами Docker














Скачайте dmg по этой ссылке:
Реестры и репозитории Docker
Pull (выгрузка из реестра) образа
Push (загрузка в реестр) образа
Первые действия с контейнерами
Первый запуск контейнера
Запуск и остановка контейнеров
Запуск остановленного контейнера
Пауза (приостановка всех процессов контейнера)
Блокировка (до остановки контейнера)
Отправка SIGKILL (завершающего сигнала)
Отправка другого сигнала
Подключение к существующему контейнеру
Получение информации о контейнерах
Информация о контейнере
Изменения в файлах или директориях файловой системы контейнера
Загрузка репозитория в tar (из файла или стандартного ввода)
Сохранение образа в tar-архив
Просмотр истории образа
Создание образа из контейнера
Push (загрузка в реестр) образа
Получение информации о сети
Подключение работающего контейнера к сети
Подключение контейнера к сети при его запуске
Отключение контейнера от сети
Удаление работающего контейнера
Удаление контейнера и его тома (volume)
Удаление всех контейнеров со статусом exited
Удаление всех остановленных контейнеров
Удаление контейнеров, остановленных более суток назад
Удаление неиспользуемых (dangling) образов
Удаление неиспользуемых (dangling) образов даже с тегами
Удаление всех образов
Удаление всех образов без тегов
Остановка и удаление всех контейнеров
Удаление неиспользуемых (dangling) томов
Удаление неиспользуемых (dangling) томов по фильтру
Удаление неиспользуемых сетей
Удаление всех неиспользуемых объектов
По умолчанию для Docker 17.06.1+ тома не удаляются. Чтобы удалились и они тоже:
Установка Docker Swarm
Прим. перев.: в Docker версий 1.12.0+ ничего дополнительно устанавливать не требуется, т.к. Docker Swarm встроен в Docker Engine в виде специального режима (Swarm mode).
Подключение рабочего узла (worker) к Swarm
Подключение управляющего узла (manager) к Swarm
Основные команды Docker
Рассмотрим систему управления контейнерами под названием Docker. Ознакомимся с базовыми принципами ее работы, а также подробно рассмотрим основные команды, необходимые для управления Docker и ее составляющими.
Краткая справка
Docker — это система управления контейнерами. Контейнеры же представляют собой логическое эволюционное продолжение виртуальных машин. Это изолированная среда для разработки и тестирования программного обеспечения.
Контейнер Docker потребляет мало ресурсов и быстро запускается, а еще его легко переносить с одного устройство на другое. Из-за этих преимуществ Docker постепенно наращивает аудиторию и превращается в некий индустриальный стандарт, которым пользуются даже крупные корпорации вроде Microsoft.
Поэтому стоит хотя бы на базовом уровне понимать, что есть Docker и как им управлять. В этом материале речь пойдет об основных командах для управления контейнерами. Будем их создавать, запускать, удалять и выполнять прочие полезные задачи, возникающие по ходу работы.
Общие сведения об основных командах Docker
Управление контейнерами и образами в Docker мало чем отличается от управления другими приложениями в терминале Linux. Принцип тот же – вводим текст и получаем результат. Сначала надо указать ключевое слово Docker, потом указать команду, которую надо выполнить, а затем объект применения команды, аргументы, опции и прочие дополнения. Типичная операция, выполняемая в Docker, выглядит вот так:
Для того чтобы обратиться к конкретному контейнеру или образу в Docker, используются их ID или названия, придуманные разработчиком. Допустим, для создания и запуска контейнера с названием new_container надо ввести:
У команд существуют опции и аргументы. Их тоже рассмотрим.
Команды для управления контейнерами
Контейнер — ключевая единица в Docker. Поэтому для начала разберемся, как управлять ей.
Далее рассмотрим каждую из команд подробнее.
container create
Из названия понятно, что речь идет о создании нового контейнера. Это основная функция Docker, с нее начинается его работа.
Синтаксис следующий: docker create [опции] название образа [дополнительные команды][аргументы].
В квадратных скобках указываются опциональные компоненты команды. Использовать их необязательно, но можно оптимизировать создаваемый контейнер под свои задачи.
К примеру, добавить ссылку на другой контейнер с помощью тега –link. Или подключить Standard Input с помощью команды в духе:
Либо создать контейнер из образа операционной системы Ubuntu, добавив подключение к терминалу и запуск bash при каждом старте Docker:
Только при наличии терминала можно управлять контейнером. Поэтому его нужно обязательно запрашивать при каждому запуске.
container start
В отличие от предыдущей команды, эта запускает контейнер, который существует, но находится в нерабочем состоянии.
Синтаксис следующий: docker start [опции] название или ID контейнера [название или ID контейнера].
Все просто – вводите команду, а потом указываете название контейнера, чтобы его запустить:
Какой из вариантов использовать, решает разработчик, ориентируясь на собственные предпочтения. Технических отличий нет.
container run
Комбинирует две вышеописанные команды. Сначала создает новый контейнер, а потом тут же его включает.
Синтаксис следующий: docker run [опции] название образа [команды][аргументы].
Практика та же, что мы видели в синтаксисе команды docker create. Разница в одном слове и доступных опциях.
Чтобы создать контейнер из образа Ubuntu и тут же взять контроль над ним через командную строку, нужно сделать запрос терминала через опции команды.
используется для подключения к контейнеру с возможностью передавать ему команды после создания.
stop
Выполняет противоположную функцию. То есть не запускает контейнер, а, наоборот, останавливает его работу.
Например, чтобы выключить контейнер с именем Timeweb, надо ввести в терминал:
Аналогично с ID. Просто имя надо заменить на уникальный код, привязанный к контейнеру. Получится что-то в духе:
restart
Последняя команда, связанная с рабочим состоянием. Она выполняет перезапуск выбранного контейнера.
Синтаксис следующий: docker restart [опции] название или ID контейнера [название или ID контейнера].
Вводите команду, а потом указываете название контейнера, чтобы его перезапустить:
container ls (или docker ps)
Обе команды выполняют одну и ту же задачу. Просто одна из них использовалась раньше, а другая появилась позднее.
docker ps отображает в терминале все запущенные контейнеры. А при добавлении опции -a в список попадают все контейнеры, созданные в системе.
В вывод команды попадают следующие параметры:
При желании можно использовать опцию volume, чтобы в терминале отображались только тома, являющиеся предпочтительным механизмом хранения данных в Docker.
logs
Одна из команд, позволяющая подробнее ознакомиться с тем, как работает Docker. Точнее одна из его запущенных единиц. Показывает, как функционирует контейнер и что в текущий момент с ним происходит. Выводит некий журнал данных.
Если указать ключ –follow и название контейнера, то в терминал в реальном времени будут выводиться логи Docker. Так можно беспрерывно наблюдать за его работой и возможным появлением ошибок.
inspect (для контейнера)
Отображает подробную информацию из Docker после обращения к конкретному контейнеру.
Синтаксис следующий: docker inspect [опции] название или ID контейнера [название или ID контейнера].
По умолчанию отображает данные в формате JSON. Можно использовать дополнительную опцию –format для смены формата данных.
rm
Команда удаления одного или нескольких контейнеров Docker, найденных на диске вашего хостинга.
Синтаксис следующий: docker rm [опции] название или ID контейнера [название или ID контейнера].
Чтобы удалить сразу несколько контейнеров с разными названиями и ID, нужно ввести:
Перед тем как удалить контейнер, нужно его выключить. Для этого надо воспользоваться командой:
Команды Docker для управления образами
Еще одна значимая единица в Docker — образы. Управление ими во многом похоже на управление контейнерами, но есть ряд отличий, которые важно учитывать. Причем как в командах, так и в опциях.
Рассмотрим каждую из них немного подробнее.
build
С помощью этой команды можно собрать образ, используя заранее подобранные параметры. Собираются одни из данных, хранящихся в файлах Dockerfile. Они находятся по определенным URL или заранее загружены в файловую систему.
Синтаксис следующий: docker image build [опции] название и адрес файла Dockerfile, из которого будет собран образ.
Например, если вы хотите собрать образ с названием Timeweb и тегом host в директории moy_repositoriy, то надо ввести в терминал:
Образами можно делиться через сервис Docker Hub. Тогда ими смогут пользоваться другие пользователи Docker, указав при сборке соотвествующий адрес. Для входа в Hub используется команда docker login (еще упомянем ее ниже).
push
После сборки образа на диске хостинга его можно разместить в Docker Hub с помощью отдельной команды.
Синтаксис следующий: docker image push [опции] название и адрес, где будет размещен образ
К примеру, чтобы отправить в хаб образ Timeweb, который мы создали ранее, нужно ввести в терминал:
Он будет размещен по адресу, указанному в команде push. После этого его смогут вытащить другие пользователи.
pull
В Docker Hub находится большой список уже готовых образов, которые были созданы вами или другими пользователями. Чтобы не собирать новые из Dockerfile, можно скачать уже имеющиеся и работать с ними. Чтобы их вытащить, нужна команда pull.
Синтаксис следующий: docker image pull [опции] название и адрес, где будет размещен образ.
К примеру, чтобы вытащить из хаба образ Timeweb, который мы создали ранее, нужно ввести в терминал:
Аналогичным образом его смогут вытаскивать другие пользователи, обращаясь к адресу и названию образа, которые вы указывали.
ls
docker image ls отвечает за отображение в терминале дополнительной информации об образах. Она показывает их список (как и в случае с контейнерами) и информацию о размере каждого.
Синтаксис следующий: docker image pull [опции][адрес репозитория:тег].
В вывод команды можно добавить другие данные с помощью отдельных ключей:
-a — увеличивает список отображаемых образов за счет отображения даже промежуточных. –digests — добавляет в вывод команды еще и дайджесты. -f — фильтрует выдачу по заранее определенным условиям. –format — меняет формат отображения данных на основе шаблона Go. –no-trunc — отключает усечение информации в терминале. -q — показывает ID вместо названий образов.
history
Показывает своего рода историю образа. Речь идет о «слоях», то есть промежуточных вариациях образа, входящих в его состав. Команда history показывает их названия, размер и дату создания.
Синтаксис следующий: docker history [опции] название образа.
Например, чтобы отобразить слои образа Timeweb, введем в терминал:
inspect (для образа)
Отображает подробную информацию из Docker после обращения к конкретному образу.
Синтаксис следующий: docker inspect [опции] название или ID контейнера [название контейнера или образа].
По умолчанию отображает данные в формате JSON. Можно использовать дополнительные опции –format для смены формата данных. Опция -s показывает размер инспектируемых элементов.
rm
Команда удаления одного или нескольких образов Docker, найденных на диске вашего хостинга.
Синтаксис следующий: docker rm [опции] название и путь до образа.
Чтобы удалить образ Timeweb из системы, нужно ввести:
Эта команда позволяет выбирать только образы, которые хранятся локально. Удаленные элементы из репозитория удалить не получится.
Чтобы удалить все локальные образы, обнаруженные в системе, введем в терминал:
images
Команда показывает все образы Docker, которые расположены на жестком диске вашего сервера (или локально).
Вывод команды docker images выглядит так:
Docker самый простой и понятный туториал. Изучаем докер, так, если бы он был игровой приставкой
Когда я наконец-то понял все тонкости работы с Docker (на полное изучение которого ушло несколько месяцев), и начал правильно применять его при разработке (а он как раз и нужен для разработки, в большей степени), то почувствовал, как будто обрёл какую-то сверхспособоность. Смотря на свой опыт изучения Докера, я понял, что мне есть что рассказать, и чем поделиться. В этой статье я постарался создать максимально понятную для новичков инструкцию, благодаря которой вы сможете полностью изучить Docker за 30 минут. Я долго думал о том, чтобы написать туториал, и наконец-то осилил эту задачу, и, как мне кажется, получилось неплохо 🙂
Эта инструкция так же подходит для тех, кто не имеет никаких знаний, или опыта работы с докером, или аналогичным программным обеспечением. Вы получите все важные знания, необходимые для работы. Статья построена по принципу от простого к сложному. В итоге статьи вы будете чётко понимать, что такое Docker, зачем нужен, как с ним работать, и применять его для разработки: создавать окружение, необходимое для создания вашего приложения.
Эта статья, в больше мере, нацелена на получение практических знаний, и только немного теории, построенной на аналогиях из жизни. Потому, эта статья имеет окрас веселья и лайтовости, в большей мере, чем супер-конкретики и теоретических нюансов.
Так же, прошу заметить, если вы используете Vagrant, и решите установить Docker, то Vagrant перестанет работать. Такая жизнь, но с этим можно смириться, тем более, субъективно, Docker круче ^^.
Что вы узнаете из этой статьи
Что такое Docker
О том, как появился Docker:
В процессе развития Докера, он вырос из масштабов внутреннего проекта, стал доступен для широких масс, и затмил своей популярностью своего родителя dotCloud, из-за чего было принято решение создать новую отдельную компанию под названием Docker Incorporated. Направление новосозданной компании было только в разработке Докера, и развитию его экосистемы.
Но, что это на самом деле значит?
Давайте на секунду забудем про Докер, и вспомним про такую ностальгическую штуку, как GameBoy Color:
Если вы помните, игры для этой приставки поставлялись в виде картриджей:
И я уверен в том, что производители видео игр пользуются успехом из-за своей простоты:
Раньше, вы, создавая приложения, к примеру на PHP, устанавливали локально PHP, MySql, возможно, NodeJs, при этом устанавливая зависимости в виде нужных расширений и библиотек. И, в случае передачи вашего скрипта какому-то знакомому, ему требовалось настраивать аналогичное окружение, аналогичных версий, иметь аналогичные расширения и конфигурацию, чтобы успешно запустить ваше приложение. Сейчас же, при использовании Докера, такой проблемы не возникнет впринципе. Теперь вам достаточно иметь установленную программу Docker, которая по одной вашей команде установит окружение, описанное для запуска вашего приложения.
Какое программное обеспечение можно запустить с помощью докера? В техническом плане, Docker чем-то похож на виртуальную машину:
Docker позволяет запустить ОС Linux в изолированной среде очень быстро, в течение нескольких минут.
Зачем использовать Docker?
Кошмар при установке ПО, с которым приходится сталкиваться. У вас когда-нибудь было такое, что вы пытаетесь установить ПО на ваш компьютер, а оно отказывается работать? Вы получаете несколько непонятных вам ошибок, из-за которых ничего не запускается. И после нескольких часов гугления, на десятой странице гугла. и на каком-то форуме, до этого неизвестного вам, вы наконец-то находите случайный комментарий, которые помогает пофиксить вашу проблему.
Docker спасёт нас. Docker, как и Game Boy приставка, берёт стандартизированные части программного обеспечения и запускает их так, как Game Boy запускал бы игру.
Как для разработчика, теперь вы не должны волноваться о том, на какой системе будет запущено ваше приложение.
Как пользователь, вам не нужно волноваться о том, что вы скачаете неподходящую версию ПО (нужного для работы программы). В Докере эта программа будет запущена в аналогичных условиях, при которых это приложение было разработано, потому, исключается факт получить какую-то новую, непредвиденную ошибку. Для пользователя все действия сводятся к принципу подключи и играй.
Установка Docker
Docker предоставляет 2 сборки:
После установки потребуется перезагрузка системы, и уже можно начинать полноценно работать с Докером.
Если вы используете Linux, то, docker-compose нужно будет устанавливать отдельно по инструкции.
Что такое Docker Image?
Как в случае с картриджами, бывают различные игры, так и Docker имеет различные образы ПО: ubuntu, php (который наследуется от оригинального образа Ubuntu), nodejs, и т.д.
Зная эту команду, скачаем образ Ubuntu 18.10 :
Это как поездка за новым картриджем в магазин, только намного быстрее :).
Теперь, для того, чтобы посмотреть список всех загруженных образов, нужно выполнить:
У вас, как и на скрине, должен появиться только что скачанный образ Ubuntu 18.10. И, как обсуждалось выше, по поводу маленького размера образов, чистый образ Ubuntu при установке из Docker-образа, весит всего 74 МБ. Не чудо ли?
Проводя аналогии, команда docker images выглядит как коллекция картриджей от приставки, которые у вас есть сейчас:
Что такое Docker контейнер?
Теперь представьте, что мы обновили нашу приставку с Game Boy на GameCube. Игры хранятся на диске, который предназначен только для чтения самого образа игры. А прочие файлы (сохранения, кеш и т.д.) сохраняются внутри самой приставки, локально.
Запуск Docker контейнера соответствует тому, что вы играете в свою Gamecube игру. Docker запускает ваш образ в своей среде, аналогично тому, как Gamecube запускает игру с диска, не модифицируя оригинальный образ, а лишь сохраняя изменения и весь прогресс в какой-то песочнице.
Для запуска контейнера существует команда:
Давайте запустим наш первый контейнер Ubuntu:
Команда echo ‘hello from ubuntu’ была выполнена внутри среды Ubuntu. Другими словами, эта команда была выполнена в контейнере ubuntu:18.10.
Теперь выполним команду для проверки списка запущенных контейнеров:
Давайте добавим немного интерактивности в наше обучение. Мы можем подключиться к консоли виртуальной ОС (Ubuntu 18.10), и выполнять любое количество команд без завершения работы контейнера, для этого, запустим команду:
Docker контейнер является полностью независимым от системы хоста, из которой он запускался. Как изолированная виртуальная машина. И в ней вы можете производить любые изменения, которые никак не повлияют на основную операционную систему.
Это аналогично тому, как, если бы вы играли в Mario Kart на приставке Gamecube, и неважно, что вы делаете в игре, вы никак не сможете изменить само ядро игры, или изменить информацию, записанную на диске.
Контейнер является полностью независимым и изолированным от основной операционной системы, аналогично виртуальной операционной системе. Вы можете вносить любые изменения внутри виртуалки, и никакие из этих изменений не повлияют на основную операционную систему.
Теперь откройте новое окно терминала (не закрывая и не отключаясь от текущего), и выполните команду docker ps
Только на этот раз вы можете увидеть, что контейнер с Ubuntu 18.10 в текущий момент запущен.
Теперь вернёмся назад к первому окну терминала (который находится внутри контейнера), и выполним:
В моём случае, CONTAINER_ID последнего контейнера = 7579c85c8b7e (у вас же, он будет отличаться)
Запустим контейнер командой:
Теперь остановим и удалим Docker контейнеры (командами docker stop и docker rm соотвественно):
Что такое DockerFile?
Docker позволяет вам делиться с другими средой, в которой ваш код запускался и помогает в её простом воссоздании на других машинах.
К примеру, если вы разрабатывали приложение на php7.2, и использовали ElasticSearch 9 версии, и сохранили это в Dockerfile-е, то другие пользователи, которые запустят образ используя ваш Dockerfile, получат ту же среду с php7.2 и ElasticSearch 9.
С Dockerfile вы сможете подробно описать инструкцию, по которой будет воссоздано конкретное состояние. И делается это довольно-таки просто и интуитивно понятно.
Представьте, что вы играете в покемонов
Вы пытаетесь пройти первый уровень, но безрезультатно. И я, как ваш друг, хочу с этим помочь. У меня есть 2 таблетки варианта:
Инструкция прохождения первого уровня
Что является более полезным? Я склоняюсь, что это второй вариант. Потому что он демонстрирует, как добиться желаемого состояния. Это не просто чёрный ящик, который переносит игру на второй уровень.
С докером вы так же имеете два варианта при создании образа:
Я склоняюсь ко второму варианту, потому что он более подробный, гибкий, и редактируемый (вы можете переписать Dockerfile, но не можете перемотать состояние образа в случае прямых изменений).
Пришло время попрактиковаться на реальном примере. Для начала, создадим файл cli.php в корне проекта с содержимым:
Для просмотра полного списка команд можете перейти по ссылке
При написании Dockerfile, начинать следует с наиболее актуального существующего образа, дополняя его в соответствии с потребностями вашего приложения.
К примеру, мы могли не использовать образ php:7.2-cli, а могли взять ubuntu:18.10, последовательно выполняя команды в RUN одна за одной, устанавливая нужное ПО. Однако, в этом мало смысла, когда уже есть готовые сборки.
Теперь, запустим контейнер из нашего образа командой docker run pyramid
Круто! Shell скрипт был успешно скопирован, и выполнен благодаря указанному в Dockerfile параметру CMD.
Однако, сейчас этот контейнер недостаточно гибкий. Нам бы хотелось, чтобы можно было удобно изменять количество строк, из скольки состоит пирамида.
Для этого, отредактируем файл cli.php, и изменим, чтобы количество аргументов принималось из командной строки. Отредактируем вторую строку на:
Почему это работает?
Когда контейнер запускается, вы можете переопределить команду записанную в Dockerfile в поле CMD.
Для этого, дополним Dockerfile:
Мы немного поменяли формат записи. В таком случае, CMD будет добавлена к тому, что выполнится в ENTRYPOINT.
Теперь, заново пересоберём образ
И запустим контейнер с желаемым аргументом
Монтирование локальной директории в Docker-контейнер
Когда игра читает файлы сохранений, файловая система Game Cube внедряет их в текущий сеанс игры (представим это, даже если это не так). Игра может изменять файл сохранений, и это изменение отразится на файловой системе Game Cube, т.е. возникает двусторонняя связь.
Монтирование директории в контейнер позволяет ему читать и писать данные в эту директорию, изменяя её состояние.
При выполнении этой команды, указанная папка смонтируется в папку /mounted, внутри файловой системы контейнера, а команда touch mounted/testfile создаст новый файл под названием testfile, который вы можете увидеть из основной ОС.
Монтирование папки позволяет вам изменять файлы вашей основной системы прямо во время работы внутри Docker контейнера.
Это удобная особенность, которая позволяет нам редактировать код в редакторе на основной ОС, а изменения будут сразу же применяться внутри контейнера.
Что такое Docker Volumes?
Вы можете вставить вашу карту внутрь приставки, точно так же, как и Docker Volume может быть прикреплён к любому из контейнеров.
С Docker Volum-ами мы имеем контейнер, который хранит постоянные данные где-то на нашем компьютере (это актуально, потому что после завершения работы контейнер удаляет все пользовательские данные, не входящие в образ). Вы можете прикрепить Volume-данные к любому из запущенных контейнеров.
Вместо того, чтобы каждый раз, при запуске контейнера, писать, какие из папок вы хотите смонтировать, вы просто можете создать один контейнер с общими данными, который потом будете прикреплять.
Лично я, не использую это очень часто на практике, потому что есть много других методов по управлению данными. Однако, это может быть очень полезно для контейнеров, которые должны сохранять какие-то важные данные, или данные, которыми нужно поделиться между несколькими контейнерами.
Порты контейнеров
Docker позволяет нам получить доступ к какому-то из портов контейнера, пробросив его наружу (в основную операционную систему). По умолчанию, мы не можем достучаться к каким-либо из портов контейнера. Однако, в Dockerfile опция EXPOSE позволяет нам объявить, к какому из портов мы можем обратиться из основной ОС.
Для этого, на по-быстрому, запустим Docker-образ php-apache, который работает на 80 порту.
А так же, в этой папке создадим файл Dockerfile :
Пробежимся по командам:
FROM: это вам уже знакомо, это образ с уже установленным php и apache
WORKDIR: создаст папку если она не создана, и перейдёт в неё. Аналогично выполнению команд mkdir /var/www/html && cd /var/www/html
EXPOSE: Apache по-умолчанию запускается на 80 порту, попробуем «прокинуть» его в нашу основную ОС (посмотрим как это работает через несколько секунд)
Для работы с сетью в Docker, нужно проделать 2 шага:
Это что-то похоже на подключение вашей PS4 приставки к телевизору по HDMI кабелю. При подключении кабеля, вы явно указываете, какой HDMI-канал будет отображать видео.
Выполним первый шаг прокидывания порт. Сбилдим контейнер:
И после этого, запустим контейнер:
После чего, попробуем перейти по адресу localhost:80
Но, это не сработало, потому что мы ещё не выполнили 2 шаг по маппингу портов.
Выйдите из контейнера, нажав CTRL+C.
Теперь, осталось сообщить нашему компьютеру, какой порт контейнера ему нужно слушать, и для этого формат записи будет такой:
И мы можем указать любое соответствие портов, но сейчас просто укажем, что порт системы 80 будет слушать 80 порт контейнера:
И теперь, если перейти по адресу localhost:80, то должны увидеть успешный ответ:
Оказывается, это даже легче, чем подключение HDMI-кабеля. Сейчас, можем попробовать выполнить запуск на разных портах:
Теперь, немного подчистим за собой: нужно остановить и удалить контейнеры, которые в даный момент мы запустили:
Для *nix пользователей есть небольшой хак, который позволит остановить и удалить все контейнеры Docker:
Docker образ: прослойка данных и кеширование
Docker умнее, чем вы могли бы подумать :).
Каждый раз, когда вы собираете образ, он кешируется в отдельный слой. Ввиду того, что образы являются неизменяемыми, их ядро никогда не модифицируются, потому применяется система кеширования, которая нужна для увеличения скорости билдинга.
Каждая команда в Dockerfile сохраняется как отельный слой образа.
Рассмотрим это на примере нашего прошлого Dockerfile-а:
Когда вы пишите свой Dockerfile, вы добавляете слои поверх существующего основного образа (указанного в FROM), и создаёте свой собственный образ (Image).
FROM: говорит Докеру взять за основу этот существующий образ. А все новые команды будут добавлены слоями поверх этого основного образа.
COPY: копирует файлы с основной ОС в образ
WORKDIR: устанавливает текущую папку образа в /var/www/html
Слой Образа Докера это как точка сохранения в игре Super Mario. Если вы хотите изменить какие-то вещи, произошедшие до этой точки сохранения, то вам придётся перезапустить этот уровень полностью. Если вы хотите продолжить прогресс прохождения, вы можете начать с того места, где остановились.
Для иллюстрации этого, добавим новые строки в Dockerfile:
После чего, пересоберём образ:

Выполнив эту команду, из вывода в консоль можете увидеть, что некоторые слои были взяты из кеша. Это как раз те команды, выше которых в Dockerfile не было добавлено/изменено содержимого.
И можно заметить, что в случае изменения Dockerfile, билдинг занимает больше времени, потому что не используется кеш. Где бы вы не написали команду, все закешированные команды, которые находятся ниже в Dockerfile, будут перебилжены заново. А те, что находятся выше, будут по-прежнему браться из кеша.
Если честно, то это действительно крутая функция. Docker следит за изменениями в файлах и использует кеш всегда, когда это нужно (когда были произведены изменения в каких-то из файлов). Изменение ваших файлов потенциально может затрагивать будущие команды, из-за чего, и все последующие слои билдятся заново, а не берутся из кеша.
Какие выводы из этого можно сделать:
В заключение, так же хочу сказать, как можно уменьшить размер слоёв Docker образов.
В Dockerfile вы можете иметь несколько команд (RUN) на выполнение:
В результате выполнения этой команды, будет создано 3 разных слоя в образе. Вместо этого, все команды стараются объединить в одну строку:
Если команда становится длинной, и нечитаемой, то для переноса на следующую строку делаем так:
Технически, только команды ADD, COPY, и RUN создают новый слой в Docker образе, остальные команды кешируются по-другому
Что такое Docker-Compose?
Docker Compose управляет контейнерами, запускает их вместе, в нужной последовательности, необходимой для вашего приложения.
Его можно назвать дирижёром в мире Docker-а.
Docker-compose организовывает совместных запуск контейнеров, как инструменты в групповой игре в определённых участках песни.
Каждый инструмент имеет конкретную задачу в группе оркестра. Труба создаёт основную мелодию песни; фортепиано, гитара дополняют основную мелодию; барабаны задают ритм; саксофоны добавляют больше гармонии и т.д.
Каждый из инструментов имеет свою конкретную работу и задачу, как и наши контейнеры.
Docker-compose написан в формате YAML который по своей сути похож на JSON или XML. Но YAML имеет более удобный формат для его чтения, чем вышеперечисленные. В формате YAML имеют значения пробелы и табуляции, именно пробелами отделяются названия параметров от их значений.
Мы можем использовать этот файл для билдинга нашего предыдущего образа apache:
После выполнения этой команды, Docker спарсит файл docker-compose и создаст описанные сервисы на основе инструкций во вкладке build.
И теперь, запустим эти сервисы, которые создали:
В результате чего, сервер должен был запуститься, и стать доступным по адресу localhost:8080.
Теперь, отключитесь от консоли, нажав CTRL+C.
С docker-compose.yml мы переносим все параметры, ранее записываемые в командной строке при запуске контейнера в конфигурационный YAML файл.
Добавленная строка примонтирует текущую директорию основой операционной системы к директории /var/www/html контейнера.
Теперь, выполните по очереди команды:
При удалении, вас спросят, действительно ли удалять, напишите y и нажмите кнопку enter. Эти команды остановят и удалят все контейнеры, описанные в файле docker-compose.yml (то же самое, как мы ранее запускали docker stop и docker rm )
Теперь перебилдим сервисы, потому что мы изменили Dockerfile:
И опять, по адресу localhost:8080 поднимется наш сервер.
Вместо того, чтобы копировать каждый раз файлы в образ, мы просто примонтировали папку, содержащую исходный код приложения. И теперь, каждый раз не придётся делать ребилд образа, когда файлы изменяются, теперь изменения происходят в лайв режиме, и будут доступны без перестройки образа.
Чтобы в этом убедиться, изменим файл index.php, добавим в него скрипт нами любимой пирамиды:
И теперь, если перейти по адресу localhost:8080?count=10, то увидим, что пирамида выводится:
Монтирование вашей локальной папки как Docker Volume это основной метод как разрабатывать приложения в контейнере.
где, вместо
а вместо
К примеру, эта команда может выглядеть так:
Но, сделаем это на основе текущего Dockerfile:
И в результате должны получить
Пока что, в docker-compose.yml описан только один сервис, потому разворачиваем мы только один контейнер. Но реальный файл docker-compose выглядит больше. К примеру, для Laravel он такой:
Как писать Микро Сервисы с Docker? Что такое микросервисы?
Ниже я постараюсь кратко описать, что такое микросервисы:
Одиночный миросервис выполняет одну конкретнкую задачу. Он никак не связан с другими существующими микросервисами. Вместе же, микросервисы образуют приложение.
Микросервис должен выполнять свою задачу в изолированной среде, управлять своей собственной локальной информацией, и быть независимым от общей системы настолько, насколько это возможно. В основном, каждый из микросервисов имеет собственную, отдельную базу данных (если она нужна).
Это позволяет создавать максимально гибкие и легко масштабируемые приложения.
Идея разделения по ответственности предоставляет преимущество в том, что команда разработчиков может работать параллельно, фокусируясь над разными компонентами.
В основном, микросервисы имеют канал коммуникации мужду собой, в виде REST API, который возвращает данные в JSON, или что-то типа того.
Иногда бывает неясно, насколько большой, или маленькой должна быть задача микросервиса, которую он должен решать. Это решение лежит на плечах разработчика, здесь нет чёткого правила.
Использование микросервисов позволяет быстро масшабироваться под большой нагрузкой, без масшабирования остальных частей вашего приложения. То есть, такая архитектура позволяет вам масшабировать систему компонентно, там, где это требуется. В случае монолитной, единой системы, вам придётся масшабировать всё приложение.
Ввиду того, что статья и так получилась достаточно большой, то пример реализации микросервисной архитектуры я покажу в следующей статье на эту тему. Я принял решение подготовить более качественный материал на эту тему вместе с примерами кода.
Резюме
Я попытался написать эту статью максимально просто, построив всё объяснение на аналогиях и примерах их жизни. Эта статью можно считать простой инструкцией по работе с Docker. Помимо того, что я описал, как пользоваться Docker-ом, добавив несколько рабочих примеров, которые вы можете попробовать у себя на компьютере, я добавил много дополнительной информации, и некоторых тонкостей работы с Docker-ом. Надеюсь, что эта статья показала вам, что такое Docker, и с чем его едят. В следующей статья я затрону более продвинутые темы и приведу примеры.
Subscribe to Блог php программиста: статьи по PHP, JavaScript, MySql
Get the latest posts delivered right to your inbox



























