Docker автоматически перезапустит npm install на package.json change - PullRequest
0 голосов
/ 21 сентября 2018

Я пытаюсь настроить контейнеры development для проекта node.js, чтобы мои локальные исходные файлы были доступны гостю (чтобы я мог dnsmasq подстановочные запросы к локальному домену через порт80, но я думаю, что это не имеет отношения к вопросу).Когда я делаю изменение локально, процесс узла в контейнере перезапускается:

Dockerfile:

FROM node:8

# Install app dependencies
RUN npm install -g nodemon
COPY package.json /tmp/package.json
RUN cd /tmp && npm install --production

NODE_PATH=/tmp/node_modules
WORKDIR /app

EXPOSE 8080
EXPOSE 9229

CMD nodemon --inspect index.js

docker-compose.json (усечено):

version: '3.3'
services:
    app:
        build: .
        container_name: 'my-app'
        restart: unless-stopped
        ports:
            - 8080:8080
            - 9229:9229
        volumes:
            - .:/app

Поскольку node_modules установлены в Dockerfile, каждый раз, когда я добавляю пакет в packages.json, мне приходится вручную перестраивать контейнер:

docker-compose stop
docker-compose build
docker-compose up -d

Я могу настроить часыдля этого используется inotify, но я не люблю останавливать весь стек (включая другие службы, определенные в нем).

Возможно ли иметь эту логику внутри контейнера и повторнозапустить npm install каждый раз, когда package.json изменяется?

Ответы [ 2 ]

0 голосов
/ 21 сентября 2018

Решение

Я написал файл ввода, который запускает два потока в node.js, поэтому Dockerfile может быть очень ванильным.Теперь все, что нам нужно, это docker-compose.

Dockerfile

FROM node:8
RUN npm install -g nodemon

docker-compose.yml

version: '3.5'
services:
    app:
        build: .
        user: '1000'
        working_dir: /opt/app
        ports:
            - 8080:8080
            - 9229:9229
        volumes:
            - ./:/opt/app
        command: 'node docker-entry.js'

docker-entry.js

/**
 * @file docker-entry for development container
 * @author Redsandro (https://www.windowsremix.com/)
 */
'use strict'
const { spawn } = require('child_process')

/*
 * Install dependencies every time package.json changes
 */
spawn('nodemon -w package.json --exec "npm install"', {
    stdio: 'inherit',
    shell: true
})

/*
 * Restart node when a source file changes, plus:
 * Restart when `npm install` ran based on `package-lock.json` changing.
 */
spawn('nodemon --inspect -e js,json -i node_modules -i package.json index.js', {
    stdio: 'inherit',
    shell: true
})

.dockerignore

# Just ignore everything
**

Это работает, потому что package-lock.json изменяется при добавлении или обновлении зависимостей.Так что npm 5 требуется.Не тестировался на изображениях других узлов.

Убедитесь, что в вашем рабочем каталоге нет node_modules или package-lock.json при первом запуске.Приложение внутреннего узла будет аварийно завершать работу при первом запуске (очевидно, оно не может найти зависимости), но оно будет перезапущено после установки зависимостей.

Введите docker-compose up -d && docker-compose logs -f, чтобы увидеть результаты.Сделайте некоторые изменения в файлах и добавьте пакет to package.json.

Каждый раз, когда вы запускаете контейнер, будет запускаться npm install, что необязательно 9 из 10 раз, если вы не измените package.json, покаконтейнер был остановлен.Это нормально, потому что приложение узла запускается параллельно, вам не нужно ждать, пока это завершится. Вы можете использовать контейнер немедленно.(Если, конечно, это не ваш первый запуск.)

Чтобы сделать: Я надеялся переместить node_modules в какой-нибудь гостевой каталог (например, /tmp), чтобы все эти данные былихранится на докере, а не на моем ноутбуке ssd.Что еще более важно, ваш хост и гость теперь используют одни и те же node_modules. Если вы используете не-linux ОС и скомпилированные пакеты, у вас будет плохое время.Потому что он будет работать либо на хосте, либо на госте, но не на обоих.Кажется, я не могу указать другой установочный каталог для npm, как я делал до без npm, записывая туда же package-lock.json, , и этот файл необходим в локальном каталоге для работы этой установки.Я уверен, что с некоторыми умными связями это может работать, но я исчерпал время, которое я выделил для этого решения.Советы приветствуются.Не стесняйтесь добавлять дополнения и другие ответы.

0 голосов
/ 21 сентября 2018

Возможно ли иметь эту логику внутри контейнера и перезапускать npm install каждый раз при изменении package.json?

Мне не совсем понятно, если вашизменения в package.json выполняются на хосте или в контейнере Docker в каталоге / tmp /.Я предполагаю, что вы модифицируете файл на хосте, так как у вас есть другие файлы проекта.

Если вы модифицируете package.json в другом месте, чем / tmp / в вашем контейнере, вам нужно вручную скопировать новую версию package.jsonв / tmp в контейнере

docker cp "location/of/package.json" "containername":/tmp/

, затем вы просто вводите контейнер и устанавливаете зависимости.

docker exec -it containername bash
cd /tmp/
npm install

Возможно ли иметь эту логику внутри контейнера и повторнозапускать npm install каждый раз при изменении package.json?

Вы можете передать описанную выше логику в простой скрипт bash.Затем вы можете запустить некоторый watcher (например, nodemon), чтобы наблюдать package.json и запустить скрипт после изменения файла.Возможно, было бы также неплохо пропустить большую задержку, чтобы он не пытался установить модуль до того, как вы введете его полное имя.Но в большинстве случаев, я думаю, вы просто используете команду npm вместо того, чтобы вводить имя модуля вручную.

...