Как выбрать образ Docker для node.js

Node.js

Приложения Node.js обычно используютсяpm2илиdockerДля развертывания, если вы планируете развертывание с помощью докера, вы также можете столкнуться с проблемой выбора образа узла.Официальный предоставляет следующие три типа вариантов:

  1. node:<version>: это официальный образ по умолчанию, основанный на сборке Debian, указанные версии:

    • Debian 10 (buster) — текущий стабильный выпуск (stable)
    • Debian 9 (растянутый) — старая стабильная версия
    • Debian 8 (jessie) — старая стабильная версия (oldoldstable)
    • Debian 7 (wheezy) — устаревшая стабильная версия

    Эти образы основаны наbuildpack-depsЧтобы построить, вы можете посмотреть его здесьDockerfile, преимущество этого типа образа в том, что установленные зависимости очень полны, напримерcurl,wget, недостатком является слишком большой объем.

  2. node:<version>-slim: это упрощенная версия образа после удаления избыточных зависимостей.Он также основан на debian и намного меньше, чем образ по умолчанию.Многие общедоступные программные пакеты были удалены, и сохранена только самая базовая операционная среда узла.

  3. node:<version>-alpine: эта версия основана на образе alpine, который меньше, чем тонкая версия debian, и можно сказать, что это самый маленький образ узла. Хоть он и небольшой по размеру, но функций у него много.Обычные приложения node.js могут запускаться, но если в проекте используются расширения C++, не используйте это, т.к. alpine использует musl вместо glibc, некоторое ПО в c/ Среда c++ может быть несовместима.

Затем, основываясь на версии node.js 14, загрузите три вышеуказанных типа изображений для сравнения:

docker pull node:14-buster
docker pull node:14-buster-slim
docker pull node:14-alpine

Сравнение размеров зеркал

бегатьdocker images | grep node:

node           14-buster           70c62b76e4cc        5 hours ago         912MB
node           14-buster-slim      9917d232c3dd        5 hours ago         181MB
node           14-alpine           9db54a688554        5 hours ago         117MB

Вы можете увидеть зеркало по умолчаниюnode:14-busterобъем до912MB, слишком велик по сравнению сnode:14-buster-slimгораздо меньше, при этомnode:14-alpineявляется более легким.

Сравнение использования памяти контейнера

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

docker run -d --name node-14-buster node:14-buster node -e "require('http').createServer((req, res) => res.end('Hello World')).listen(3030)"

docker run -d --name node-14-buster-slim node:14-buster-slim node -e "require('http').createServer((req, res) => res.end('Hello World')).listen(3030)"

docker run -d --name node-14-alpine node:14-alpine node -e "require('http').createServer((req, res) => res.end('Hello World')).listen(3030)"

бегатьdocker statsПросмотр использования памяти во время выполнения

NAME                  CPU %   MEM USAGE/LIMIT     MEM %   NET I/O   BLOCK I/O    PIDS
node-14-alpine        0.00%   4.809MiB/1.796GiB   0.26%   0B/0B     0B/0B        7
node-14-buster-slim   0.00%   4.238MiB/1.796GiB   0.23%   0B/0B     0B/0B        7
node-14-buster        0.00%   4.207MiB/1.796GiB   0.23%   0B/0B     4.88MB/0B    7

Разница не большая, но память, занимаемая alpine, чуть выше, но все в пределах допустимого.

как выбрать?

С точки зрения приложения node.js, как выбрать зеркало? Самая большая разница между alpine и buster/buster-slim заключается в плагине C++, например, ваш пакет используетsharpЕсли этот пакет обрабатывает образ, образ alpine нельзя использовать, поскольку он несовместим. В других случаях, если ваше приложение и зависимости написаны исключительно на node.js и не включают плагины C++, рекомендуется использовать образы alpine.

Образ buster/buster-slim может запускать все проекты node.js, включая эти зависимости C++, но есть дыра.npm startЗапущенный проект не может отслеживать сигнал SIGTERM от докера. Если у процесса нет соответствующего события SIGTERM, докер по умолчанию ждет 10 секунд, а затем принудительно убивает приложение. Шаги теста следующие:

  1. Сначала создайтеcodeпапка, пишиindex.js:

    console.log('pid', process.pid)
    process.on('exit', (code) => {
      console.log('进程 exit 事件的代码: ', code)
    })
    process.on('SIGTERM', (code) => {
      console.log('SIGTERM', code)
      process.exit(0)
    })
    require('http').createServer((req, res) => res.end('Hello World')).listen(3030)
    
  2. Затем создайте package.json:

    {
      "scripts": {
        "start": "node index.js"
      }
    }
    
  3. Запустите контейнер:

    docker run -d --name node-14-buster -v /code:/code node:14-buster sh -c 'cd code && npm start'
    docker run -d --name node-14-buster-slim -v /code:/code node:14-buster sh -c 'cd code && npm start'
    docker run -d --name node-14-alpine -v /code:/code node:14-alpine sh -c 'cd code && npm start'
    
  4. перезапустить контейнер

    При перезапуске образа buster/buster-slim обнаруживается, что скорость очень низкая, достигая тайм-аута в 10 секунд, что связано с отсутствием ответа на сигнал SIGTERM, отправленный докером, что можно проверить с помощью следующего кода:

    docker logs -f node-14-buster
    # 然后开新命令行
    docker kill -s SIGTERM node-14-buster
    docker restart node-14-buster
    

    И buster, и buster-slim не могут принимать сигналы SIGTERM, а alpine может.

пользовательское изображение

По совпадению, наш текущий проект использует как плагины C ++, так и мониторинг событий SIGTERM.Три типа изображений, предоставленных официальным лицом, не могут быть использованы, но также легко настроить образ node.js на основе других операционных систем, например создать на основе системы Centos7.Dockerfile выглядит следующим образом:

FROM centos:7
RUN curl -L https://dl.yarnpkg.com/rpm/yarn.repo -o /etc/yum.repos.d/yarn.repo
RUN curl --silent --location https://rpm.nodesource.com/setup_14.x | bash -
RUN yum install -y nodejs yarn
WORKDIR /code
EXPOSE 80
CMD npm start

Затем создайте образ node.js:

docker build -t node:14-centos7 .