Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion locale/ru/docs/guides/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ layout: docs.hbs
* [Debugging - Getting Started](/ru/docs/guides/debugging-getting-started/)
* [Easy profiling for Node.js Applications](/ru/docs/guides/simple-profiling/)
* [Diagnostics - Flame Graphs](/en/docs/guides/diagnostics-flamegraph/)
* [Dockerizing a Node.js web app](/en/docs/guides/nodejs-docker-webapp/)
* [Докеризация веб-приложения Node.js](/ru/docs/guides/nodejs-docker-webapp/)
* [Migrating to safe Buffer constructors](/en/docs/guides/buffer-constructor-deprecation/)

## Ключевые концепции Node.js
Expand Down
278 changes: 278 additions & 0 deletions locale/ru/docs/guides/nodejs-docker-webapp.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,278 @@
---
title: Докеризация веб-приложения Node.js
layout: docs.hbs
---

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

Цель этого примера — показать, как поместить приложение Node.js в Docker-контейнер.
Это руководство предназначено для разработки, но не для прямого использования в
продакшене. Мы также предполагаем, что вы успешно [установили Docker](https://docs.docker.com/install/) на свой ПК и
имеете базовое представление о структуре Node.js приложения.

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

Docker позволяет вам упаковать приложение вместе с его окружением и всеми зависимостями в
"коробку", называемую контейнером. Обычно контейнер состоит из приложения, работающего в
упрощенной версии ОС Linux. Образ — это шаблон для контейнера, контейнер — это работающий
экземпляр образа.

## Создание приложения Node.js

Для начала создадим новую директорию, в которой будут находиться все файлы приложения. В этой директории
создайте файл `package.json`, в котором описано приложение и его зависимости:

```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.16.1"
}
}
```

После создания файла `package.json`, выполните команду `npm install`. Если вы используете `npm`
версии 5 или выше, это также создаст файл `package-lock.json`, который будет скопирован в ваш docker-образ.

Далее создайте файл `server.js`, который определяет веб-приложение на основе
фреймворка [Express.js](https://expressjs.com/):

```javascript
'use strict';

const express = require('express');

// константы
const port = 8080;
const host = '0.0.0.0';

// приложение
const app = express();
app.get('/', (req, res) => {
res.send('hello world\n');
});

app.listen(port, host);
console.log(`running on http://${host}:${port}`);
```

Далее мы рассмотрим, как можно запускать это приложение внутри Docker-контейнера,
используя официальный образ Docker'а. Сначала давайте создадим Docker-образ с нашим приложением.

## Создание файла Dockerfile

Создайте пустой файл с именем `Dockerfile`:

```markup
touch Dockerfile
```

Откройте этот файл в вашем любимом текстовом редакторе.

Первое, что нам надо сделать — определить базовый образ,
который будет взят за основу. Мы будем использовать образ `node` последней версии
LTS* (версии с долгосрочной поддержкой) — `10`,
доступный на [Docker Hub](https://hub.docker.com/).

\* Прим. переводчика: на момент написания статьи.

```docker
FROM node:10
```

Затем создадим директорию для кода приложения внутри образа.
Это будет рабочая папка для вашего приложения.

```docker
# создание директории приложения
WORKDIR /usr/src/app
```

Образ, который мы используем, поставляется с уже предустановленным Node.js и NPM.
Поэтому мы можем просто установить зависимости приложения с помощью команд `npm`.
Обратите внимание, если вы используете `npm` 4 или ниже, файл `package-lock.json`
не будет сгенерирован.

```docker
# установка зависимостей
# символ астериск ("*") используется для того чтобы по возможности
# скопировать оба файла: package.json и package-lock.json
COPY package*.json ./

RUN npm install
# Если вы создаете сборку для продакшн
# RUN npm ci --only=production
```

Обратите внимание, что вместо того, чтобы копировать весь рабочий каталог,
мы копируем только файл `package.json`. Это позволяет воспользоваться
кэшированием слоев в Docker. [Здесь](http://bitjudo.com/blog/2014/03/13/building-efficient-dockerfiles-node-dot-js/)
bitJudo дал хорошее объяснение того, как это работает. Более того,
команда `npm ci`, указанная в комментарии, позволяет создавать
более быстрые, надежные, воспроизводимые сборки для продакшена.
вы можете прочесть больше об этой команде [здесь](https://blog.npmjs.org/post/171556855892/introducing-npm-ci-for-faster-more-reliable).

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

```docker
# копируем исходный код
COPY . .
```

Сервер привязан к `8080` порту, поэтому мы будем использовать
инструкцию `EXPOSE`, чтобы проинформировать Docker о том, что в контейнере
имеется приложение, прослушивающее этот порт.

```docker
EXPOSE 8080
```

Последняя, но не менее важная команда `CMD` содержит все необходимые
переменные среды и инструкции для запуска приложения.
Здесь мы просто используем `node server.js` для запуска.

```docker
CMD [ "node", "server.js" ]
```

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

```docker
FROM node:10

# создание директории приложения
WORKDIR /usr/src/app

# установка зависимостей
# символ астериск ("*") используется для того чтобы по возможности
# скопировать оба файла: package.json и package-lock.json
COPY package*.json ./

RUN npm install
# Если вы создаете сборку для продакшн
# RUN npm ci --only=production

# копируем исходный код
COPY . .

EXPOSE 8080
CMD [ "node", "server.js" ]
```

## Файл .dockerignore

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

```
node_modules
npm-debug.log
```

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

## Сборка образа

Перейдите в директорию, в которой находится ваш `Dockerfile` и запустите
следующую команду, чтобы собрать Docker-образ. Флаг `-t` позволяет поставить
тэг к вашему образу, чтобы его позже было проще найти при помощи команды
`docker images`:

```bash
docker build -t <your username>/node-web-app .
```

Созданный образ теперь будет отображаться в списке всех образов:

```bash
$ docker images

# пример вывода
repository tag id created
node 10 1934b0b038d1 5 days ago
<your username>/node-web-app latest d64d3505b0d2 1 minute ago
```

## Запуск образа

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

```bash
docker run -p 49160:8080 -d <your username>/node-web-app
```

Отобразите логи вашего приложения:

```bash
# отобразить все контейнеры, чтобы получить id нужного нам
$ docker ps

# отобразить логи
$ docker logs <container_id>

# пример логов
running on http://localhost:8080
```

Если вам нужно попасть внутрь контейнера, используйте команду `exec`:

```bash
# войти в контейнер в интерактивном режиме
$ docker exec -it <container id> /bin/bash
```

## Проверка

Чтобы проверить ваше приложение, используйте публичный порт, к которому привязан контейнер:

```bash
$ docker ps

# пример вывода
id image command ... ports
ecce33b30ebf <your username>/node-web-app:latest npm start ... 49160->8080
```

В примере выше docker связал порт `8080` внутри контейнера с портом `49160`
на вашем компьютере.

Вы можете сделать запрос к вашему приложению с помощью утилиты `curl`
(установите ее, если требуется с помощью команды: `sudo apt-get install curl`):

```bash
$ 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
```

Надеемся, что эта инструкция помогла вам настроить и запустить простое приложение
Node.js с помощью Docker.

Вы можете найти больше информации о Docker и Node.js в docker по следующим ссылкам:

* [Официальный docker-образ Node.js](https://hub.docker.com/_/node/)
* [Руководство по лучшим практикам Node.js в Docker](https://github.com/nodejs/docker-node/blob/master/docs/bestpractices.md)
* [Официальная документация Docker](https://docs.docker.com/)
* [Тэг Docker на stack overflow](https://stackoverflow.com/questions/tagged/docker)
* [Канал Docker на reddit](https://reddit.com/r/docker)