LINUX.ORG.RU

Docker не реагирует на изменения файлов в хост-системе

 ,


0

6

В докер монтирую каталог из хост системы. Важный момент - при редактировании файлов в хост системе, изменения в докере видны. Т.е. в хост-системе есть файл «file.txt» с таким содержанием:

test
В контейнере выполним cat и получим, ожидаемо, test.

Отредактируем файл:

test123
В контейнере выполним cat и получим, ожидаемо, test123.

Но вот беда, при редактировании файла моего проекта, server.js, изменения не подхватываются. Я подумал, что не хватает какого-нибудь forever.js, который бы мониторил изменения и перезапускал проект, поставил его, написал простой конфиг:

var forever = require('forever-monitor');

var child = new (forever.Monitor)('server.js', {
    sourceDir: __dirname,
    silent: false,
    watch: true
});

child.start();
Поправил package.json:
{
    ...
    "main": "forever.js",
    "scripts": {
        "start": "node forever.js"
    },
    "dependencies": {
        ...
        "forever": "~0.15.3"
    }
    ...
}
Запускаю на хост-машине - все работает идеально. При запуске в контейнере - не работает. Такое ощущение, как будто событие изменения файла не ловится. Скрипт работает, без ошибок, но проект он не перезапускает, при изменении файла.

Погуглив, нашел тред о том, что нужно юзать редактор с тру-перезаписью файла, чтобы все работало. НО! Что я только не юзал, изменения все равно не подхватывались. Я даже в винде тестил, не пашет.

В чем может быть проблема?

Deleted

Последнее исправление: Bizun (всего исправлений: 1)

Подпишусь, сам на такой баг не наталкивался, но уже интересно, как так.

gwinn ★★★★
()

покажи Dockerfile и как запускаешь контейнер

irr123
()
Ответ на: комментарий от gwinn

С монтированием и запуском все просто, все из туторов:

docker run -p 49160:8080 -d -v /calendar/src:/usr/src/app kamplyktar/calendar

И dockerfile:

FROM node:boron

# Create app directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

# Install app dependencies
COPY package.json /usr/src/app/
RUN npm install

# Bundle app source
COPY . /usr/src/app

# Your app binds to port 8080
EXPOSE 8080

# Define the command to run your app 
CMD [ "npm", "start" ]

irr123

Deleted
()
Ответ на: комментарий от Deleted

Это то еще решение:

# Bundle app source
COPY . /usr/src/app
-v /calendar/src:/usr/src/app

Но похоже, что докер тут абсолютно не при чем. Проблема у тебя вероятно в том, что «событие изменения файла» никем не обрабатывается. Твой монитор ловит только start, stop, etc, а тебе похоже надо что-то вроде этого fs.watch()

irr123
()
Ответ на: комментарий от irr123

Сомневаюсь, ведь на хост-машине все ок... Но все же, я перестраховался, поставив глобально forever.js и запустив проект вот так:

forever --watch server.js
Опять таки, на хосте - ОК, в докере не ОК.

Deleted
()

Кажется, я разобрался.

Я предположил, что изменения файла не подхватываются из за того, что в докер не попадает событие изменения файла. Именно по этому и не работал вариант с forever.js.

Погуглил, наткнулся на статью, в которой как раз описывали мою проблему и способ ее решения с помощью webpack'a.

Если вкратце, то webpack настраивается таким образом, что не ждать событие изменения файла, а с перерывом в N миллисекунд проверять файл на изменение. Если изменение было обнаружено, то проект пересобирается.

Но тут возникла еще одна проблема. Не смотря на то, что изменения файлов детектятся исправно, веб-сервер не перезапускается, и страница не меняется. Тут я опять решил заюзать forever.js (т.к. внутри контейнера события изменения файлов работают исправно), и уже с ним все работает исправно.

Вот конфиг webpack'a:

var webpack = require('webpack');
var path = require('path');
var fs = require('fs');

var nodeModules = {};
fs.readdirSync('node_modules')
  .filter(function(x) {
    return ['.bin'].indexOf(x) === -1;
  })
  .forEach(function(mod) {
    nodeModules[mod.toString()] = 'commonjs ' + mod;
  });

module.exports = {
  entry: './server.js',
  target: 'node',
  output: {
    path: path.join(__dirname, 'build'),
    filename: 'server.js'
  },
  externals: nodeModules,
  watchOptions: {
    poll: 500,
    aggregateTimeout: 1000
  }
}

package.json:

{
    ...
    "main": "server.js",
    "scripts": {
        "preinstall": "npm i -g webpack && npm i -g forever",
        "start": "webpack --watch | forever -w ./build/server.js"
    },
    ...
}

Не сильно костыльно получилось? Можно как то избавиться от forever.js, сделав все webpack'ом?

Deleted
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.