Node.js Recipes
3.23K subscribers
174 photos
7 videos
1 file
622 links
По буднях нотатки по #Nodejs розробці, по вихідним огляди конференцій та доповідей (с) @galkin_nikita
Download Telegram
Когда можно считать, что вышла новая версия Node.js?
#docker #devops

У #Nodejs есть официальный график выхода и поддержки мажорных версий. Так 20 апреля ожидается первый релиз 16 версии Node.js.
Выход минорных и патч версий не имеет графика, а определяется Node.js Release Working Group.
Например, 6 апреля была опубликована версии 14.16.1. Спустя 24 часа Node.js Docker Working Group опубликовали эту версию на Docker Hub.
Еще раз, за выпуск binary и Docker image отвечают разные люди, поэтому задержка составляет сутки и более.
В современных проектах Node.js запускается как Docker контейнер, поэтому именно появление новой версии Docker Image стоит считать выходом новой версии.
Вы заметили в вашем Docker Desktop вкладку Dev Environments? Там пока нет ничего кроме интро видео. Мы узнаем детали 27 мая на DockerCon Live 2021.

➡️ Бесплатная регистрация
#conference #docker #freebies
How to Build and Run Node Apps with Docker and Compose
#worth_seeing #docker

Доклад с прошлого DockerCon. Он особенно полезен для начинающих #nodejs разработчиков. Если вы опытный разработчик, то рекомендую посмотреть весь плейлист, откуда взят этот доклад.
Как понять запущен ли Node.js внутри Docker?
#nodejs_api #docker

Docker контейнеры созданы, чтобы запускать только один процесс. У этого процесса id всегда 1. Рекомендуемый запуск #nodejs:
ENTRYPOINT ["node", "src/index.js"]
Тогда на уровне кода легко проверить
const isDocker = process.pid === 1

Кроме айди текущего процесса (process.pid), у нас есть айди родительского процесса – process.ppid. Для стартового процесса он равен 0.

Если вы запускаете через npm run ..., то npm будет иметь pid=1 и являться родительским процессом для Node.js. Так делать не следует.

Возможные варианты использования:

1️⃣ При локальной разработке использовать человекочитаемые логи, а внутри Docker в формате json:
const pino = require('pino');
const logger = pino({ prettyPrint: process.pid !== 1 });
Требует pino-pretty.

2️⃣ Переходить в debug режим по нажатию ctrl+T.
if (process.pid !== 1) {
process.on('SIGINFO', () => {
require('inspector').open();
});
}
Это автоматизация для дебага запущенного процесса. Без нее сначала узнаем айди процесса через ctrl+T, а потом делаем kill -SIGUSR1 <pid>
Как тестировать Dockerfile?
#package #docker

При анализе проектов я часто вижу, что нет проверки Dockerfile. Так на одном из проектов выяснилось, что сборка Docker image сломана два с половиной месяца.
Поэтому CI должен проверять, что:
➡️ Docker image собирается
➡️ Docker container стартует
➡️ health-check отдает успешный ответ

Если на проекте существуют e2e тесты, то #nodejs необходимо запускать как и в продакшене – как контейнер. Для этого отлично подходит пакет testcontainers. Он позволяет работать с Docker контекстом из кода. Вот пример из документации:

const path = require("path");
const { GenericContainer } = require("testcontainers");
const buildContext = path.resolve(__dirname, "dir-containing-dockerfile");
const container = await GenericContainer.fromDockerfile(buildContext)
.withBuildArg("ARG_KEY", "ARG_VALUE")
.build();
const startedContainer = await container
.withExposedPorts(8080)
.start();
Как использовать ARG и ENV внутри Dockerfile?
#docker

Сегодня обсудим две инструкции внутри Dockerfile: ARG и ENV.

TL;DR Используйте ARG для определения build-time переменных, а ENV – run-time. Используйте ENV=arg_var_name, чтобы создать образ с переменной определяемой в ходе сборки.

Инструкция ARG определяет build-time variables. Они доступны только во время сборки docker image во всех инструкциях включая FROM. Запущенный контейнер не могут получить к доступ к этим переменным. Это также относится к инструкциям CMD и ENTRYPOINT, которые определяют, что контейнер должен запускать по умолчанию. Если вы не указываете значение по умолчанию для ARG, то при сборке передача аргументов обязательна. Для этого используется --build-arg. Пример:
ARG some_variable_name
# or with a hard-coded default:
#ARG some_variable_name=world
RUN echo "Hello $some_variable_name"

$ docker build --build-arg some_variable_name=a_value

Переменные ENV также доступны во время сборки. Однако, в отличие от ARG, они доступны внутри запущенного контейнера. Значения ENV можно переопределить при запуске контейнера.

ENV и ARG можно комбинировать вместе.

Пример из реального проекта:

FROM node:14.17.1-alpine

ARG VERSION=latest
ENV VERSION=$VERSION
ENV PORT=8000
WORKDIR /opt/app/

COPY package.json package-lock.json /opt/app/
RUN npm install --production
COPY src /opt/app/

EXPOSE $PORT
ENTRYPOINT ["node", "/opt/app/index.js"]

Внутри запущенного контейнера можно использовать переменные окружения PORT и VERSION