我正在运行一个node:latest容器,本地磁盘映射到其中,我的项目特定文件驻留在其中。当我从容器外部编辑这些文件时,我希望服务器能够自动检测这些文件中的更改-这是由nodemon
模块提供的。
上次我这么做的时候还行,大约2年前。我拿了那个旧项目,更新了它(显然有必要让它现在甚至运行,在解决关键的安全漏洞之上),但是它声称在从命令行运行node时找不到nodemon
模块(无论是由容器启动还是手动启动)。如果我启动一个交互式节点会话,在进入容器后,它可以找到模块。
容器启动时新安装的模块。至少目前,一旦问题得到解决,这种情况将会改变。
简写:
# node nodemon version
internal/modules/cjs/loader.js:1032
throw err;
^
Error: Cannot find module '/app/nodemon'
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:1029:15)
at Function.Module._load (internal/modules/cjs/loader.js:898:27)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
at internal/main/run_main_module.js:17:47 {
code: 'MODULE_NOT_FOUND',
requireStack: []
}
# node
Welcome to Node.js v14.4.0.
Type ".help" for more information.
> nm = require("nodemon")
[Function: nodemon] {
restart: [Function (anonymous)],
on: [Function (anonymous)],
addListener: [Function (anonymous)],
once: [Function (anonymous)],
emit: [Function (anonymous)],
removeAllListeners: [Function (anonymous)],
reset: [Function (anonymous)],
config: {
run: false,
system: { cwd: '/app' },
required: true,
dirs: [],
timeout: 1000,
options: {},
load: [Function (anonymous)],
reset: [Function: reset]
}
}
> .exit
长版本,带有完整性检查…所有命令都是从容器内部运行的,在通过docker-compose.yml:
挂载的本地目录中。# pwd
/app
# ls
bin data node_modules package-lock.json package.json public routes server.js startScript.sh views
# cat package.json
{
"name": "app",
"version": "1.0.0",
"description": "",
"main": "app.js",
"scripts": {
"test": "echo "Error: no test specified" && exit 1",
"start": "node server.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"body-parser": "^1.20.0",
"cookie-parser": "^1.4.6",
"debug": "^4.3.4",
"express": "^4.18.1",
"http-errors": "^2.0.0",
"jQuery": "^1.7.4",
"morgan": "^1.10.0",
"multer": "^1.4.5-lts.1",
"nodemon": "^2.0.16",
"pug": "^3.0.2"
}
}
# export NODE_PATH=/app/node_modules
# echo $NODE_PATH
/app/node_modules
# ls $NODE_PATH
@babel binary-extensions color-convert depd function-bind imurmurhash is-regex mime-db on-headers pug-filters registry-url strip-json-comments url-parse-lax
@sindresorhus body-parser color-name destroy get-intrinsic inherits is-typedarray mime-types once pug-lexer resolve supports-color util-deprecate
@szmarczak boxen concat-map doctypes get-stream ini is-yarn-global mimic-response p-cancelable pug-linker responselike supports-preserve-symlinks-flag utils-merge
abbrev brace-expansion concat-stream dot-prop glob-parent ipaddr.js isarray minimatch package-json pug-load safe-buffer to-fast-properties vary
accepts braces configstore duplexer3 global-dirs is-binary-path jQuery minimist parseurl pug-parser safer-buffer to-readable-stream void-elements
acorn buffer-from constantinople ee-first got is-ci js-stringify mkdirp path-parse pug-runtime semver to-regex-range widest-line
ansi-align busboy content-disposition emoji-regex graceful-fs is-core-module json-buffer morgan path-to-regexp pug-strip-comments semver-diff toidentifier with
ansi-regex bytes content-type encodeurl has is-expression jstransformer ms picomatch pug-walk send token-stream wrap-ansi
ansi-styles cacheable-request cookie end-of-stream has-flag is-extglob keyv multer prepend-http pump serve-static touch wrappy
anymatch call-bind cookie-parser escape-goat has-symbols is-fullwidth-code-point latest-version negotiator process-nextick-args pupa setprototypeof type-fest write-file-atomic
append-field camelcase cookie-signature escape-html has-tostringtag is-glob lowercase-keys nodemon promise qs side-channel type-is xdg-basedir
array-flatten chalk core-util-is etag has-yarn is-installed-globally lru-cache nopt proxy-addr range-parser signal-exit typedarray xtend
asap character-parser crypto-random-string express http-cache-semantics is-npm make-dir normalize-path pstree.remy raw-body statuses typedarray-to-buffer yallist
assert-never chokidar debug fill-range http-errors is-number media-typer normalize-url pug rc streamsearch undefsafe
babel-walk ci-info decompress-response finalhandler iconv-lite is-obj merge-descriptors object-assign pug-attrs readable-stream string-width unique-string
balanced-match cli-boxes deep-extend forwarded ignore-by-default is-path-inside methods object-inspect pug-code-gen readdirp string_decoder unpipe
basic-auth clone-response defer-to-connect fresh import-lazy is-promise mime on-finished pug-error registry-auth-token strip-ansi update-notifier
# npm view nodemon
nodemon@2.0.16 | MIT | deps: 10 | versions: 237
Simple monitor script for use during development of a Node.js app.
https://nodemon.io
keywords: cli, monitor, monitor, development, restart, autoload, reload, terminal
bin: nodemon
dist
.tarball: https://registry.npmjs.org/nodemon/-/nodemon-2.0.16.tgz
.shasum: d71b31bfdb226c25de34afea53486c8ef225fdef
.integrity: sha512-zsrcaOfTWRuUzBn3P44RDliLlp263Z/76FPoHFr3cFFkOz0lTPAcIw8dCzfdVIx/t3AtDYCZRCDkoCojJqaG3w==
.unpackedSize: 196.5 kB
dependencies:
chokidar: ^3.5.2 debug: ^3.2.7 ignore-by-default: ^1.0.1 minimatch: ^3.0.4 pstree.remy: ^1.1.8 semver: ^5.7.1 supports-color: ^5.5.0 touch: ^3.1.0 undefsafe: ^2.0.5 update-notifier: ^5.1.0
maintainers:
- remy <remy@leftlogic.com>
dist-tags:
debug-1268: 1.15.2-alpha.2 debug: 2.0.14-alpha.1 latest: 2.0.16
published a month ago by remy <remy@leftlogic.com>
# node nodemon version
internal/modules/cjs/loader.js:1032
throw err;
^
Error: Cannot find module '/app/nodemon'
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:1029:15)
at Function.Module._load (internal/modules/cjs/loader.js:898:27)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
at internal/main/run_main_module.js:17:47 {
code: 'MODULE_NOT_FOUND',
requireStack: []
}
# node
Welcome to Node.js v14.4.0.
Type ".help" for more information.
> nm = require("nodemon")
[Function: nodemon] {
restart: [Function (anonymous)],
on: [Function (anonymous)],
addListener: [Function (anonymous)],
once: [Function (anonymous)],
emit: [Function (anonymous)],
removeAllListeners: [Function (anonymous)],
reset: [Function (anonymous)],
config: {
run: false,
system: { cwd: '/app' },
required: true,
dirs: [],
timeout: 1000,
options: {},
load: [Function (anonymous)],
reset: [Function: reset]
}
}
> .exit
# export NODE_PATH=/app
# echo $NODE_PATH
/app
# node nodemon
internal/modules/cjs/loader.js:1032
throw err;
^
Error: Cannot find module '/app/nodemon'
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:1029:15)
at Function.Module._load (internal/modules/cjs/loader.js:898:27)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
at internal/main/run_main_module.js:17:47 {
code: 'MODULE_NOT_FOUND',
requireStack: []
}
#
因为我希望有人会问,尽管看起来无关紧要,这里是安装模块的脚本:
#!/bin/sh
rm /app/package.json
rm /app/package-lock.json
rm -rf /app/node_modules
npm init -y
npm install express
npm install http-errors
npm install pug
npm install morgan
npm install cookie-parser
npm install debug
npm install jQuery
npm install body-parser
npm install multer
npm install nodemon
npm audit
npm audit fix
该脚本运行在一个新节点:最新的容器上,除了在上面所示的目录中映射之外,没有其他奇怪的地方,所以这应该是可重复的。理想情况下,它不会删除node_modules和诸如此类的东西,以加快启动速度,但在这种情况下,我让它这样做,只是为了确保一切都是干净的。
如果有人问,这里是docker-compose.yml:
#redis:
# image: redis
# volumes:
# - ./webapp/data/redis:/data
#mysql:
# image: mysql:latest
# environment:
# MYSQL_ROOT_PASSWORD: StackOverflowsdfj87ey2,238n
# MYSQL_DATABASE: StackOverflowDB
# MYSQL_USER: StackOverflow
# MYSQL_PASSWORD: StackOverflowmcxhdie73.6xm
# volumes:
# - ./webapp/data/mysql:/var/lib/mysql
application:
image: node:latest
working_dir: /app
command: /app/startScript.sh
volumes:
- ./webapp:/app
ports:
- 80:3000
# links:
# - redis
# - mysql
这是我能想到的所有可能与此相关的…就像我说的,这曾经可靠地工作-使用完全相同的docker-compose。Yml和启动脚本,具有完整的数据库支持。
Nodemon不是一个模块。通常,它是全局安装的,并作为命令行中的命令使用。
由于它不是全局安装的,所以运行它的一种方法是像这样启动它
./node_modules/nodemon/bin/nodemon.js -h