Как развернуть приложение Node.js с помощью Docker

0 Акции
0
0
0
0

Введение

Node.js — это среда выполнения JavaScript, которая в последние годы стала популярной для создания серверных приложений.

В этом руководстве показано, как развернуть приложение Node.js на облачном сервере с помощью Docker, Docker Hub и Docker Compose.

Предпосылки
  • В этом руководстве предполагается, что Docker установлен на вашей локальной системе. Если у вас его нет, инструкции по установке можно найти в официальной документации.
  • Вам также понадобится облачный сервер под управлением дистрибутива Linux, предпочтительно Ubuntu 24.04. Если вы используете другой дистрибутив, вам может потребоваться следовать специальным инструкциям по установке Docker на сервер.
  • Для некоторых шагов также потребуется учетная запись Docker Hub (бесплатно) для загрузки образа Docker для приложения.
  • Если у вас нет опыта работы с Docker, ничего страшного, это руководство очень простое и объясняет основные концепции того, что мы делаем.
  • Вам необходимо приложение Node.js, которое вы можете развернуть.
О Докере

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

  • Образы: в Docker образы представляют собой «снимки» или шаблоны файловой системы и содержат все необходимое для запуска приложения.
  • Контейнеры: это фактически работающие экземпляры приложения. Они создаются путём преобразования шаблона (образа) в нечто, что можно запустить и которое имеет состояние.
  • Слои — это элементы, из которых состоит образ Docker. Каждый слой строится поверх другого, что позволяет реализовать функцию кэширования слоёв. Это означает, что при изменении хотя бы одного слоя в образе вам не нужно перестраивать или перезагружать все слои образа.
  • Реестры — это место, куда вы загружаете (push) образы, чтобы сделать их доступными для всего мира или для тех, у кого есть учётные данные. В этом руководстве мы будем использовать Docker Hub, но существуют и альтернативы, предоставляемые GCP, AWS, Azure, GitHub и другими.

Шаг 1 — Создание Dockerfile

Создайте файл Dockerfile со следующим содержимым в корневом каталоге вашего проекта Node.js:

FROM node:20.17
ENV NODE_ENV=production
WORKDIR /app
COPY package*.json .
RUN npm ci
COPY . .
EXPOSE 8080
CMD [ "node", "src/index.js" ]

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

В данном случае мы создаём образ на основе шаблона, иногда называемого базовым образом, в данном случае это node:20.17. Это официальный образ, предоставленный компанией Docker, и вы можете найти о нём больше информации здесь.

Следующий шаг устанавливает переменную окружения NODE_ENV в режим production. Основной эффект заключается в том, чтобы избежать установки пакетов разработки при запуске следующей установки npm, но часто это может привести к лучшей оптимизации модулей, которые могут вам понадобиться.

С помощью команды WORKDIR мы перемещаем текущий каталог в /app, который, в свою очередь, становится каталогом, в котором выполняются следующие инструкции.

Строка пакета COPY*.json . Копирует файлы package.json и package-lock.json в папку /app файловой системы образа Docker. Обратите внимание, что точка в конце указывает на текущий каталог.

Теперь мы используем директиву RUN для установки производственных зависимостей с помощью команды npm ci (ci означает чистую установку и предназначено для использования в автоматизированных средах).

На этом этапе стоит отметить, что до сих пор мы копировали в сборку только файлы package*.json, а не весь каталог проекта. Это позволяет нам воспользоваться кэшированием слоёв Docker, так что если зависимые пакеты не изменились, слои можно использовать без пересборки.

Следующая строка (COPY . .) копирует оставшиеся файлы в образе.

При желании мы можем указать, что хотим открыть доступ к определённому сетевому порту из контейнера для веб-приложения. Обратите внимание, что директива EXPOSE фактически не открывает порт: как говорится в документации, она «действует как своего рода документ между создателем образа и пользователем контейнера о портах, которые должны быть опубликованы». .

Наконец, последняя директива определяет команду, которую Docker должен использовать для запуска приложения при запуске контейнера. В данном случае мы предполагаем, что точкой входа приложения является файл index.js.

Обычно рекомендуется создать файл .dockerignore вместе с Dockerfile. Это гарантирует, что при запуске COPY.. ненужные файлы с вашего компьютера не будут скопированы в образ:

.git
Dockerfile
node_modules

В этом случае мы не хотим, чтобы версии каталогов, такие как git или node_modules, находящиеся на стадии разработки, были доступны в создаваемом нами шаблоне.

Шаг 2 — Создание изображения

Теперь, когда у нас есть Dockerfile, мы можем указать Docker использовать его для создания образа.

Базовая команда для этого выглядит следующим образом и должна быть запущена в основной папке проекта:

docker build -t myproject .

Если установка не завершится успешно и возникнет ошибка “/bin/sh -c npm ci”, замените npm ci в Dockerfile на npm install и повторите попытку.

 

