I'm attempting to deploy my create-react-app
SPA on a Digital Ocean droplet with Ubuntu 14.04 and Nginx. Per the static server deployment instructions, I can get it working when I run serve -s build -p 4000
, but the app comes down as soon as I close the terminal. It is not clear to me from the create-react-app
repo readme how to keep it running forever, similar to something like forever.
Without running serve
, I get Nginx's 502 Bad Gateway error.
Nginx Conf
server {
listen 80;
server_name app.mydomain.com;
root /srv/app-name;
index index.html index.htm index.js;
access_log /var/log/nginx/node-app.access.log;
error_log /var/log/nginx/node-app.error.log;
location ~* ^.+\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js|flv|swf|html|htm|svg)$ {
root /srv/app-name/build;
}
location / {
proxy_pass http://127.0.0.1:4000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Access-Control-Allow-Origin *;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
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 abuild
directory with a production build of your app. Set up your favorite HTTP server so that a visitor to your site is servedindex.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.