I’m still trying to improve my Docker builds. Here’s an example for a multi-stage Docker build for React:
## base image
FROM node:12.13.1-alpine as compile-image
## install global packages
ENV NPM_CONFIG_PREFIX=/home/node/.npm-global
RUN npm install npm@latest -g
RUN npm install pnpm react-scripts@3.3.0 -g
## set working directory & give permissions to user `node`
RUN mkdir -p /usr/src/app && chown node:node /usr/src/app
WORKDIR /usr/src/app
## switch to non-root user & install dependencies
USER node
COPY package*.json /usr/src/app/
COPY pnpm-lock.yaml /usr/src/app/pnpm-lock.yaml
ENV PATH /usr/src/app/node_modules/.bin:$PATH
ENV PATH=$PATH:/home/node/.npm-global/bin
RUN pnpm install
## set environment to production, overwrite
## with docker-compose
ARG NODE_ENV=production
ENV NODE_ENV $NODE_ENV
## create build
COPY . /usr/src/app
RUN pnpm run build
## runtime image
FROM nginx:1.15.9-alpine
## update nginx conf with custom config
RUN rm -rf /etc/nginx/conf.d
COPY conf /etc/nginx
## copy static files
COPY --from=compile-image /usr/src/app/build /usr/share/nginx/html
## expose port
EXPOSE 80
## run nginx
CMD ["nginx", "-g", "daemon off;"]
Further Reading
- Dockerizing a React app by Michael Herman
- Docker and Node.js Best Practices
- Node + Docker Hello World, for Showing Good Defaults for Using Node.js in Docker by Bret Fisher
- Top 4 Tactics To Keep Node.js Rockin’ in Docker by Bret Fisher