Reputation: 893
I'm trying to deploy an application I wrote to my unraid server so I had to docker-ize it. It's written with nodejs and depends on imagemagick and ghostscript so I had to include a build step to install those dependencies. I'm seeing an error when running this image though
Here's my dockerfile
FROM node
RUN mkdir -p /usr/src/app
RUN chmod -R 777 /usr/src/app
WORKDIR /usr/src/app
COPY . /usr/src/app
RUN npm i --only=production
FROM ubuntu
RUN apt-get update
RUN apt-get install -y imagemagick ghostscript nodejs
ENTRYPOINT node /usr/src/app/index.js
Console output
internal/modules/cjs/loader.js:638
throw err;
^
Error: Cannot find module '/usr/src/app/index.js'
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:636:15)
at Function.Module._load (internal/modules/cjs/loader.js:562:25)
at Function.Module.runMain (internal/modules/cjs/loader.js:831:12)
at startup (internal/bootstrap/node.js:283:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:623:3)
Originally, my entrypoint was configured like ENTRYPOINT node ./index.js
but I thought that I was in the wrong directory or something but switching to an absolute path didn't work either so here I am.
Upvotes: 1
Views: 1379
Reputation: 20467
By using a second FROM
instruction, you are introducing a second stage. Nothing from the first stage is available to the second stage by default. If you need some artefacts, you need to copy them explicitly.
# give the stage a name to
# be able to reference it later
FROM node as builder
RUN mkdir -p /usr/src/app
RUN chmod -R 777 /usr/src/app
WORKDIR /usr/src/app
COPY . /usr/src/app
RUN npm i --only=production
# this is a new stage
FROM ubuntu
RUN apt-get update
RUN apt-get install -y imagemagick ghostscript nodejs
# you need to copy the things you need
COPY --from=builder /usr/src/app /usr/src/app
ENTRYPOINT node /usr/src/app/index.js
That said, it seems pointless for a node app to do that. I would suggest using a single stage. The node runtime is required to run your app. Multi staging would make sense if you were to use node to build statics with something like webpack and then copy the produced statics into a second stage that doesn't need the node runtime.
Also note that using an entrypoint over a simple command only makes sense if your application takes additional arguments and flags, and you want the user of your image to be able to provide said arguments without being required to know how to start the actual app.
Another thing to improve is using npm ci
over npm i
to avoid untested behaviour in production.
The use of the 2 run instructions to create the folder and change its permissions seem also somewhat redundant. If you use a workdir, that folder is automatically created.
Upvotes: 1