How to create a production build of a create react app?

Viewed 8973

I am trying to create a production build for online deployment of create-react-app with an express js backend using docker.

This is my docker file:

FROM node:12.18.3
WORKDIR /app
COPY ["package.json", "package-lock.json", "./"]
RUN npm install --production
COPY . .

RUN npm run build

EXPOSE 80
CMD ["npm", "start"]

I am using npm run build but still the react developer tools tells that it is a development build and not a production build.

Also in the sources all the project files are visible which should not be visible:

enter image description here

I have tried adding the below statement in the .env file in the root directory of the create-react-app but the project files are still visible:

GENERATE_SOURCEMAP=false

It will be helpful if anyone can guide me how do I fix this and create a production build.

Thank you

4 Answers

The reason why your source files are visible is simple. This is due to CMD ["npm", "start"]. It basically uses the webpack-dev-server and your docker image is build in the development environment. In order to deploy your app to production, you need a web server like nginx, to serve your static files, then create a docker image and run in the container, of your choice.

You need a web server like nginx to serve the files from the build folder. npm run build just creates the build folder it doesn't have any impact on what happens when you run npm start.

npm run build

creates a build directory with a production build of your app. Inside the build/static directory will be your JavaScript and CSS files. Each filename inside of build/static will contain a unique hash of the file contents. This hash in the file name enables long term caching techniques.

For those looking for a solution, the issue can be fixed by creating a server.js file in the project directory with the following content:

const express = require('express');
const serveStatic = require('serve-static');
const path = require('path');
const app = express();

// create middleware to handle the serving the app
app.use("/", serveStatic ( path.join (__dirname, '/build') ) );
// Catch all routes and redirect to the index file
app.get('*', function (req, res) {
res.sendFile(__dirname + '/build/index.html')
});

// Create default port to serve the app on
const port = process.env.PORT || 3000
app.listen(port);

also in the docker file add:

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

instead of

CMD ["npm", "start"]
Related