brendandburns / kbp-sample

Sample app for Kubernetes best practices book from O'Reilly
99 stars 100 forks source link

Error: Cannot find module 'redis' while running container #8

Open deemon359 opened 2 years ago

deemon359 commented 2 years ago

I have tried to run container I've just created from Dockerfile and I got an error

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

Error: Cannot find module 'redis' at Function.Module._resolveFilename (internal/modules/cjs/loader.js:636:15) at Function.Module._load (internal/modules/cjs/loader.js:562:25) at Module.require (internal/modules/cjs/loader.js:692:17) at require (internal/modules/cjs/helpers.js:25:18) at Object. (/server.js:2:15) at Module._compile (internal/modules/cjs/loader.js:778:30) at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10) at Module.load (internal/modules/cjs/loader.js:653:32) at tryModuleLoad (internal/modules/cjs/loader.js:593:12) at Function.Module._load (internal/modules/cjs/loader.js:585:3)

How can I fix this issue? Why redis doesn't install despite on "RUN npm install -g redis" command within the Dockerfile?

conradwt commented 2 years ago

@deemon359 Here's a better package.json and Dockerfile to get things working for you:

package.json:

{
  "name": "kbp-sample",
  "version": "1.0.0",
  "description": "",
  "main": "server.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node server.js"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/brendandburns/kbp-sample.git"
  },
  "author": "",
  "license": "ISC",
  "bugs": {
    "url": "https://github.com/brendandburns/kbp-sample/issues"
  },
  "homepage": "https://github.com/brendandburns/kbp-sample#readme",
  "dependencies": {
    "double-ended-queue": "^2.1.0-0",
    "redis": "^4.0.0-rc.4",
    "redis-commands": "^1.4.0",
    "redis-parser": "^2.6.0"
  }
}

Dockerfile:

FROM node:16-bullseye-slim as base

ENV NODE_ENV=production

RUN apt-get update \
    && apt-get install -y --no-install-recommends \
    tini \
    && rm -rf /var/lib/apt/lists/*

EXPOSE 8080

RUN mkdir -p /app && chown -R node:node /app

WORKDIR /app

USER node

COPY --chown=node:node package*.json yarn*.lock ./

RUN npm ci --only=production && npm cache clean --force

# dev stage (no source added, assumes bind mount)
FROM base as dev

ENV NODE_ENV=development

ENV PATH=/app/node_modules/.bin:$PATH

RUN npm install --only=development && npm cache clean --force

CMD ["nodemon", "./server.js", "--inspect=0.0.0.0:9229"]

# copy in source code for test and prod stages
# we do this in its own stage to ensure the
# layers we test are the exact hashed layers the cache
# uses to build prod stage
FROM base as source

COPY --chown=node:node server.js server.js

# test stage: combine source code and dev stage deps
FROM source as test

ENV NODE_ENV=development

ENV PATH=/app/node_modules/.bin:$PATH

COPY --from=dev /app/node_modules /app/node_modules

RUN npx eslint .

RUN npm test

CMD ["npm", "run", "test"]

### prod stage
FROM source as prod

ENTRYPOINT ["/usr/bin/tini", "--"]

CMD ["node", "./server.js"]

Next, you can build the image as follows:

docker build -t ${USER}/kbp-sample .

Finally, you can run the service by doing the following:

  1. start Redis on your local development machine and it should be running at http://127.0.0.1:6379
  2. start the kbp-sample service on port 8080
    docker run --rm -p 8080:8080 ${USER}/kbp-sample