Deploy Create-React-App on Nginx

One of the major benefits of React (and Create React App) is that you don't need the overhead of running a Node server (or proxying to it with Nginx); you can serve the static files directly.

From the Deployment documentation you've linked to, Create React App describes what to do:

npm run build creates a build directory with a production build of your app. Set up your favorite HTTP server so that a visitor to your site is served index.html, and requests to static paths like /static/js/main.<hash>.js are served with the contents of the /static/js/main.<hash>.js file.

In your case, run npm run build to create the build/ directory and then make the files available in a location Nginx can access them. Your build is probably best done on your local machine and then you can securely copy the files across to your server (via SCP, SFTP etc). You could run npm run build on your server, but if you do, resist the temptation to directly serve the build/ directory as the next time you run a build, clients could receive an inconsistent set of resources whilst you're building.

Whichever build method you choose, once your build/ directory is on your server, then check its permissions to ensure Nginx can read the files and configure your nginx.conf like so:

server {
  listen 80;
  server_name app.mydomain.com;
  root /srv/app-name;
  index index.html;
  # Other config you desire (TLS, logging, etc)...
  location / {
    try_files $uri /index.html;
  }
}

This configuration is based upon your files being in /srv/app-name. In short, the try_files directive attempts to load CSS/JS/images etc first and for all other URIs, loads the index.html file in your build, displaying your app.

For note, you should be deploying using HTTPS/SSL to serve it rather than with insecure HTTP on port 80. Certbot provides automatic HTTPS for Nginx with free Let's Encrypt certificates, if the cost or process of obtaining a certificate would otherwise hold you back.


I was hosting NextJS as main app on / and wanted to host CRA on /admin route. Here is what I did:

  • serve CRA through custom express server
  • change hostname in package.json
  • add basename to /admin for react-router
  • define the following proxy pass:
location / {
  proxy_pass http://localhost:3000;
}
location /admin {
  proxy_pass http://localhost:3001;
}
location /admin/ {
  proxy_pass http://localhost:3001/;
}

Related articles:

  • CRA Deployment
  • React-Router
  • Multiple SPAs
  • Another StackOverflow question