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

Введение

Node.js - это среда выполнения jаvascript, которая в последние годы стала популярной для создания серверных приложений.
В этом руководстве показано, как развернуть приложение Node.js на облачном сервере через Docker, Docker Hub и Docker Compose.
Предпосылки
  • В этом руководстве предполагается, что в вашей локальной системе установлен Docker. Если у вас его нет, вы можете найти инструкции по его установке в официальной документации
  • У вас также должен быть облачный сервер с дистрибутивом Linux, предпочтительно Ubuntu 18.04. Если вы используете другой дистрибутив, вам, возможно, придется поискать конкретные инструкции, когда пришло время установить Docker на ваш сервер
  • Некоторые шаги также требуют наличия бесплатной учетной записи Docker Hub для загрузки образа Docker для приложения.
  • Если у вас нет предыдущего опыта работы с Docker, это нормально, это руководство довольно простое и объясняет основные концепции того, что мы делаем
О докере
Если вы только начинаете работать с Docker, вот несколько терминов, которые стоит пересмотреть, чтобы убедиться, что мы находимся на одном пути.
  • Изображения : в Docker изображения являются «снимками» или шаблонами файловой системы и содержат все, что необходимо для запуска приложения.
  • Контейнеры : это фактические запущенные экземпляры приложения. Они создаются путем взятия шаблона (изображения) и превращения его во что-то, что может быть запущено и имеет состояние
  • Слои - это элементы, которые составляют изображение Docker. Каждый слой построен поверх другого, что позволяет предоставлять функцию, называемую кэшированием слоев. Это означает, что вам не нужно перестраивать или повторно загружать все слои изображения, когда изменяется только один из них.
  • Реестры являются местом , где вы загружаете ( нажимные ) изображения , чтобы сделать их доступными для всего мира, или те , которые имеют учетные данные для доступа к нему. В этом руководстве мы собираемся использовать Docker Hub, но есть также альтернативы, предоставляемые GCP, AWS, Azure, GitHub и другими.

Шаг 1 - Создайте Dockerfile

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

WORKDIR /app

COPY package*.json .

RUN npm ci --only=production

COPY . .

EXPOSE 8080

CMD [ "node", "index.js" ]
Это Dockerfileместо, куда вы помещаете инструкции, которые позволяют Docker создавать образ. Каждая инструкция представляет создание слоя, который является модификацией создаваемой файловой системы изображения.
В этом случае мы создаем наше изображение, начиная с шаблона, иногда называемого базовым изображением , которое в данном случае является node:10.16. Это официальное изображение, предоставленное компанией Docker, и вы можете узнать больше об этом здесь .
Следующий шаг перемещает текущий рабочий каталог /app, в который будут выполняться следующие инструкции.
Линия COPY package*.json .имеет эффект копирования файлов package.jsonи package-lock.jsonв /appдиректорию образа файловой системы Докер. Обратите внимание, что точка в конце необходима для обозначения текущего каталога.
Теперь мы используем RUNинструкцию для установки производственных зависимостей с помощью npm ciкоманды, представленной в npm 5.7.0 .
На данный момент следует отметить одну вещь: до сих пор мы копировали в сборке только package*.jsonфайлы, а не весь каталог проекта. Это позволяет использовать кэширование слоев Docker, чтобы при неизменности зависимых пакетов слои можно было повторно использовать без их перестройки.
Следующая строка ( COPY . .) копирует остальные файлы на изображении. При желании мы можем сообщить Docker, что мы хотим предоставить определенный сетевой порт контейнера, чтобы через него можно было получить доступ к веб-приложению.
Наконец, последняя инструкция определяет команду, которая должна использоваться Docker для запуска приложения при запуске контейнера. В этом случае мы предполагаем, что точкой входа приложения является index.jsфайл.
Обычно хорошей идеей является создание файла с именем .dockerignoreвместе с Dockerfile. Это гарантирует, что при запуске COPY . .ненужные файлы с вашего компьютера не будут скопированы в образ:
.git
Dockerfile
node_modules
В этом случае нас не интересует наличие каталогов для разработки, подобных .gitили node_modulesдоступных внутри шаблона, который мы создаем.

Шаг 2 - Постройте изображение

Теперь, когда у нас есть Dockerfile, мы можем сказать Docker использовать его для создания образа.
Основная команда для этого выглядит следующим образом и должна быть выполнена в корневом каталоге проекта:
docker build -t myproject .
-tПараметр определяет имя изображения, в этом случае myproject. В .конце строки требуется указать Docker, что нужно искать Dockerfileв текущем каталоге.
ПРИМЕЧАНИЕ : при первом запуске сборки это займет некоторое время, поскольку Docker должен загрузить все слои базового образа (в этом случае Node.js 10.16).
Поскольку мы собираемся выгрузить это изображение в онлайн-реестр Docker Hub (чтобы сделать его доступным с нашего сервера), нам необходимо присвоить образу имя, используя определенное соглашение.
Поэтому приведенная выше команда будет выглядеть так:
docker build -t username/myproject:latest .
Где usernameваше имя пользователя Docker Hub, и latestявляется тег изображения. Изображение может иметь несколько тегов, поэтому иногда вы видите рабочий процесс, подобный следующему:
docker build -t myproject .
docker tag myproject username/myproject:latest
docker tag myproject username/myproject:20190926
Эти команды создают изображение, а затем помечают его тегами latestи 20190926(датой написания этого урока).
Docker Hub по умолчанию не удаляет старые изображения, поэтому это позволяет вести историю всех изображений, которые вы поместили в реестр. Изображение с тегом latestвсегда будет тем, которое было создано последним, а старшие будут помечены датой.

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

