как узнать порт контейнера докер
🐳 Как узнать IP-адрес Docker контейнера
Хотите узнать, какой IP-адрес у вашего запущенного контейнера?
Вы можете проверить работающий контейнер, чтобы получить эту информацию.
Команда inspect предоставляет много подробностей о проверяемом контейнере.
Пролистайте к концу вывода и загляните в раздел Networks, чтобы получить IP-адрес контейнера.
Вы также можете использовать команду grep, чтобы вывести только строки, соответствующие шаблону «IPAddress».
Не знаете название или идентификатор контейнера? Используйте команду sudo docker ps.
Не пугайтесь, если у вашего контейнера более одного IP-адреса.
В этом нет ничего необычного.
Чтобы понять это, вам нужно разобраться, как контейнеры взаимодействуют друг с другом.
Я объясню вам это в следующем разделе, а затем расскажу о некоторых других методах получения IP-адреса запущено контейнера Docker.
Как общаются Docker контейнеры?
Docker – это инструмент для упаковки и доставки программного обеспечения с использованием технологии контейнеризации.
Программное обеспечение может иметь множество целей, от, возможно, простой обработки текста до полноценного веб-сервера, на котором размещаются ваши файлы.
Каждое из этих программ разбивается на микросервисы, а затем упаковывается в контейнеры.
В зависимости от назначения программного обеспечения одной службе может потребоваться взаимодействие с другой.
Например, рассмотрим WordPress.
Есть две службы: одна – это веб-сервер, фронтенд, а другая – бэкэнд, база данных.
Интерфейс должен взаимодействовать с базой данных, иначе он просто не будет работать.
Эта связь достигается за счет наличия по крайней мере двух сетевых интерфейсов, связанных с каждым из этих двух контейнеров, причем оба интерфейса подключены к одной и той же сети.
Эта сеть называется «docker network».
Docker network
Считайте Docker network пулои доступных IP-адресов.
Если два контейнера получат IP-адреса из одного пула, они смогут обмениваться данными друг с другом.
В основном есть два типа сетей: сети по умолчанию или предварительно определенные сети и сети, определяемые пользователем.
Вы можете получить список сетей, используя следующую команду:
Проигнорируйте последние две записи и сосредоточьтесь на первой сети.
Сеть bridge – это сеть по умолчанию, к которой будет подключаться каждый контейнер, если не другое указан явно.
Вы можете получить более подробную информацию об этой сети, выполнив команду docker network inspect bridge.
Я собираюсь отфильтровать вывод, так как для этой демонстрации мне не нужны все данные, которые мы можем вывести.
Если у вас не установлен jq, установите его с помощью диспетчера пакетов вашего дистрибутива.
У каждой из этих сетей есть подсеть, в случае сети bridge это подсеть 172.17.0.0/16.
Это означает, что всего имеется 65534 – 1 = 65533 используемых хостов или IP-адресов.
Я отминусовал один, так как для шлюза выделен 172.17.0.1.
Вы также можете увидеть это, используя следующую команду:
Проверка IP-адреса Docker контейнера
Есть несколько способов проверить IP-адрес[а], связанный с вашим контейнером, вот их список, включая примеры команд.
Метод 1: Inspect
Подкоманда inspect чрезвычайно полезна.
Контейнер можно проверить с помощью команды docker container inspect [CONTAINER ID] | [CONTAINER NAME].
Проверка контейнера означает получение как можно большего количества информации о контейнере, от портов, переменных среды до точек монтирования, данных контрольной группы и т. д.
Из вывода можно извлечь IP-адрес.
Если вы запустите команду inspect для контейнера, вы получите кучу информации в формате JSON.
Прокрутите вниз, пока не найдете ключ NetworkSettings, там найдите IPAddress.
Это и есть IP-адрес вашего контейнера.
Вот отфильтрованный вывод:
Метод 2: Использование оболочки контейнера
Это наиболее простой метод, но я его не рекомендую.
В этом методе вы присоединяете свой stdin|stdout к контейнеру и запускаете команду ip (или другую команду, которая показывает IP-адреса, связанные с сетевыми адаптерами).
Причина, по которой я не рекомендую это делать, заключается в том, что многие образа довольно легкие и не содержат команду ip (или что-то подобное).
Возьмем в качестве примера образ ubuntu:20.04, запустим контейнер, подобный следующему:
Чтобы контейнер работал, я использовал команду sleep 1d.
Теперь запустите процесс оболочки внутри контейнера и прикрепите свой stdin|stdout вот таким образом:
Оказавшись в этом контейнере, попробуйте запустить ip или ifconfig.
Вы увидите что-то вроде следующего:
Чтобы эти команды работали, вам необходимо установить соответствующие пакеты.
Чтобы получить команду ip, установите пакет iproute2 и повторно запустите команду ip a.
Теперь вы можете увидеть, что IP-адрес, связанный с интерфейсом eth0@if5, равен 172.17.0.2.
Обратите внимание на сеть, частью которой является этот контейнер.
Поскольку я не создавал и не подключал пользовательскую сеть к этому контейнеру, он был подключен к сети bridge, поэтому сеть этого IP-адреса 172.17.0.0.
Метод 3: проверив саму сеть
Всякий раз, когда контейнер подключается к сети, этот подключенный контейнер также виден из сети вместе с IP-адресом, назначенным этим контейнерам.
Поскольку мой контейнер подключен к сети bridge, я могу проверить сеть с помощью следующей команды:
Чтобы продемонстрировать это, я развернул еще один контейнер с именем ip.
Вы можете увидеть контейнеры и IP-адреса в указанном выше выводе JSON.
Теперь извлечь IP-адрес конкретного контейнера здесь немного сложнее.
Если вы знаете идентификатор контейнера, вы можете использовать jq следующим образом:
Какой метод выбрать?
Это были все методы, с помощью которых вы можете получить IP-адрес [а] контейнеров.
Второй метод, хотя и интуитивно понятен, не воспроизводится.
В большинстве случаев первый метод самый простой и хорошо выполняет свою работу.
Но может наступить время, когда вы захотите проверить, какие контейнеры подключены к определенной сети, и получить IP-адреса в этой сети.
В этом случае имеет смысл проверить сеть и подсветить IP-адреса.
Вы можете получить все имена контейнеров и назначенные им IP-адреса из сети вот так:
Смените bridge на другую сеть, и вы получите все контейнеры и их IP-адреса.
Надеюсь, эта статья была для вас полезной.
Если у вас есть какие-либо вопросы, дайте мне знать в комментариях ниже.
Docker: привязываем порты
Решаем вопрос с портами раз и навсегда
Вы когда-нибудь были на собеседовании на должность младшего разработчика, где от вас ожидали, что вы знаете, как работает Docker? Сегодня интервьюеры ожидают, что вы хорошо знаете восемь, десять или даже более технологий. Это сумасшествие. Скорее всего, вы не изучали Docker в университете. Если у вас есть знания в этой области, вы отличаетесь от других людей.
Одна из первых проблем, с которой вы столкнетесь, когда начнёте использовать Docker, в том, что вы не сможете просто так подключиться к контейнеру. Эта статья о том, почему так происходит. Я также объясню на практическом примере, как в Docker работает привязка портов.
Даже если вы уже опытный разработчик, вы должны знать, что такое привязка портов. В противном случае во время собеседования вы можете выглядеть глупо. Если у вас нет об этом ни малейшего представления, возьмите чашку кофе и устраивайтесь поудобнее. Я постараюсь рассказать всё, что вам нужно знать об этом. Всего за несколько минут!
Начнём с контейнера Nginx Docker
Ничего страшного, если вы ничего не знаете о Docker. Я попробую подробно всё объяснить. Во-первых, мне нужно убедиться, что вы понимаете разницу между контейнером Docker и образом Docker.
Образ Docker — это файл со всеми зависимостями и конфигурациями для запуска определённой программы. Одна из проблем, решаемых с помощью Docker — кошмар установки.
Мы все устанавливали программы на Windows, Mac или Linux. Когда программе чего-то не хватает, она сообщает об этом и всё. Это раздражает. Наверное, можно тоже просто установить её, да? Тогда не хотите ли вы установить и эту программу? Ох… В конце концов вы получаете множество программ. При этом часто нужно настроить системные переменные и так далее. В худшем случае это может повредить систему. Вы же не хотите, чтобы все ваши коллеги прошли через это? Так вот, образ Docker содержит все необходимое для установки программы, а контейнер Docker — это запущенный экземпляр образа.
Итак, Docker решает проблему установки. Контейнер содержит все необходимое для работы и ничего больше. Вы можете запустить его на Windows, Linux или Mac и, в принципе, везде, где установлен Docker. Но хватит о преимуществах. Мы здесь для того, чтобы поднять и запустить контейнер.
Давайте, наконец, начнём с Nginx Docker. Nginx — это веб-сервер, работающий на 80 порту. Я сразу же запущу контейнер Docker (в отсоединенном режиме), используя образ Nginx Docker:
Создается контейнер. Вы увидите его UUID. Если вы не знаете, что такое UUID. С помощью команды container ps вы получаете список активных контейнеров:
Теперь, если вы попытаетесь подключиться к контейнеру напрямую с помощью curl или браузера, у вас не получится. То есть вы не можете подключиться непосредственно к контейнеру.
— Но почему? В Docker-файле говорится, что порт 80 открыт… я его не понимаю.
— Не волнуйтесь, я объясню это в следующей части статьи!
Почему нельзя подключиться напрямую?
Контейнеры могут подключаться к внешнему миру без какой-либо конфигурации. Это здорово, потому что нам не нужно менять ничего из того, что мы запрограммировали раньше. Но внешний мир не может подключиться к контейнеру по умолчанию.
— А, понятно. То есть не наоборот. Как же тогда мы должны подключиться?
— Есть несколько вариантов сделать это. Изучим их.
1. Предоставить все порты Docker’а.
— Хорошо звучит, но как теперь найти этот порт?
— Не волнуйтесь, мы найдем ваши порты. Для этого есть несколько способов. Я покажу два из них:
• docker container port
Начнём с команды Docker. Просто допишите к ней UUID контейнера. Вы увидите, что порт контейнера 80 привязан к IP-адресу хоста 0.0.0.0 и порту хоста 32768 (или другому порту при самостоятельном выполнении команды).
Другой вариант — команда netstat. Чтобы найти все открытые порты, вы также можете выполнить команду ниже. Заметьте, что вы найдёте свой любимый порт среди других портов. Искомый порт находится в третьей строке.
Все открытые порты, найденные netstat.
2. Доступ к определённому порту
Пример привязки портов: привязка порта 80 контейнера Docker к 8080 порту хост-машины.
Предоставление всех портов Docker обычно не очень хорошая идея: по умолчанию не выставляется вообще ни один порт. Думаю, это сделано в целях безопасности. Вы же не хотите открывать всё: это не имеет никакого смысла. Верно? Чтобы открыть только один порт, выполните эту команду:
Порт 80 контейнера Nginx открыт внешнему миру на порту хоста 8080. Теперь вы можете подключиться к контейнеру несколькими способами. Например, с помощью curl или вашего браузера. Это потрясающе!
Поздравляю, теперь вы понимаете самую важную часть привязки портов в Docker! Я покажу результат выполнения curl:
Ещё одна вещь
Заключение
Привязка портов в Docker — важная концепция, которую необходимо понимать, если вы работаете с контейнерами. Поначалу она может сбить с толку и вызвать вопросы о том, зачем вам нужно настраивать входящие соединения. Docker предоставляет всю необходимую документацию. Однако некоторые концепции Docker нам, разработчикам, понять труднее, чем другие.
Я надеюсь, эта статья прояснила для вас привязку портов.
Погружаемся в Docker: Dockerfile и коммуникация между контейнерами
В прошлой статье мы рассказали, что такое Docker и как с его помощью можно обойти Vendor–lock. В этой статье мы поговорим о Dockerfile как о правильном способе подготовки образов для Docker. Также мы рассмотрим ситуацию, когда контейнерам нужно взаимодействовать друг с другом.
В InfoboxCloud мы сделали готовый образ Ubuntu 14.04 с Docker. Не забудьте поставить галочку «Разрешить управление ядром ОС» при создании сервера, это требуется для работы Docker.
Dockerfile
Подход docker commit, описанный в предыдущей статье, не является рекомендованным для Docker. Его плюс состоит в том, что мы настраиваем контейнер практически так, как привыкли настраивать стандартный сервер.
Вместо этого подхода мы рекомендуем использовать подход Dockerfile и команду docker build. Dockerfile использует обычный DSL с инструкциями для построения образов Docker. После этого выполняется команда docker build для построения нового образа с инструкциями в Dockerfile.
Написание Dockerfile
Давайте создадим простой образ с веб-сервером с помощью Dockerfile. Для начала создадим директорию и сам Dockerfile.
Созданная директория — билд-окружение, в которой Docker вызывает контекст или строит контекст. Docker загрузит контекст в папке в процессе работы Docker–демона, когда будет запущена сборка образа. Таким образом будет возможно для Docker–демона получить доступ к любому коду, файлам или другим данным, которые вы захотите включить в образ.
Добавим в Dockerfile информацию по построению образа:
Также Dockerfile поддерживает комментарии. Любая строчка, начинающаяся с # означает комментарий.
Первая инструкция в Dockerfile всегда должна быть FROM, указывающая, из какого образа нужно построить образ. В нашем примере мы строим образ из базового образа ubuntu версии 14:04.
Далее мы указываем инструкцию MAINTAINER, сообщающую Docker автора образа и его email. Это полезно, чтобы пользователи образа могли связаться с автором при необходимости.
Инструкция RUN исполняет команду в конкретном образе. В нашем примере с помощью ее мы обновляем APT репозитории и устанавливаем пакет с NGINX, затем создаем файл /usr/share/nginx/html/index.html.
Мы используем этот формат для указания массива, содержащего команду для исполнения и параметры команды.
Далее мы указываем инструкцию EXPOSE, которая говорит Docker, что приложение в контейнере должно использовать определенный порт в контейнере. Это не означает, что вы можете автоматически получать доступ к сервису, запущенному на порту контейнера (в нашем примере порт 80). По соображениям безопасности Docker не открывает порт автоматически, но ожидает, когда это сделает пользователь в команде docker run. Вы можете указать множество инструкций EXPOSE для указания, какие порты должны быть открыты. Также инструкция EXPOSE полезна для проброса портов между контейнерами.
Строим образ из нашего файла
, где trukhinyuri – название репозитория, где будет храниться образ, nginx – имя образа. Последний параметр — путь к папке с Dockerfile. Если вы не укажете название образа, он автоматически получит название latest. Также вы можете указать git репозиторий, где находится Dockerfile.
В данном примере мы строим образ из Dockerfile, расположенном в корневой директории Docker.
Что произойдет, если инструкция не исполнится?
Давайте переименуем в Dockerfile nginx в ngin и посмотрим.
Использования кеша сборок для шаблонизации
Используя кеш сборок можно строить образы из Dockerfile в форме простых шаблонов. Например шаблон для обновления APT-кеша в Ubuntu:
Инструкция ENV устанавливает переменные окружения в образе. В данном случае мы указываем, когда шаблон был обновлен. Когда необходимо обновить построенный образ, просто нужно изменить дату в ENV. Docker сбросит кеш и версии пакетов в образе будут последними.
Инструкции Dockerfile
Давайте рассмотрим и другие инструкции Dockerfile. Полный список можно посмотреть тут.
Инструкция CMD указывает, какую команду необходимо запустить, когда контейнер запущен. В отличие от команды RUN указанная команда исполняется не во время построения образа, а во время запуска контейнера.
ENTRYPOINT
Часто команду CMD путают с ENTRYPOINT. Разница в том, что вы не можете перегружать ENTRYPOINT при запуске контейнера.
При запуске контейнера параметры передаются команде, указанной в ENTRYPOINT.
Можно комбинировать ENTRYPOINT и CMD.
WORKDIR
С помощью WORKDIR можно установить рабочую директорию, откуда будут запускаться команды ENTRYPOINT и CMD.
Специфицирует пользователя, под которым должен быть запущен образ. Мы можем указать имя пользователя или UID и группу или GID.
VOLUME
Инструкция VOLUME добавляет тома в образ. Том — папка в одном или более контейнерах или папка хоста, проброшенная через Union File System (UFS).
Тома могут быть расшарены или повторно использованы между контейнерами. Это позволяет добавлять и изменять данные без коммита в образ.
В примере выше создается точка монтирования /opt/project для любого контейнера, созданного из образа. Таким образом вы можете указывать и несколько томов в массиве.
Инструкция ADD добавляет файлы или папки из нашего билд-окружения в образ, что полезно например при установке приложения.
Источником может быть URL, имя файла или директория.
В последнем примере архив tar.gz будет распакован в /var/www/wordpress. Если путь назначения не указан — будет использован полный путь включая директории.
Инструкция COPY отличается от ADD тем, что предназначена для копирования локальных файлов из билд-контекста и не поддерживает распаковки файлов:
ONBUILD
Инструкция ONBUILD добавляет триггеры в образы. Триггер исполняется, когда образ используется как базовый для другого образа, например, когда исходный код, нужный для образа еще не доступен, но требует для работы конкретного окружения.
Коммуникация между контейнерами
В предыдущей статье было показано, как запускать изолированные контейнеры Docker и как пробрасывать файловую систему в них. Но что, если приложениям нужно связываться друг с другом. Есть 2 способа: связь через проброс портов и линковку контейнеров.
Проброс портов
Такой способ связи уже был показан ранее. Посмотрим на варианты проброса портов чуть шире.
Когда мы используем EXPOSE в Dockerfile или параметр -p номер_порта – порт контейнера привязывается к произвольному порту хоста. Посмотреть этот порт можно командой docker ps или docker port имя_контейнера номер_порта_в_контейнере. В момент создания образа мы можем не знать, какой порт будет свободен на машине в момент запуска контейнера.
Можно привязать UDP порты, указав /udp:
Линковка контейнеров
Связь через сетевые порты — лишь один способ коммуникации. Docker предоставляет систему линковки, позволяющую связать множество контейнеров вместе и отправлять информацию о соединении от одного контейнера другому.
Префикс DB_ был взят из alias контейнера.
Можно просто использовать информацию из hosts, например команда ping db (где db – alias) будет работать.
Заключение
В этой статье мы научились использовать Dockerfile и организовывать связь между контейнерами. Это только вершина айсберга, очень многое осталось за кадром и будет рассмотрено в будущем. Для дополнительного чтения рекомендуем книгу The Docker Book.
Готовый образ с Docker доступен в облаке InfoboxCloud.
В случае, если вы не можете задавать вопросы на Хабре, можно задать в Сообществе InfoboxCloud.
Если вы обнаружили ошибку в статье, автор ее с удовольствием исправит. Пожалуйста напишите в ЛС или на почту о ней.
Управление портами Docker
В Docker сами контейнеры могут иметь приложения, работающие на портах. Если вы хотите получить доступ к приложению в контейнере через номер порта, то вам необходимо сопоставить номер порта контейнера с номером порта хоста Docker. Рассмотрим пример того, как можно это достичь.
В нашем примере мы собираемся загрузить контейнер Jenkins из Docker Hub. После чего мы сопоставим номер порта Jenkins с номером порта хоста Docker.
Шаг 1. Первым делом вам необходимо зарегистрироваться на Docker Hub.
Шаг 2. После того как вы зарегистрируетесь, войдите в Docker Hub.
Шаг 3. Теперь мы рассмотрим образ Jenkins.
Шаг 4. Если вы прокрутите вниз на той же странице, то увидите команду Docker pull, которая будет использоваться для загрузки образа Jenkins на локальный сервер Ubuntu.
Шаг 5. Перейдите на сервер Ubuntu и выполните следующую команду:
Шаг 6. Чтобы понять, какие порты открыты контейнером, вы должны использовать команду Docker inspect.
Давайте подробнее рассмотрим эту команду.
docker inspect#
Данный метод позволяет возвращать низкоуровневую информацию о контейнере или образе.
Вывод вернёт низкоуровневую информацию об образе или контейнере в формате JSON.
Пример#
Из вывода видно, что в разделе “ExposedPorts” упоминаются два порта. Первый — это порт данных 8080, а второй — это порт управления 50000.
Чтобы запустить Jenkins и сопоставить порты, вам необходимо изменить вызов команды Docker run, дописав к нему параметр ‘p’, который определяет отображение портов. Итак, вам нужно выполнить следующую команду:
Левая часть сопоставления номеров портов — это порт хоста Docker для сопоставления, а правая — номер порта контейнера Docker.
Когда вы откроете браузер и перейдёте к хосту Docker через порт 8080, то увидите, что Jenkins запущен и работает.
Введение ¶
В этой статье я хочу немного рассказать про Docker. Здесь я покажу, как начать с ним работать, самые основы. Большая проблема, с которой я сам столкнулся, когда изучал эту технологию, была в огромном количестве избыточной информации. Когда же я разобрался, всё оказалось намного проще.
Эту статью я писал, используя Debian 9 на VirtualBox. Конечно, это не обязательное условие, но докер сам по себе, на мой взгляд, ставит много лишнего в систему, поэтому я предпочитаю держать его в виртуальной машине.
Из чего состоит Docker ¶
Сам по себе докер, это виртуальная машина. И нужно рассматривать его именно как полноценную виртуальную машину, в которой есть свой жёсткий диск, оперативная память и сетевая карта. Если вы работали с виртуальными машинами, напримкер, VirtualBox, то многие вещи будут уже знакомы, правда, с той разницей, что докер не имеет красивую GUI-оболочку, а управляется в основном из консоли.
Основные компоненты докера:
Нужно помнить, что в контейнере всегда запускается образ. При этом, если докер не нашёл образ в локальном хранилище, то он будет искать его в удалённом репозитории (как правило, на Dockerhub).
Как запустить образ ¶
Как бы странно это не казалось, но, если вам хочется уже что-то запустить, то образ даже и собирать-то не надо. Достаточно установить docker и выполнить:
Это приведёт к следующим действиям:
Чтобы удалить ненужные контейнеры и образы, выполните:
Поздравляю! Теперь вы стали почти докер-мастером.
Немного теории ¶
Основная идея докера, это запуск приложений в изолированном пространстве. Виртуальные контейнеры нужны, чтобы окружение одного процесса не мешало другому. Каждый контейнер по умолчанию изолирован от других контейнеров и от машины, на которой он работает. Данные внутри контейнера существуют, пока жив сам контейнер. Если контейнер удалить, то удалятся и данные, которые в нём были. При этом образ, из которого был запущен контейнер, никак не изменится.
Именно на идеи изоляции процесса построена основная часть логики докера. Контейнер работает, пока работает начальный процесс (его называют entry point или command). Как только процесс завершается, контейнер останавливается. Это ключевое отличие докера от привычных виртуальных машин (вроде VirtualBox).
Благодаря изоляции процессов, на одной машине можно запускать много версий приложения, которое в обычных условиях будет конфликтовать. Например, можно запустить сразу MySQL 8 и MySQL 5, nodejs 8 и nodejs 10. Без докера сделать это тоже можно, но проблематичней.
Ещё одним важным отличием докера от обычных виртуальных машин является то, что он не эмулирует аппаратную часть. Он использует ресурсы системы, но изолирует сам процесс. Поэтому не рекомендуют запускать контейнеры из образов, которые были собраны под платформы, отличные от той, где запущен докер.
Как использовать ресурсы контейнера ¶
По умолчанию контейнер закрыт от любых контактов извне. Вы не можете ни скопировать в него файл, ни подключиться к сокету. Он закрыт. Но при запуске контейнера можно пробросить порт или папку. Тогда к нему можно будет подключиться, добавить файл или что-то скачать. Всё это делается при создании (запуске) контейнера через аргументы.
Проброс портов ¶
Для примера запустим контейнер с Debian 9 и пробросим локальный порт 3132 на 80 порт контейнера:
Пояснения к команде:
Общий принцип запуска контейнеров довольно простой:
Аргументы, параметры и тег необязательны, их можно опускать. Но нужно помнить, что без аргументов образ сам по себе не пробрасывает порты и папки. Это всегда делается через аргументы при создании контейнера.
Теперь давайте рассмотрим, как выполнять команды внутри контейнера. Для примера установим и запустим консольный сервер php 7:
Пояснения к команде:
Чтобы проверить, работает сервер или нет, нужно подключиться на 3132 порт основной машины, например так:
В этом примере я использовал две разные консоли. На одной я запускал сервер, а на другой curl. Ещё можно использовать браузер, если докер установлен у вас в системе.
Проброс папки ¶
Прежде, чем начать что-то менять, надо удалить старый контейнер:
Теперь подготовим наш «проект»:
А теперь запускаем контейнер с пробросом папки проекта:
Если вы помните, я удалил контейнер, в котором был установлен php, а это значит, что мне заново придётся установить пакет php7.0-cli:
Теперь в контейнере есть и проект, и php, можно запускать сервер:
Теперь проверяем, как работает наш проект:
Для наглядности давайте создадим ещё один файл в «проекте», чтобы удостовериться, что всё работает как надо:
Должно вывести что-то вроде этого:
Если у вас получилось, смело пишите в резюме, что владеете докером!
Собираем образ (image) ¶
Работа с образом не представляет ничего сложного. Нужно создать файл Dockerfile, указать в нём образ-источник, добавить свои команды и собрать.
Прежде, чем писать файл, я бы хотел определить проблемы, которые нужно решить:
Указать проброс портов или папки в Dockerfile файле нельзя (несмотря на директивы EXPOSE и VOLUME, проброс и монтирование можно делать только при запуске контейнера). Сделано это специально по причинам безопасности, иначе владелец образа в репозитории мог бы подключать любую системную папку в контейнер без ведома пользователя и красть данные.
Создаём Dockerfile в любой папке со следующим содержимым:
Небольшое отступление про точку входа. Как я уже говорил, основная специализация докера, это изолирование процесса. Поэтому в одном контейнере запускается всегда один процесс, и точка входа тоже всегда одна. Если нужно запустить вместе несколько процессов (например, php-frm и nginx), то пишется скрипт, который становится точкой входа и запускает нужные приложения. Но объявить несколько точек входа, на данный момент, нельзя.
Теперь нужно собрать образ командой:
Пояснения к команде:
Готово! Теперь можно запустить контейнер из нашего образа:
Если всё сделано правильно, то список запущенных контейнеров должен быть таким:
Ура! Теперь вы гуру 🙂 Конечно, это далеко не все возможности докера, но это то, на чём строятся большие проекты. В основе каждого проекта стоят контейнеры, которые запускаются из образов. Комбинации контейнеров образуют кластеры, которые обеспечивают безотказную работу крупных приложений.
Что дальше ¶
Теперь, когда вы научились создавать образы и поднимать контейнеры, надо понять, как организовать их бесперебойную работу и межконтейнерное взаимодействие.
Попробуйте выполнить следующие шаги: