简体   繁体   中英

Node import module not found when running inside docker

I have a small react app with a node js server with the following imports:

import express from 'express'
import compression from 'compression'
import cookieParser from 'cookie-parser'
import bodyParser from 'body-parser'
import * as path from 'path'
import * as _ from 'lodash'
import { CloudConfigOptions, Config, ConfigObject } from 'spring-cloud-config'

import { ApiService } from './src/service/ApiService'
import { BackendEnum } from './src/service/BackendEnum'

And then several endpoints, for example:

server.put('/data', keycloak.protect('user'), (req: any, res: any) => { 
    ApiService.runSomeLogic();

    return res
})

On my local machine when I run: npm run dev:express the server starts up just fine.

Now the issue is, when I build the docker image and try to run it I get the following error:

$ docker run my-container:1.0

> my-app@0.1.0 start /app
> cross-env NODE_ENV=production node server.js

internal/modules/cjs/loader.js:985
  throw err;
  ^

Error: Cannot find module './src/service/ApiService'
Require stack:
- /app/server.js
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:982:15)
    at Function.Module._load (internal/modules/cjs/loader.js:864:27)
    at Module.require (internal/modules/cjs/loader.js:1044:19)
    at require (internal/modules/cjs/helpers.js:77:18)
    at Object.<anonymous> (/app/server.js:58:20)
    at Module._compile (internal/modules/cjs/loader.js:1158:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1178:10)
    at Module.load (internal/modules/cjs/loader.js:1002:32)
    at Function.Module._load (internal/modules/cjs/loader.js:901:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:74:12) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [ '/app/server.js' ]
}
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! my-app@0.1.0 start: `cross-env NODE_ENV=production node server.js`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the my-app@0.1.0 start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /root/.npm/_logs/2021-03-29T15_29_46_508Z-debug.log

The docker image is built using npm -q install , npm -q install and then npm run build

And this is the output of npm -debug.log file:

0 info it worked if it ends with ok
1 verbose cli [ '/usr/local/bin/node', '/usr/local/bin/npm', 'start' ]
2 info using npm@6.13.4
3 info using node@v12.16.1
4 verbose run-script [ 'prestart', 'start', 'poststart' ]
5 info lifecycle my-app@0.1.0~prestart: my-app@0.1.0
6 info lifecycle my-app@0.1.0~start: my-app@0.1.0
7 verbose lifecycle my-app@0.1.0~start: unsafe-perm in lifecycle true
8 verbose lifecycle my-app@0.1.0~start: PATH: /usr/local/lib/node_modules/npm/node_modules/npm-lifecycle/node-gyp-bin:/app/node_modules/.bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
9 verbose lifecycle my-app@0.1.0~start: CWD: /app
10 silly lifecycle my-app@0.1.0~start: Args: [ '-c', 'cross-env NODE_ENV=production node server.js' ]
11 silly lifecycle my-app@0.1.0~start: Returned: code: 1  signal: null
12 info lifecycle my-app@0.1.0~start: Failed to exec start script
13 verbose stack Error: my-app@0.1.0 start: `cross-env NODE_ENV=production node server.js`
13 verbose stack Exit status 1
13 verbose stack     at EventEmitter.<anonymous> (/usr/local/lib/node_modules/npm/node_modules/npm-lifecycle/index.js:332:16)
13 verbose stack     at EventEmitter.emit (events.js:311:20)
13 verbose stack     at ChildProcess.<anonymous> (/usr/local/lib/node_modules/npm/node_modules/npm-lifecycle/lib/spawn.js:55:14)
13 verbose stack     at ChildProcess.emit (events.js:311:20)
13 verbose stack     at maybeClose (internal/child_process.js:1021:16)
13 verbose stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:286:5)
14 verbose pkgid my-app@0.1.0
15 verbose cwd /app
16 verbose Linux 5.8.0-48-generic
17 verbose argv "/usr/local/bin/node" "/usr/local/bin/npm" "start"
18 verbose node v12.16.1
19 verbose npm  v6.13.4
20 error code ELIFECYCLE
21 error errno 1
22 error my-app@0.1.0 start: `cross-env NODE_ENV=production node server.js`
22 error Exit status 1
23 error Failed at the my-app@0.1.0 start script.
23 error This is probably not a problem with npm. There is likely additional logging output above.
24 verbose exit [ 1, true ]

