Docker для начинающих: что такое Docker и как создавать контейнеры Docker

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

Кто хочет остаться позади, когда такая революционная технология поражает мир программирования? Итак, сегодня мы начинаем новую серию руководств, чтобы вы узнали, как использовать Docker для разработки приложений. Если вы абсолютный новичок в Docker, эта серия руководств - правильное место для вас.

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


Зачем еще ждать? Давайте начнем!



Что такое докер

Docker - это инструмент, который используется для создания приложений; то есть для создания, развертывания и запуска приложений через контейнеры.


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

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

Хотя контейнеры, работающие в одной системе, изолированы друг от друга при исполнении, они используют одно и то же ядро ​​ОС. Следовательно, контейнеры более легкие по сравнению с альтернативным выбором для изоляции выполнения приложений - виртуальными машинами.

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


Хотя контейнеры использовались задолго до Docker, внедрение Docker сделало использование контейнеров популярным в сообществе разработчиков. При докеризации приложения используются два компонента: Dockerfile а также Образ Docker . Давай узнаем, что это такое.

Dockerfile

Dockerfile - это текстовый файл, содержащий набор команд, необходимых для создания образа докера. Dockerfile, среди прочего, содержит информацию о базовой ОС, языке, расположении файла и сетевых портах.

Образ Docker

Когда вы запускаете команду сборки Docker с установленным файлом docker, на основе файла docker создается образ докера. Они действуют как шаблоны для создания окончательного контейнера докеров. После создания образы докеров статичны. Вы можете вызвать команду Docker run, чтобы создать контейнер докера с помощью образа докера.



Докеризация приложения Node.js

В этом руководстве мы собираемся докеризовать приложение Node.js. Мы будем следовать пошаговому подходу к запуску контейнера Docker.


1 - Создайте приложение Node.js 2 - Создайте файл докера 3 - Создайте образ докера 4 - Создайте контейнер приложения

Прежде чем погрузиться в докеризацию нашего приложения, вы должны убедиться, что Docker и Node.js установлены в вашей системе.

  • Установите Docker в вашу систему - я не буду рассказывать, как установить Docker в этом руководстве, но вы можете следовать документации Docker и установить Docker на рабочий стол Windows или Ubuntu.
  • Загрузите и установите Node.js с официального сайта

Создайте приложение Node.js

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

npm init -y


Затем установите и добавьте Express в качестве зависимости к вашему приложению, выполнив эту команду в командной строке. Мы будем использовать Express для создания приложения.

npm install express --save

Это добавит экспресс как зависимость к нашему package.json файл.

Теперь мы можем создать приложение Node с помощью Express.


Создайте файл с именем app.js в каталоге проекта и добавьте в файл следующий код.

const express = require('express') const app = express() app.get('/', (req, res) => {
res.send('Hello World!') }) app.listen(3000, () => {
console.log('Node server has started running') })

Приведенный выше код создает сервер Node, который прослушивает входящие запросы через порт 3000. Вы можете запустить эту команду в командной строке, чтобы запустить сервер Node.

node app.js

Теперь перейдите в свой браузер и перейдите по URL-адресу http://localhost:3000 и вы увидите текст Hello World! на странице.

Мы создали простое приложение Node для нашего проекта. Теперь перейдем к созданию файла докеров.

Создайте Dockerfile

В файле dockerfile мы предоставляем информацию, необходимую для создания и запуска нашего приложения Node в среде Docker.

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

FROM node:latest WORKDIR /dockerTutorial COPY . . RUN npm install EXPOSE 3000 ENTRYPOINT ['node', 'app.js']
  • ИЗ Команда извлекает из Docker Hub образ ОС для запуска нашего приложения в конкретной ОС. Docker Hub - это репозиторий образов докеров, которые мы можем перенести в локальную среду. Мы получаем образ на основе Ubuntu, в котором установлен Node.js. Использование «последней» в качестве версии Node извлекает образ, в котором установлена ​​последняя версия Node.
  • WORKDIR команда устанавливает рабочий каталог приложения.
  • КОПИРОВАТЬ команда копирует файлы из текущего каталога (в командной строке) в рабочий каталог, который был установлен на предыдущем шаге. Вы можете указать имя файла для копирования или использовать двойные точки для копирования всех файлов из текущего каталога в рабочий каталог.
  • ЗАПУСТИТЬ команда устанавливает все зависимости, необходимые для сборки приложения. Сюда входят все зависимости, указанные в package.json файл.
  • РАЗОБЛАЧАТЬ Команда открывает порт из контейнера Docker во внешний мир. Этот порт получает все запросы, которые мы отправляем в контейнер Docker. Порт специально установлен на 3000, потому что это порт, который наше приложение Node внутри контейнера Docker использует для прослушивания запросов.
  • ТОЧКА ВХОДА указывает, как запустить приложение. Docker присоединяет массив, который мы предоставляем, к одной команде для запуска приложения. В этом случае node app.js.