Теперь, когда у нас есть изображение, нам нужно отправить его в реестр. Прежде всего, выполните следующую команду, чтобы убедиться, что ваш экземпляр Docker аутентифицирован с помощью Docker Hub:
docker login
Затем запустите, docker pushчтобы загрузить изображение вместе со всеми тегами.
docker push username/myproject
Если ваше приложение маленькое, эта команда должна быть выполнена быстро, потому что она должна загружать только слои, соответствующие вашему приложению Node.js и его зависимостям jаvascript.
Когда у вас есть новая версия образа, вы должны снова запустить команду push, чтобы убедиться, что она загружена в Docker Hub.

Шаг 4 - Установите Docker в Ubuntu 18.04

Теперь мы можем перейти на сервер, чтобы установить Docker и Docker Compose. Как упоминалось в предварительных условиях, здесь предполагается, что у вас есть сервер Ubuntu 18.04, который уже запущен и работает.
Прежде всего, для установки Docker требуются системные зависимости, которые можно установить с помощью следующих команд:
sudo apt-get update
sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common
Теперь добавьте официальный ключ Docker GPG и настройте собственный репозиторий apt:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"
Наконец, обновите индекс apt еще раз и установите Docker Community Edition:
sudo apt-get update
sudo apt-get install docker-ce
Мы также собираемся установить Docker Compose 1.24.1, просто загрузив двоичный файл. Docker Compose - это инструмент, который значительно упрощает управление контейнерами и их жизненный цикл.
sudo curl -L "https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
Последний полезный шаг состоит в добавлении текущего пользователя Ubuntu в dockerгруппу, чтобы мы могли запускать команды Docker непосредственно из нее.
Это легко сделать с помощью следующей команды:
sudo gpasswd -a myuser docker
Убедитесь, что все прошло нормально, выполнив следующие команды:
docker --version
docker ps
docker-compose --version
Если вы не видите никаких ошибок или предупреждений, вы можете идти.

Шаг 5 - Запустите контейнер с Docker Compose

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

services:
  myproject:
    container_name: 'myproject'
    image: 'username/myproject'
    restart: unless-stopped
Это очень простой файл Docker Compose, который конфигурирует один вызываемый контейнер myprojectна основе username/myprojectобраза из Docker Hub. Если вы не укажете тег, он будет по умолчанию установлен на latest, но вы также можете установить определенный, если хотите:
version: '3'

services:
  myproject:
    container_name: 'myproject'
    image: 'username/myproject:20190901'
    restart: unless-stopped
Наконец, restartсвойство указывает, что контейнер должен автоматически перезапускаться при сбое, если он не был остановлен вручную.
Если вы сейчас выполните эту upкоманду 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:
version: '3'

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

Шаг 6 - Включить автоматические сборки (необязательно)

Фантастика, вы сейчас развернули первый выпуск своего контейнера Node.js приложения.
Если код вашего приложения размещен в git-репозитории на GitHub или BitBucket, у меня для вас отличная новость: процесс сборки Docker можно автоматизировать в облаке бесплатно с помощью Docker Hub.
Если вы перейдете на вкладку «Builds» своего изображения в Docker Hub, вам будет предложено создать похожую страницу:

После привязки вашей учетной записи GitHub или BitBucket выберите репозиторий, в котором находится ваш код и где он Dockerfileнаходится. Конфигурация по умолчанию, предлагаемая Docker Hub, подходит для первой сборки, поэтому нажмите кнопку «Сохранить и построить» и подождите.

Сборка Docker будет запущена в облаке через несколько минут, а затем вы найдете новое изображение с тегом, latestавтоматически помещенным в раздел « Теги ». Каждый новый коммит (push) в вашем git-репозитории теперь будет вызывать новую сборку.

Шаг 7 - Развертывание новой версии

Допустим, вам нужно опубликовать изменение в вашем приложении. Если вы не включили автоматические сборки, вам нужно будет повторить шаги 2 и 3, чтобы в Docker Hub появилось новое изображение.
Затем на вашем сервере вы должны вручную извлечь новый образ, например так:
docker-compose -f docker-compose.yml pull
И перезапустите контейнер с новым изображением:
docker-compose -f docker-compose.yml up -d --force-recreate

Заключение

Отлично, ты сделал это! Это было базовое введение в развертывание приложения Node.js в Ubuntu 18.04 с использованием Docker, Docker Hub и Docker Compose.
Мы увидели, как написать простое Dockerfile, как создать образ, отправить его и развернуть на сервере. Настройка автоматических сборок полезна и является первым шагом в мир непрерывной интеграции и доставки (CI / CD).
В Docker есть еще много всего, что не рассматривается в этом руководстве, поэтому обязательно ознакомьтесь с документацией по Docker и Docker Compose, чтобы узнать больше о концепциях и функциях.

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

Автору будет очень приятно узнать обратную связь о своем руководстве.

Комментариев 0