Опция -t задаёт имя образа, в данном случае myproject. В конце строки нужно указать Docker, что нужно искать Dockerfile в текущем каталоге.

Примечание: Первый запуск сборки займет некоторое время, поскольку Docker необходимо загрузить все слои базового образа (в данном случае Node.js 20.17).

Поскольку мы планируем загрузить этот образ в онлайн-реестр Docker Hub (чтобы получить к нему доступ с нашего сервера), нам необходимо назвать образ, используя определенное соглашение об именовании.

Таким образом, приведенная выше команда будет выглядеть так:

docker build -t username/myproject:latest .

Где username — ваше имя пользователя Docker Hub, а last — тег образа. У образа может быть несколько тегов, поэтому иногда можно увидеть рабочий процесс, похожий на этот:

docker build -t myproject .
docker tag myproject username/myproject:latest
docker tag myproject username/myproject:20240905

Эти команды создают изображение, а затем присваивают ему теги latest и 20240904 (дата последнего обновления этого руководства).

Docker Hub по умолчанию не удаляет старые образы, поэтому позволяет вести историю всех образов, отправленных в реестр. Образ с последним тегом всегда соответствует образу, собранному последней версией, а более старые образы помечаются датой.

Шаг 3 — Нажмите на изображение

Теперь, когда у нас есть образ, нам нужно отправить его в реестр. Для начала выполните следующую команду, чтобы убедиться, что ваш экземпляр Docker аутентифицирован в Docker Hub:

docker login

Затем запустите docker push, чтобы загрузить образ вместе со всеми тегами.

docker push username/myproject

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

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

Шаг 4 — Установка Docker в Ubuntu 24.04

Теперь мы можем перейти к установке Docker и Docker Compose на сервер. Как уже упоминалось в предварительных требованиях, предполагается, что у вас уже настроен сервер Ubuntu 24.04.

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

sudo apt-get update
sudo apt-get install ca-certificates curl

Теперь добавьте официальный ключ Docker GPG и настройте пользовательский репозиторий apt:

sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Наконец, обновите каталог apt еще раз и установите Docker Community Edition:

sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Приведенная выше команда также устанавливает Docker Compose — инструмент, который значительно упрощает управление контейнерами и их жизненным циклом.

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

Это можно легко сделать с помощью следующей команды:

sudo gpasswd -a myuser docker

Убедитесь, что все прошло успешно, выполнив следующие команды:

docker --version
docker ps
docker compose version

Если вы не видите никаких ошибок или предупреждений, все готово.

Шаг 5 — Запуск контейнера с помощью Docker Compose

Создайте на сервере файл docker-compose.yml со следующим содержимым:

services:
myproject:
container_name: 'myproject'
image: 'username/myproject'
restart: unless-stopped

Это очень простой файл Docker Compose, который настраивает один контейнер с именем myproject на основе имени пользователя/образа myproject из Docker Hub. Если метка не указана, по умолчанию будет использоваться последняя, но вы также можете указать конкретную метку:

services:
myproject:
container_name: 'myproject'
image: 'username/myproject:20240904'
restart: unless-stopped

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

Если вы выполните эту команду Compose сейчас, образ Docker будет отменен, и ваше приложение, как мы надеемся, запустится:

docker compose -f docker-compose.yml up

Эта команда создаёт контейнер и запускает его. Вывод контейнера перехватывается Docker и отображается в консоли. Нажмите CTRL + C (или CMD + C) и подождите несколько секунд, пока контейнер не остановится.

Если всё прошло успешно, теперь вы готовы запустить контейнер как призрак, чтобы он продолжал работать в фоновом режиме до остановки. Это можно сделать, добавив опцию -d к команде:

docker compose -f docker-compose.yml up -d

Бум, узел! (О, я серьёзно)

Обязательно ознакомьтесь со справочной документацией по Compose-файлу, где вы найдете полезные функции, такие как сопоставление сетевых портов между сервером и контейнером. Вот небольшой пример сопоставления внешнего порта 80 с внутренним портом 8080:

services:
myproject:
container_name: 'myproject'
image: 'username/myproject'
restart: unless-stopped
ports:
- '80:8080'

Шаг 6 — Установка новой версии

Предположим, вам нужно выпустить изменение в приложении. Если у вас не включены автоматические сборки, вам придётся повторять шаги 2 и 3, пока в Docker Hub не появится новый образ.

Затем вам необходимо вручную загрузить новое изображение на свой сервер, вот так:

docker compose -f docker-compose.yml pull

И перезапустите контейнер с новым образом:

docker compose -f docker-compose.yml up -d --force-recreate

Результат

Отлично, вы справились! Это было базовое введение в развёртывание приложения Node.js в Ubuntu 24.04 с использованием Docker, Docker Hub и Docker Compose.

Мы увидели, как написать простой Dockerfile, как создать образ, отправить его и развернуть на сервере.

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может понравиться