Создание образа Docker

Используйте следующую команду для создания образа Docker из файла dockerfile.

docker build -t docker-tutorial .

Docker-tutorial это имя образа Docker. Точка указывает путь к файлу в каталоге проекта, где мы сейчас находимся в командной строке.

Если образ ОС указан с ИЗ команда узел: последний , в данный момент отсутствует на вашем устройстве, он будет извлечен из Docker Hub, когда вы запустите указанную выше команду.

После извлечения образа каждая команда в файле dockerfile будет выполняться одна за другой.

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

docker images

Результат выглядит так

Создание контейнера

Теперь мы можем использовать созданный образ для создания нашего контейнера Docker. Используйте команду docker run, чтобы создать контейнер.

docker run -p 8080:3000 docker-tutorial

Здесь числа 8080 и 3000 обозначают внешний и внутренний размер контейнера. Внешний порт 8080 - это порт, который мы используем для подключения к приложению через наш браузер. Внутренний порт 3000 - это порт, который наше приложение прослушивает на предмет входящих запросов. Контейнер Docker сопоставляет заданный внешний порт с внутренним портом.

Посетите URL http://localhost:8080 в браузере и посмотрите, откроется ли страница с Hello World! сообщение, которое вы получили при посещении http://localhost:3000 перед. Если да, значит, ваш контейнер Docker запущен и работает.

Вы можете использовать эту команду для просмотра всех запущенных контейнеров Docker на вашем устройстве.

docker ps

Команда выдаст вам такой результат. Здесь мы можем найти CONTAINER_ID и NAME запущенного контейнера.

Добавление переменных среды в ваше приложение

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

Обратите внимание, как мы явно упомянули порт, который наше приложение Node слушает, когда сервер работает. Этот подход негибкий и подвержен ошибкам. Если мы запускаем наше приложение в среде, которая не открывает порт 3000 для сервера Node, наше приложение перестает работать.

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

Посмотрим, как это сделать.

Сначала добавьте переменную окружения в наш файл докеров с ее значением. Для этого нам нужно добавить новую команду в файл докеров.

FROM node:latest WORKDIR /dockerTutorial COPY . . ENV PORT=3000 RUN npm install EXPOSE $PORT ENTRYPOINT ['node', 'app.js']

Используя команду ENV, за которой следует имя переменной и присвоение значения, мы можем добавить новую переменную среды в наш файл докеров. Вы заметили, что команда EXPOSE 3000 была изменена, чтобы не указывать явно номер порта? Вместо этого он обращается к созданной переменной PORT, чтобы получить точный номер порта. При таком подходе, если нам нужно изменить номер порта, нам нужно изменить только одно место в нашем коде, что упрощает обслуживание нашего приложения.

Теперь мы изменили файл dockerfile, следующим шагом будет изменение app.js для ссылки на созданную переменную среды. Для этого мы заменяем номер порта 3000, используемый внутри метода прослушивания, на process.env.PORT.

const express = require('express') const app = express() app.get('/', (req, res) => {
res.send('Hello World!') }) app.listen(process.env.PORT, () => {
console.log('Node server has started running') })

Поскольку мы внесли изменения в файлы нашего приложения и файл dockerfile, нам нужно создать новый образ для нового контейнера. Но сначала мы должны остановить работающий в данный момент контейнер Docker, чтобы добиться этого.

Мы можем использовать команду docker stop, чтобы остановить контейнер.

docker stop f10

Значение f10, используемое в этой команде, представляет собой первые три цифры идентификатора контейнера.

Мы можем использовать команду docker kill, чтобы остановить работающий контейнер.

docker kill f10

Разница между docker kill и docker stop заключается в том, что docker stop останавливает контейнер более изящно, освобождая использование ресурсов и сохраняя состояние. docker kill, однако, более резко останавливает контейнер без должного высвобождения ресурсов или сохранения состояния. Для контейнера, работающего в производственной среде, лучше использовать docker stop для остановки контейнера.

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

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

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

Но есть подход получше. Мы можем запустить контейнер в режиме демона. В режиме демона контейнер работает в фоновом режиме без использования текущей вкладки для отображения результатов.

Чтобы запустить контейнер в режиме демона, вам просто нужно добавить дополнительный флаг -d в команду docker run.

docker run -d -p 8080:3000 docker-tutorial

Запуск контейнера в интерактивном режиме

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

Используйте следующую команду для запуска контейнера в интерактивном режиме.

docker exec -it e37 bash

Здесь e37 - идентификатор контейнера. Поиграйте с интерактивным режимом, используя команды bash.



Заключение

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