Nodemon не обновляет свое содержимое в Docker

#docker #nodemon

Вопрос:

Несмотря на то, что в Интернете много вопросов и ответов, я не смог найти ничего, что решило бы проблему, связанную с тем, что запуск простого express приложения js не будет обновляться при внесении изменений при запуске его внутри Docker.

Вот мой Dockerfile

 FROM node:16-alpine3.11
WORKDIR /var/be_core
VOLUME /var/be_core
COPY package*.json ./
RUN npm install
COPY . .
CMD ["npm", "start"]
 

То docker-compose.yml

 version: '3.9'
volumes:
  be_core_volume:

services:
  be_server_core:
    ports:
      - "9000:3000"
    image: jeko/be_server_core
    environment:
      - BE_SERVER_CORE_PORT=3000
    volumes:
      - "be_core_volume:/var/be_core"
 

Сервер js, действительно простой:

 const express = require('express');
const app = express();

app.get('/', (req, res) => {
    res.send("Hello world");
});

const PORT = process.env.BE_SERVER_CORE_PORT || 3000;

app.listen(PORT, () => {
    console.log(`Core server running on internal port : ${PORT}`);
});
 

команда npm start просто выполняет это

 "scripts": {
        "start": "nodemon -L ./server.js"
}
 

Если я запускаю сервер как автономный процесс (не в контейнере docker), он отлично работает.
использование команды docker-compose up — вместо этого — кажется, работает нормально, так как она запускает все, но при изменении чего-либо в server.js файле она не обновляется.

Что я делаю не так?

Ответ №1:

Вы перезаписываете код приложения с помощью докера с именем том.

volumes: можно смонтировать две вещи: либо каталог из хост-системы (монтирование привязки), либо хранилище, управляемое Docker (именованный том). Когда часть с левой стороны двоеточия-это просто имя, она монтирует именованный том.

Именованные тома ведут себя несколько странно при подключении тома к каталогу, содержащему содержимое в образе. В первый раз только при запуске контейнера содержимое изображения копируется на том. Однако каждый раз после этого (старое) содержимое тома имеет приоритет, даже если базовое изображение обновляется. Таким образом, при вашей настройке не только не монтируется каталог хоста (поскольку это именованный том), но и игнорируются изменения в изображениях, если вы docker-compose build снова.

Вы можете изменить это volumes: на привязку, и содержимое вашей хост-системы перезапишет содержимое образа. Будьте осторожны, чтобы монтировать только исходный код приложения, а не node_modules каталог.

 version: '3.8'
# no top-level volumes:
services:
  be_server_core:
    ...
    volumes:
      - "./src:/var/be_core/src" # note path on left-hand-side
 

Вместо того, чтобы пытаться убедить Docker имитировать локальную среду разработки, вы также можете счесть более удобным использовать реальную локальную среду разработки для повседневной работы. Запустите Node и Nodemon непосредственно на своем хосте, как обычно, и включите Docker только для зависимостей вашей службы, а затем для тестирования и развертывания интеграции. Здесь у вас вообще не было бы volumes: блока, все ваше приложение было бы встроено в изображение.