Цель этого примера — показать вам, как поместить Node.js приложение в контейнер Docker. Руководство предназначено для разработки, а не для производственного развертывания. Руководство также предполагает, что у вас есть работающий Докер установка и базовое понимание того, как Node.js приложение структурировано.
В первой части этого руководства мы создадим простое веб-приложение в Node.js, затем создадим образ Docker для этого приложения и, наконец, создадим экземпляр контейнера из этого образа.
Docker позволяет вам упаковать приложение вместе с его окружением и всеми его зависимостями в «коробку», называемую контейнером. Обычно контейнер состоит из приложения, работающего в упрощенной версии операционной системы Linux. Образ — это схема контейнера, контейнер — это работающий экземпляр образа.
Создать Node.js приложение
Сначала создайте новый каталог, в котором будут находиться все файлы. В этом каталоге создайте package.json
файл, описывающий ваше приложение и его зависимости.:
{
"name": "docker_web_app",
"version": "1.0.0",
"description": "Node.js on Docker",
"author": "First Last <first.last@example.com>",
"main": "server.js",
"scripts": {
"start": "node server.js"
},
"dependencies": {
"express": "^4.18.2"
}
}
Используя новый package.json
файл, запустите npm install
. Если вы используете npm
версию 5 или новее, при этом будет создан package-lock.json
файл, который будет скопирован в ваш образ Docker.
Затем создайте server.js
файл, который определяет веб-приложение, используя Express.js фреймворк:
'use strict';
const express = require('express');
// Constants
const PORT = 8080;
const HOST = '0.0.0.0';
// App
const app = express();
app.get('/', (req, res) => {
res.send('Hello World');
});
app.listen(PORT, HOST, () => {
console.log(`Running on http://${HOST}:${PORT}`);
});
На следующих шагах мы рассмотрим, как вы можете запустить это приложение внутри Docker контейнера, используя официальный образ Docker. Сначала вам нужно создать Docker образ вашего приложения.
Создание файла Dockerfile
Создайте пустой файл с именем Dockerfile
:
touch Dockerfile
Откройте Dockerfile
в вашем любимом текстовом редакторе
Первое, что нам нужно сделать, это определить, из какого образа мы хотим создать. Здесь мы будем использовать последнюю версию LTS (долгосрочной поддержки), 18
node
доступную на Docker Hub:
FROM node:18
Затем мы создаем каталог для хранения кода приложения внутри изображения, это будет рабочий каталог для вашего приложения:
# Create app directory
WORKDIR /usr/src/app
Этот образ поставляется с Node.js и NPM уже установлен, поэтому следующее, что нам нужно сделать, это установить зависимости вашего приложения с помощью npm
двоичного файла. Пожалуйста, обратите внимание, что если вы используете npm
версию 4 или более раннюю, package-lock.json
файл не будет создан.
# 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 --omit=dev
Обратите внимание, что вместо копирования всего рабочего каталога мы копируем только package.json
файл. Это позволяет нам воспользоваться преимуществами кэшированных слоев Docker . У bitJudo есть хорошее объяснение этого. здесь. Кроме того, npm ci
команда, указанная в комментариях, помогает обеспечивать более быстрые, надежные и воспроизводимые сборки для производственных сред. Подробнее об этом можно прочитать здесь.
Чтобы поместить исходный код вашего приложения в образ Docker, используйте COPY
инструкцию:
# Bundle app source
COPY . .
Ваше приложение привязывается к порту, 8080
поэтому вы будете использовать EXPOSE
инструкцию для его настройки сопоставление с docker
демоном:
EXPOSE 8080
И последнее, но не менее важное: определите команду для запуска вашего приложения, используя CMD
которая определяет вашу среду выполнения. Здесь мы будем использовать node server.js
для запуска вашего сервера:
CMD [ "node", "server.js" ]
Теперь ваше Dockerfile
должно выглядеть следующим образом:
FROM node:18
# Create 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 --omit=dev
# Bundle app source
COPY . .
EXPOSE 8080
CMD [ "node", "server.js" ]
файл .dockerignore
Создайте .dockerignore
файл в том же каталоге, что и ваш Dockerfile
, со следующим содержимым:
node_modules
npm-debug.log
Это позволит избежать локальных модулей и журналы отладки могут быть скопированы на ваш Установленный образ Docker и, возможно, переписывая модули в ваш образ.
Создание вашего имиджа
Перейдите в каталог, в котором находится ваше приложение, Dockerfile
и запустите следующую команду для создания образа Docker. Флаг -t
позволяет пометить изображение, чтобы его было легче найти позже с помощью docker images
команды:
docker build . -t <your username>/node-web-app
Теперь ваше изображение будет отображаться в Docker:
$ docker images
# Example
REPOSITORY TAG ID CREATED
node 18 78b037dbb659 2 weeks ago
<your username>/node-web-app latest d64d3505b0d2 1 minute ago
Запустите образ
Запуск вашего изображения с помощью -d
запускает контейнер в отключенном режиме, оставляя контейнер запущенным в фоновом режиме. Флаг -p
перенаправляет общедоступный порт на частный порт внутри контейнера. Запустите созданный ранее образ:
docker run -p 49160:8080 -d <your username>/node-web-app
Распечатайте выходные данные вашего приложения:
# Get container ID
$ docker ps
# Print app output
$ docker logs <container id>
# Example
Running on http://localhost:8080
Если вам нужно зайти внутрь контейнера, вы можете использовать команду exec
:
# Enter the container
$ docker exec -it <container id> /bin/bash
Тест
Чтобы протестировать ваше приложение, получите порт вашего приложения, сопоставленный Docker:
$ docker ps
# Example
ID IMAGE COMMAND ... PORTS
ecce33b30ebf <your username>/node-web-app:latest npm start ... 49160->8080
В приведенном выше примере Docker сопоставил 8080
порт внутри контейнера с портом 49160
на вашем компьютере.
Теперь вы можете вызывать свое приложение с помощью curl
(при необходимости установить через: sudo apt-get install curl
):
$ curl -i localhost:49160
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/html; charset=utf-8
Content-Length: 12
ETag: W/"c-M6tWOb/Y57lesdjQuHeB1P/qTV0"
Date: Mon, 13 Nov 2017 20:53:59 GMT
Connection: keep-alive
Hello world
Завершите работу с изображением
Чтобы завершить работу запущенного приложения, мы запускаем kill
команду. При этом используется идентификатор контейнера, который в этом примере был ecce33b30ebf
.
# 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
Мы надеемся, что это руководство помогло вам освоить и запустить простое Node.js приложение в Docker.