Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

390
Views
Should Dockerfile execute "npm install" and "npm run build" or should it only copy those files over?

I'm a little new to Docker and trying to wrap my head around some of the concepts.

In a lot of tutorials and articles (actually, almost all of them), this is a typical Dockerfile for a create-react-app and nginx configuration:

# CRA
FROM node:alpine as build-deps
WORKDIR /usr/src/app
COPY package.json package-lock.json ./
RUN npm install
COPY . ./
RUN npm run build

# Nginx
FROM nginx:1.12-alpine
COPY --from=build-deps /usr/src/app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

Assuming everything works as expected, the image would be huge.

I had the idea of taking a slightly different approach. Run npm install && npm run build locally, and then have this as the Dockerfile:

FROM nginx:1.12-alpine
WORKDIR /opt/app-root

COPY ./nginx/nginx.conf /etc/nginx/
COPY ./build ./src/dist/

COPY ./node_modules .

USER 1001
EXPOSE 8080
ENTRYPOINT ["nginx", "-g", "daemon off;"]

Which approach is better? Whenever I run docker build -t app-test:0.0.1 ., it seems to me that the second approach is always faster.

over 4 years ago · Santiago Trujillo
4 answers
Answer question

0

If you don't need the node_modules tree (and for Nginx hosting a browser application, you don't), the second approach of just copying in the built application is fine.

There are a couple of reasons to specifically want the first approach, to run the build in Docker. If there are architecture-specific details in your build (Node packages with native extensions, for example) Docker could be a different OS and library stack than your host system, so you might not be able to directly copy in a node_modules directory. If your build is really specific to tiny fixes in the language runtime, you can force a very specific version of Node in the Dockerfile.

Almost every browser application I've worked on builds fine with whatever node binary I have lying around, and once you've done that, the dist tree is platform-independent static files.

"Normal" style seems to vary across languages. Java applications in particular seem to generally build the application outside Docker, and then COPY the (platform-independent) final .jar file into the image. Go tends to use a multi-stage build, copying a built binary into an extremely minimal final image. If I was writing a Node browser application it'd probably look like your first form, RUN yarn build in Docker, but I've seen a lot of variations on the theme.

over 4 years ago · Santiago Trujillo Report

0

IMO first option is better on containerization perspective, because you don't need the package (npm) on your laptop to run your applications. You just need docker.

over 4 years ago · Santiago Trujillo Report

0

For that you could use multi-stage docker build.

In the first container you would install all dependencies (along with the dev dependencies) and then run npm run build. It will build your app but you will have useless dev dependencies inside your node_modules. You don't have to copy that node_modules.

In the second container your would run npm install --production --no-audit and copy the dist directory from the first container. Now you will have your compiled code and a node_modules folder with only production modules.

Making it lighter but the build time would be a bit longer.

over 4 years ago · Santiago Trujillo Report

0

Building inside a container guarantees a predictable and reproducible build artifact. Running npm install on macOS and Linux can produce different node_modules, for example node-gyp.

People often build node_modules with multi-stage build (if the actual container you're trying to build is not a Node.js application). That is to say, your actual nginx application per se does not depend on Node.js, but the node_modules directory and its containing files instead. So we generate node_modules in a node container, and copy it to the new container (nginx).

Thus, everyone building with the multi-stage Dockerfile will produce exact same container. If you copy your local node_modules into a container during build, other coworkers will not be able to predict the content of node_modules.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!