Docker /bin/bash: nodemon: 命令未找到。

24

我正在尝试将我的工作节点代码从主机挂载到一个Docker容器中,并使用docker-compose使用nodemon运行它。

但是容器似乎找不到nodemon。

注意:我的主机没有安装node或npm。

这是我项目根目录(test)下的文件。(这只是一个草稿)

Dockerfile

FROM surenderthakran/nodejs:v4
ADD . /test
WORKDIR /test
RUN make install
CMD make run

Makefile

SHELL:=/bin/bash
PWD:=$(shell pwd)
export PATH:= $(PWD)/node_modules/.bin:$(PWD)/bin:$(PATH)
DOCKER:=$(shell grep docker /proc/1/cgroup)

install:
    @echo Running make install......
    @npm config set unsafe-perm true
    @npm install

run:
    @echo Running make run......
# Check if we are inside docker container
ifdef DOCKER
    @echo We are dockerized!! :D
    @nodemon index.js
else
    @nodemon index.js
endif

.PHONY: install run

docker-compose.yml

app:
    build: .
    command: make run
    volumes:
        - .:/test
    environment:
        NODE_ENV: dev
    ports:
        - "17883:17883"
        - "17884:17884"

package.json

{
  "name": "test",
  "version": "1.0.0",
  "description": "test",
  "main": "index.js",
  "dependencies": {
    "express": "^4.13.3",
    "nodemon": "^1.8.0"
  },
  "devDependencies": {},
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "api",
    "nodejs",
    "express"
  ],
  "author": "test",
  "license": "ISC"
}

index.js

'use strict';

var express = require('express');

我使用docker-compose build构建镜像。它成功完成。 但是,当我尝试使用docker-compose up运行它时,出现以下错误:

Creating test_app_1...
Attaching to test_app_1
app_1 | Running make run......
app_1 | We are dockerized!! :D
app_1 | /bin/bash: nodemon: command not found
app_1 | make: *** [run] Error 127
test_app_1 exited with code 2
Gracefully stopping... (press Ctrl+C again to force)

有人能给些建议吗?

注意:我的基础镜像surenderthakran/nodejs:v4的Dockerfile可以在这里找到:https://github.com/surenderthakran/dockerfile_nodejs/blob/master/Dockerfile


如果您尝试交互式操作,它是否有效? - allprog
1
@allprog 是的,它可以交互工作。 - Surender Thakran
1
听起来像是路径问题 - 尝试使用 nodemon 的完整路径:/path/to/nodemon - Chris McKinnel
@ChrisMcKinnel,问题已经解决。如果您有更好的解决方案,请随时提出建议,因为我的解决方案不是很优雅。谢谢。 - Surender Thakran
@allprog 问题已解决。如果你有更好的解决方案,随意提出建议。谢谢。 - Surender Thakran
5个回答

20
该问题已解决。问题的核心是我在挂载卷中没有node_modules文件夹。

基本上,在执行docker-compose build期间,镜像是正确构建的,实际代码被添加到镜像中,并且通过在项目根目录中运行npm install创建了node_modules文件夹。但是,在执行docker-compose up时,代码被挂载到了项目根目录,覆盖了先前添加的代码,包括新创建的node_modules文件夹。

因此,我的解决方案是妥协,在我的主机上安装nodejs并在主机上执行npm install。这样,当我的代码被挂载时,我仍然可以在项目根目录中获得node_modules文件夹,因为它也从我的主机挂载而来。

虽然不是很优雅的解决方案,但既然这是开发设置,我已经做好了妥协的准备。在生产环境中,我将使用docker builddocker run进行设置,并且无论如何都不会使用nodemon

如果有人能提供更好的解决方案,我将不胜感激。

谢谢!!

我对npm/node不是很熟悉,但我认为你可以使用npm install -g将它们安装到项目根目录外的不同url中,然后使用npm link链接到它们,而不是在本地再次安装它们?另一种选择可能是使用npm config set prefix将它们安装到容器中的自定义路径,然后在您的项目目录中有一个符号链接,指向该目录的./node_modules。 我认为这将使用add和volumes都有效。 - dnephin
靶心解决方案。 - Rafik Farhad

5

我认为你应该在你的 package.json 中使用一个 preinstall 脚本。

因此,在脚本部分中,只需添加脚本:

 "scritpts": {
     "preinstall": "npm i nodemon -g",
     "start": "nodemon app.js",
 }

并且你应该已经准备好了 :)

在运行“RUN npm install”之前,可能需要运行“RUN npm set unsafe-perm true”。 - ViniciusArruda

3
我已经找到了一种不需要 Dockerfile 的方法来完成这个,如果对任何人有用的话...
您可以通过使用 sh -c 在 docker-compose.yml 中的命令行中运行多个命令。
  my-server:
    image: node:18-alpine
    build: .
    volumes:
      - .:/usr/src/app
      - /usr/src/app/node_modules
    working_dir: /usr/src/app
    ports:
      - "3100:3100"
    command: sh -c "npm install -g nodemon && npm install && npm run dev "
    environment:
      NODE_ENV: development
      PORT: 3100

嘿,太完美了!这是我的 Dockerfile:WORKDIR /app COPY package.json /app/ RUN npm install -g nodemon RUN npm install COPY . /app EXPOSE 3000 CMD ["npm", "run", "dev"] - vintagexav

1
你需要将node_modules设置为docker容器中的挂载卷。

e.g

docker-compose.yml

app:
build: .
command: make run
volumes:
    - .:/test
    - /test/node_modules
environment:
    NODE_ENV: dev
ports:
    - "17883:17883"
    - "17884:17884"

1
很晚才回答。但是你可以使用称为命名卷的东西将您的node_modules挂载到docker卷空间中。这样它就会隐藏您的绑定挂载。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接