SpecialistOff.NET / Вопросы / Статьи / Фрагменты кода / Резюме / Метки / Помощь / Файлы

Список вопросов Печать

Как упаковать приложение в контейнер Docker?


Метки: docker node.js html .dockerignore 

У меня есть приложение, написанное на NodeJS. Как я могу упаковать его в образ Docker, чтобы запускать как контейнер?

Ответы

vk39672097  Создано: 2017-12-08 20:52:20.959622  Обновлено: 2017-12-08 20:52:20.959622

Docker - система управления контейнерами в POSIX-совместимых операционных системах (на данный момент поддерживается Linux). Особенностью Docker является возможность упаковать приложение со всем необходимым окружением таким образом, чтобы запускать его на другой системе без долгих и сложных процедур установки зависимостей или сборки из исходников. Запакованное приложение, готовое к развёртыванию, называется "образом". Образы Docker основываются на "шаблонах" - предварительно настроенных рабочих окружениях. Можно рассматривать это как дистрибутивы операционной системы, хотя это и не совсем так. Кроме того, изучив документацию на Docker, вы сможете создать собственный шаблон. Преимуществом такого подхода является то, что образ вашего приложения будет содержать только само приложение, а необходимое для него окружение будет скачиваться автоматически из репозитория шаблонов. Docker слегка напоминает chroot или bsd jail, но работает иначе.

Важно различать для себя понятия "контейнер" и "образ". Контейнер - это выполняющаяся копия вашего приложения, а образ - это файл, в котором хранится приложение, и из которого и создаётся контейнер.

Предположим, что у вас есть приложение на NodeJS, которое вы хотите упаковать в контейнер. Предположим, что файл, который запускает ваше приложение называется server.js, а для работы приложение слушает порт 8000. В качестве шаблона мы будем использовать "node:carbon". Для контейнеризации приложения вам нужно создать в каталоге, где расположены файлы вашего приложения, файл "Dockerfile", в котором будут описаны параметры подготовки образа:

$ touch Dockerfile

Содержимое файла может быть примерно таким:

# Указываем используемый шаблон
FROM node:carbon
# Создаём рабочий каталог приложения внутри контейнера
WORKDIR /usr/src/app
# Устанавливаем зависимости приложения с помощью npm
# Копируются оба файла package.json И package-lock.json, если они присутствуют
COPY package*.json ./
RUN npm install
# Копируем в образ файлы вашего приложения
COPY . .
# Открываем порт 8000 чтобы он был доступен снаружи контейнера
EXPOSE 8000
# Выполняем команду для запуска приложения внутри контейнера
CMD [ "npm", "start" ]

Чтобы исключить ненужные файлы из образа, вы можете перечислить их имена в файле ".dockerignore". Допускается использование маски (*.log).

Сборка образа осуществляется следующей командой:

$ docker build -t username/node-web-app .

Где username - это условное имя автора образа, а node-web-app - имя образа. После сборки образ появляется в локальном хранилище образов. Вы можете увидеть список имеющихся образов, введя команду "docker images".

$ docker images

# Example
REPOSITORY                      TAG        ID              CREATED
node                            carbon     1934b0b038d1    5 days ago
username/node-web-app           latest     d64d3505b0d2    1 minute ago

Запуск контейнера из образа производится следующей командой:

$ docker run -p 49160:8000 -d username/node-web-app

В этом примере создаётся контейнер из образа "username/node-web-app" и сразу запускается. Порт приложения 8000 доступен на локальной машине (localhost) и для того, чтобы он был доступен "снаружи", он "пробрасывается" на порт 49160. Можно выбрать любой свободный порт, кроме того возможно пробросить порт приложения "как есть", указав опцию "-p 8000:8000".

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

$ docker ps

# Example
ID            IMAGE                                COMMAND    ...   PORTS
ecce33b30ebf  username/node-web-app:latest         npm start  ...   49160->8000

Управление контейнером можно осуществлять различными командами, указывая ID этого контейнера:

$ docker pause ecce33b30ebf    - приостановить работу контейнера с ID ecce33b30ebf
$ docker resume ecce33b30ebf   - возобновить работу контейнера с ID ecce33b30ebf
$ docker stop ecce33b30ebf     - остановить контейнер c ID ecce33b30ebf
$ docker rm ecce33b30ebf       - удалить контейнер (при этом удаляются все данные, созданные приложением внутри контейнера)

Возможно будут интересны и другие вопросы