Быстрое погружение в Dockerizing простого приложения ExpressJs

Что такое Докер?

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

Сам контейнер можно очень легко перемещать из среды в среду. Контейнер Docker — это очень легкий пакет со всеми инструкциями и зависимостями, такими как фреймворки, библиотеки и корзины внутри него.

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

Контейнер Docker против виртуальных машин

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

Давайте начнем! — Запуск Node-приложения

Мы увидим, как докеризировать приложение node.js. перед этим на машине должен быть установлен докер. Вы можете следовать этому руководству: Установка Docker.

Давайте инициализируем простое экспресс-приложение

Если у вас уже запущено приложение nodeJs, вы можете перейти к разделу # Создание файла Docker.

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

$ mkdir myapp 
$ cd myapp

Я буду использовать экспресс-генератор приложений: express-generator, чтобы быстро создать скелет приложения.

Вы можете запустить генератор приложений с помощью команды npx (доступно в Node.js 8.2.0).

$ npx express-generator

💡 Вы также можете установить экспресс-установку с помощью npm, как показано ниже.

$ npm init --yes 
$ npm install express body-parser*

Теперь давайте установим зависимости:

$ npm install

Давайте добавим console.log при запуске сервера, перейдите в свой bin/www и отредактируйте следующее

// Update from 
// server.listen(port); 
// to 
server.listen(port, ()=>{
 console.log(`Running on Port: ${port}`) 
})

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

$ npm start

Вы должны получить такой вывод

> [email protected] start /home/kyojin/Project/myapp 
> node ./bin/www

Running on Port: 3000

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

Создание вашего самого первого Dockerfile.

Образ Docker — это шаблон, содержащий инструкции для контейнера Docker. Этот шаблон написан на языке под названием YAML, что означает «Еще один язык разметки».

Образ Docker создается в файле YAML, а затем размещается как файл в реестре Docker. Изображение имеет несколько ключевых слоев, и каждый слой зависит от слоя под ним. Слои изображений создаются путем выполнения команд в Dockerfile и доступны только для чтения. Вы начинаете со своего базового уровня, который обычно содержит ваш базовый образ и вашу базовую операционную систему, а затем у вас будет слой зависимостей над ним. Затем они включают инструкции в файле, доступном только для чтения, который станет вашим Dockerfile.

Чтобы создать Docker-образ вашего приложения. вам нужно будет создать файл с именем Dockerfile и добавить следующие команды:

💡 ПРИМЕЧАНИЕ. Имя Dockerfile не важно, но имя файла по умолчанию для многих команд просто Dockerfile. Поэтому мы будем использовать это имя в качестве имени файла в этой серии.

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

FROM node:16-alpine

Alpine Linux намного меньше, чем большинство базовых образов дистрибутива (~5 МБ), поэтому образы в целом намного тоньше.

Затем нам нужно создать каталог для хранения кода приложения внутри изображения, это будет рабочий каталог для вашего приложения, и мы установим его как «/usr/src/app

WORKDIR /usr/src/app

Затем нам нужно скопировать файл package.json и/или package-lock.json с локального компьютера в образ докера, а затем установить все зависимости в образе докера.

COPY package*.json ./ 
RUN npm install 
# You can also run "npm ci"

💡 ПРИМЕЧАНИЕ. Вместо того, чтобы копировать весь рабочий каталог, мы копируем только package.json файл. Это позволяет нам использовать кешированные слои Docker.bitJudoподробно объяснил это, и его можно проверить здесь.

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

Чтобы связать исходный код вашего приложения с образом Docker, используйте инструкцию COPY:

Приведенный ниже код копирует весь исходный код из локального образа в Docker-образ.

# Bundle app source 
COPY . .

Ваше приложение привязывается к порту 3000, поэтому вы будете использовать инструкцию EXPOSE, чтобы он отображался демоном docker:

EXPOSE 3000

И последнее, но не менее важное: определите команду для запуска вашего приложения, используя CMD, который определяет вашу среду выполнения. Здесь мы будем использовать npm start для запуска вашего сервера:

CMD [ "npm", "start" ]

Ваш Dockerfile должен выглядеть примерно так:

FROM node:16-alpine 

# Create an app directory WORKDIR 
/usr/src/app 

# Install app dependencies 
# A wildcard is used to ensure both package.json AND package-lock.json are copied 
# where available (npm@5+) 
COPY package*.json ./ 
RUN npm install 

# If you are building your code for production 
# RUN npm ci --only=production 
# Bundle app source 
COPY . . 

EXPOSE 3000 
CMD [ "npm", "start" ]

Создайте .dockerignore

Создайте файл .dockerignore в том же каталоге, что и ваш Dockerfile, со следующим содержимым:

node_modules 
npm-debug.log

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

Создание своего имиджа

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

$ docker build . -t <your username>/express-web-app

Флаг -t позволяет пометить изображение, чтобы его было легче найти позже с помощью команды docker images.

Ваш образ теперь будет указан Docker:

$ docker images

Пример вывода

# Example
REPOSITORY                         TAG        ID              CREATED
node                               16-alpine  3b66eb585643    5 days ago
<your username>/express-web-app    latest     d64d3505b0d2    1 minute ago

Запустите образ

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

$ docker run -p 8001:3000 -d <your username>/express-web-app

Запуск вашего образа с -d запускает контейнер в автономном режиме, оставляя контейнер работать в фоновом режиме. Флаг -p перенаправляет общедоступный порт на частный порт внутри контейнера.

Тестовое приложение

Вы можете протестировать приложение, вызвав его с помощью cURl (при необходимости установите через: sudo apt-get install curl).

$ curl -i localhost:8001 

HTTP/1.1 200 OK 
X-Powered-By: Express 
Content-Type: text/html; charset=utf-8 Content-Length: 170 
ETag: W/"aa-z+ebXSEdArbZ+EXlN/WQjf6HV8c" 
Date: Sun, 06 Nov 2022 19:58:32 GMT 
Connection: keep-alive 
Keep-Alive: timeout=5 


<!DOCTYPE html><html><head><title>Express</title> 
<link rel="stylesheet" href="/stylesheets/style.css"></head> 
<body><h1>Express</h1><p>Welcome to Express</p></body></html>

Полезные команды:

# Get container ID 
$ docker ps 

# Print app output 
$ docker logs <container id>

Выключить изображение

Чтобы закрыть запущенное нами приложение, мы запускаем команду kill. При этом используется идентификатор контейнера, который можно найти с помощью команды docker ps.

# Kill our running container 
$ docker kill <container id> 
<container id> 

# Confirm that the app has stopped 
$ curl -i localhost:49160 
curl: (7) Failed to connect to localhost port 49160: Connection refused

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

Спасибо за чтение и удачного кодирования!

Первоначально опубликовано на https://hamon.in.