I'm currently developing a CRA app using Docker. Everything is fine in development. However, when I want to create the production build (I'm using a separate docker-compose.yml file for the production build), it keeps telling me it cannot find the files.
I keep getting Cannot find module: 'lorem.scss'. Make sure this package is installed.
It happens right after yarn run build
in the building environment.
My Dockerfile:
##############################
# Base Image
##############################
# Ger current Node Alpine Linux image.
FROM node:alpine AS base
# Set working directory.
WORKDIR /home/node/app/
# Copy project content.
COPY package.json ./
##############################
# Development Image
##############################
# Development environment.
FROM base AS development
# Run yarn to install.
RUN yarn
# Copy source code.
COPY ./src/ /home/node/app/src/
COPY ./public/ /home/node/app/public/
# Copy Storybook files.
COPY ./stories/ /home/node/app/stories/
COPY ./.storybook/ /home/node/app/.storybook/
# Run the app.
CMD [ "yarn", "run", "dev" ]
##############################
# Building Environment
##############################
# Building environment set.
FROM base AS builder
# Run yarn to install.
RUN yarn
# Copy source code.
COPY ./src/ /home/node/app/src/
COPY ./public/ /home/node/app/public/
# Run the build.
RUN yarn run build
##############################
# Production Image
##############################
FROM nginx:alpine AS production
# Copy source code.
COPY --from=builder /home/node/app/build /usr/share/nginx/html
# Copy nginx configuration template.
COPY ./nginx.template /etc/nginx/conf.d/
# Set permissions so nginx can serve it.
RUN chown nginx.nginx /usr/share/nginx/html/ -R
My docker-compose.production.yml file:
version: "3.7"
services:
##############################
# Front-End Container
##############################
frontend:
container_name: ${PROJECT_NAME}_frontend
build:
context: ./frontend/
target: production
restart: always
environment:
- PROJECT_NAME=${PROJECT_NAME}
- NODE_PATH=${REACT_NODE_PATH}
- NODE_PORT=${NODE_PORT}
- SASS_PATH=${SASS_PATH}
- NODE_ENV=production
- DOCKER_BUILDKIT=1
command: /bin/ash -c "envsubst < /etc/nginx/conf.d/nginx.template > /etc/nginx/conf.d/default.conf && exec nginx -g 'daemon off;'"
expose:
- "80"
ports:
- "80:80"
My variables in the .env file are as follows:
SASS_PATH=node_modules:src/components:src/assets/styles:src/assets/fonts
REACT_NODE_PATH=src/assets/styles/pages:src/assets/images
Your problem is that you are expecting the environment files to be passed to your docker build. While there is nothing like that happening. The environment
that you define is only passed to image at run-time as run-time environment.
So you need to either use build arguments or set these environments in your image
Passing environments
##############################
# Building Environment
##############################
# Building environment set.
FROM base AS builder
# Run yarn to install.
RUN yarn
# Copy source code.
COPY ./src/ /home/node/app/src/
COPY ./public/ /home/node/app/public/
# Run the build.
ENV SASS_PATH=node_modules:src/components:src/assets/styles:src/assets/fonts REACT_NODE_PATH=src/assets/styles/pages:src/assets/images
RUN yarn run build
Or you need to use build args
##############################
# Building Environment
##############################
# Building environment set.
FROM base AS builder
# Run yarn to install.
RUN yarn
# Copy source code.
COPY ./src/ /home/node/app/src/
COPY ./public/ /home/node/app/public/
# Run the build.
ARG SASS_PATH
ARG REACT_NODE_PATH
ENV SASS_PATH=${SASS_PATH}
ENV REACT_NODE_PATH=${REACT_NODE_PATH}
RUN yarn run build
And update your compose file like
version: "3.7"
services:
##############################
# Front-End Container
##############################
frontend:
container_name: ${PROJECT_NAME}_frontend
build:
context: ./frontend/
target: production
args:
- REACT_NODE_PATH=${REACT_NODE_PATH}
- SASS_PATH=${SASS_PATH}
restart: always
environment:
- PROJECT_NAME=${PROJECT_NAME}
- NODE_PATH=${REACT_NODE_PATH}
- NODE_PORT=${NODE_PORT}
- SASS_PATH=${SASS_PATH}
- NODE_ENV=production
- DOCKER_BUILDKIT=1
command: /bin/ash -c "envsubst < /etc/nginx/conf.d/nginx.template > /etc/nginx/conf.d/default.conf && exec nginx -g 'daemon off;'"
expose:
- "80"
ports:
- "80:80"