EDIT: The Dockerfile content is:

FROM node:12.16.1-alpine as node

### WEB
FROM node as web-builder

WORKDIR /src
COPY ./my-app/package*.json ./
COPY ./my-app/.npmrc ./
RUN apk add --no-cache git openssh
RUN npm -q install

COPY ./my-app ./

# specify ARG as late as possible to take advantage of docker layer caching across dockerfiles
ARG BUILD_ID
RUN BUILD_ID=${BUILD_ID} npm run build


FROM node as web-release

WORKDIR /app
RUN apk add --no-cache git openssh
COPY ./my-app/package*.json ./
COPY ./my-app/.npmrc ./
RUN npm install -q --only=prod && \
    npm cache clean --force

COPY --from=web-builder /src/build ./build/
COPY --from=web-builder /src/server.js ./
COPY --from=web-builder /src/config ./config/

CMD ["npm", "start"]

EDIT2: package.json (for privacy reasons I removed the version of each library) content is:

{
    "name": "my-app",
    "version": "0.1.0",
    "private": true,
    "scripts": {
        "start": "cross-env NODE_ENV=production node server.js",
        "dev": "react-scripts start",
        "build": "npm run lint && npm run build:frontend && npm run build:backend",
        "build:frontend": "react-scripts build",
        "build:backend": "tsc -p tsconfig.server.json",
        "lint": "tsc --noEmit && tslint -c tslint.json -p .",
        "dev:express": "cross-env SPRING_PROFILES=local NODE_ENV=development ENVIRONMENT=local nodemon server.ts -p tsconfig.server.json"
    },
    "eslintConfig": {
        "extends": "react-app"
    },
    "husky": {
        "hooks": {
            "pre-commit": "lint-staged"
        }
    },
    "lint-staged": {
        "*.{js,md,json,css,md,html}": [
            "prettier --write",
            "git add"
        ],
        "*.{ts,tsx}": [
            "prettier --write",
            "tslint --fix",
            "git add"
        ]
    },
    "dependencies": {
        "@martin_hotell/rex-tils": "",
        "@types/express-session": "",
        "axios": "",
        "compression": "",
        "cookie-parser": "",
        "cookie-session": "",
        "cross-env": "",
        "express": "",
        "express-basic-auth": "",
        "express-session": "",
        "fork-ts-checker-webpack-plugin": "",
        "keycloak-connect": "",
        "lodash": "",
        "react": "",
        "react-dom": "",
        "react-dropzone": "",
        "react-dual-listbox": "",
        "react-popper": "",
        "react-redux": "",
        "react-scripts": "",
        "react-sortable-tree": "",
        "react-transition-group": "",
        "redux": "",
        "redux-devtools-extension": "",
        "redux-thunk": "",
        "spring-cloud-config": "",
        "styled-components": "",
        "typescript": "",
        "uuid": ""
    },
    "devDependencies": {
        "@types/compression": "",
        "@types/cookie-parser": "",
        "@types/express": "",
        "@types/lodash": "",
        "@types/node": "",
        "@types/react": "",
        "@types/react-dom": "",
        "@types/react-redux": "",
        "@types/react-sortable-tree": "",
        "@types/redux-mock-store": "",
        "@types/styled-components": "",
        "@types/uuid": "",
        "husky": "",
        "lint-staged": "",
        "nodemon": "",
        "prettier": "",
        "react-dnd": "",
        "redux-mock-store": "",
        "ts-node": "",
        "tslint": "",
        "tslint-config-prettier": "",
        "tslint-react": "",
        "typescript": ""
    },
    "browserslist": {
        "production": [
            (...)
        ],
        "development": [
            (...)
        ]
    }
}

I am pretty sure the issue is how the import of ApiService and BackendEnum is defined but my lack of node/javascript knowledge is preventing me from figuring out how to fix this import.

Can someone spot what is wrong with my import and why the app is crashing when running inside a docker container?

You are not copying all of the source code in the second container, instead copying only one file, ie) server.js. Offending line is,

COPY --from=web-builder /src/server.js ./

Change this line to

COPY --from=web-builder /src ./

If it still reports error, please provide the error log. If it works, you don't need the other two copy statements.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM