Мы пытаемся создать контейнер с запущенным node.js, используя docker (docker-compose, так как впоследствии мы собираемся добавить mongodb).
Мы копируем пакет.json в Dockerfile, а затем монтируем том в докер-compose.yml, который содержит исходный код для выполнения.
Структура нашего проекта выглядит следующим образом.
Мы хотим, чтобы исходная папка была смонтирована как том.
Наш файл пакет.json
{
"name": "node_package",
"version": "1.0.0",
"description": "node_package inside node_dir for node_service running on node_container",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node source/index.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.17.0"
}
}
Наш Докерфайл
FROM node:10-alpine
WORKDIR /node_dir
COPY package*.json ./
RUN npm install
Наш докер-compose.yml
version: "3"
services:
node_service:
build: .
container_name: node_container
user: node
working_dir: "/node_dir"
ports:
- "8080:3000"
volumes:
- ./source:/node_dir/source
command: npm start
Теперь, когда мы запускаем это на macOS, это работает. Он монтирует исходную папку как том, а затем выполняет команда запуска нпм. Но когда мы пытаемся сделать то же самое в Windows, мы получаем следующую ошибку
Не удается найти модуль «node_dir/source/index.js»
Почему он работает на Mac, но не на Windows?
Вот наш файл index.js
const express = require('express')
const app = express()
const port = 3000
app.get('/', (req, res) => res.send('Hello World!'))
app.listen(port, () => {console.log(`Example app listening on port ${port}!`)})
Когда мы копируем исходную папку в Dockerfile, она работает в Windows. Но если мы не копируем исходную папку в Dockerfile и не монтируем ее как том в docker-compose.yml, то команда запуска нпм не работает.
Вы имеете в виду, что я должен запустить «npm install» на хост-машине с Windows или на образе контейнера?
Ну, вы говорите: «мы попробуем то же самое на окнах», поэтому я предполагаю, что у вас есть оболочка bash, работающая на окнах (или что-то в этом роде), и вы используете какой-то svn (git и т. д.), чтобы получить репо, поэтому по умолчанию вы все равно придется запускать npm install, верно? Я просто предлагаю удалить папку node_modules и запустить ее снова.
Нет, мы не используем репо. Это просто простой проект установки. Мы просто скопировали файлы вручную. Мы копируем package.json и запускаем непосредственно npm install на образ докера.
Мы также попытались удалить папку с модулями и снова запустить ее. Это ничего не изменило, потому что выдавало ошибку в файле index.js, смонтированном как том на докере (работающем в Windows)
потому что какой-то модуль узла необходимо скомпилировать, поэтому при запуске npm i
npm получить модуль, совместимый с ОС, т. Е. Папка node_module
в Windows отличается от Mac.
лучшее решение: изолировать node_module от монтирования привязки в docker-compose.
так редактируй docker-compose.yml
от:
volumes:
- ./source:/node_dir/source
к:
volumes:
- /node_dir/node_modules # isolate node_modules for compatible os
- ./source:/node_dir/source
Разве node_modules уже не изолированы в нашем текущем сценарии? потому что docker-compose.yml монтирует исходную папку с хоста в контейнер внутри каталога node_dir. Но node_modules находится в каталоге node_dir (сгенерированном установкой npm в контейнере с использованием Dockerfile, на один уровень выше, чем смонтированная исходная папка). Я не понимаю, как объявление «/node_dir/node_modules» в томе изолирует его для совместимой ОС?
нет, когда вы привязываете каталог node_dir к контейнеру докеров, файловая система - это та же ОС хоста, а не файловая система linux. при изоляции node_modules с помощью описанной выше техники node_modules перемещаются во временный том, эта файловая система основана на файловой системе Linux и полностью совместима.
Ну все равно не работает. Ошибка такая же даже после изоляции файла /node_dir/node_modules.
о, теперь сосредоточьтесь на коде, который знает, что index.js не монтируется (или копируется) в контейнер, поэтому вы должны скопировать index.js в контейнер /node_dir, чтобы решить проблему.
Я хочу, чтобы index.js находился в исходной папке. Я также проверил, даже если я не монтирую / не связываю / не присоединяю какой-либо том и копирую всю исходную папку с помощью команды COPY в файле докера после установки NPM ... Это все равно дает мне ошибку. Если я помещаю файл index.js в папку node_dir (тот же каталог, что и package.json и node_modules), он работает, но если я перемещаю его в исходную папку, он не работает. Неважно, использую ли я исходную папку или папку node_modules в качестве тома или нет. Это просто не работает, когда я помещаю index.js в исходную папку, даже если я указал это в своем package.json.
вы должны добавить эту строку в конец Dockerfile: «COPY index.js ./»
Да, я сделал, и это не имело никакого значения. Добавление index.js не поможет, так как мой index.js находится внутри исходной папки. И я пытался скопировать все, но это не работает, когда я ссылаюсь на исходную папку.
Я могу помочь вам в мессенджере телеграмм. мое имя пользователя: масихджахангири
Вы пытались удалить папку node_modules и снова запустить «npm install» на компьютере с Windows?