# Deploy Multiple MERN apps to digital ocean This tutorial will guide you through the process of deploying multiple MERN apps to a single digital ocean ubuntu VPS droplet [Reference](https://www.youtube.com/watch?v=oykl1Ih9pMg) ## 1. Sign up for Digital Ocean [DigitalOcean](https://www.digitalocean.com) ## 2. Create a droplet and Login via SSH [YouTube](https://www.youtube.com/watch?v=YYC0HSLSLjA) ## 3. Install NodeJS and npm ```sh $ sudo apt update $ sudo apt install nodejs $ nodejs -v $ npm -v ``` ## 4. Create a folder for the project on the Droplet In your droplets home directory create a folder called apps ```sh $ mkdir apps $ cd apps ``` ## 5.Clone your project from Github ```sh $ git clone yourproject.git ``` ## 6. Install dependencies and test app ``` cd yourproject npm install npm start (or whatever your start command) # stop app ctrl+C ``` ## 7. Setup PM2 process manager to keep your app running ``` sudo npm i pm2 -g # Make sure you are in the root folder of your app then run pm2 start app (or whatever your file name) # Other pm2 commands pm2 show app pm2 status pm2 restart app pm2 stop app pm2 logs (Show log stream) pm2 flush (Clear logs) # To make sure app starts when reboot pm2 startup ubuntu ``` ## 8. Setup UFW Firewall ``` sudo ufw enable sudo ufw status # (Port 22) sudo ufw allow ssh #(Port 80) sudo ufw allow http #(Port 443) sudo ufw allow https ``` ## 9. Install NGINX and configure ``` sudo apt install nginx ``` ## 10. Move the REACT front end into /var/www/html/ folder #### I am assuming that the react front end is contained in a folder called "build" in your projects root directory ``` #From within your project ROOT directory cp -Rv build /var/www/html ``` ## 11. Rename the build folder to a name that will reflect the domain name of your app ``` mv build mydomain.com ``` ## 12. Change permissions of the "mydomain.com" folder [Reference 1](https://linuxize.com/post/how-to-set-up-nginx-server-blocks-on-debian-9/) [Reference 2](https://webdock.io/en/docs/how-guides/how-configure-nginx-to-serve-multiple-websites-single-vps) ``` chown -R www-data:www-data /var/www/html/mydomain.com ``` ## 13. Configure NGINX ``` sudo nano /etc/nginx/sites-available/mydomain.com.conf ``` #### I assume that the backend is running on port 5000 as denoted in the config block below -> "proxy_pass http://localhost:5000;" #### and that the front end accesses the backend like this https://www/mydomain.com/backend/your-api-endpoints #### Copy paste this into the file that opens in NANO ``` server { listen 80; listen [::]:80; #Path to the React front end root /var/www/html/mydomain.com; #the main html file index index.html; #Enter the IP address of your droplet server_name ; #STORE the nginx access logs for this app here access_log /var/log/nginx/mydomain.com.access.log; #Store the error logs for this app here error_log /var/log/nginx/mydomain.com.error.log; location / { # Without this line routing in your Single Page APP will not work try_files $uri $uri/ /index.html =404; } #REST API BACKEND CONFIG location /backend { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-NginX-Proxy true; proxy_pass http://localhost:5000; proxy_ssl_session_reuse off; proxy_set_header Host $http_host; proxy_cache_bypass $http_upgrade; proxy_redirect off; } ``` #### Save and close the config file ``` Ctrl + O Ctrl + X ``` ## 14. Enable the new server block file by creating a symbolic link from the file to the sites-enabled directory ``` sudo ln -s /etc/nginx/sites-available/mydomain.com.conf /etc/nginx/sites-enabled/ ``` ## 15. Test the Nginx configuration for correct syntax ``` sudo nginx -t ``` If there are no errors, the output will look like this: ``` nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful ``` ## 16. Restart the Nginx service for the changes to take effect ``` sudo systemctl restart nginx ``` ## 17. Install Python NGINX certbot to generate a SSL Certificate [DigitalOcean Documentation](https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-20-04) ``` sudo add-apt-repository ppa:certbot/certbot sudo apt-get update sudo apt-get install python-certbot-nginx sudo certbot --nginx -d mydomain.com -d www.mydomain.com ``` #### To renew the certificate ``` sudo certbot renew --dry-run ``` #### If you ever need to make changes to /etc/nginx/sites-available/mydomain.com.conf [Reference](https://futurestud.io/tutorials/nginx-remove-an-app-domain-from-sites-enabled) ``` #FIRST DELETE THE CONF FILE FROM SITES-ENABLED AND NOT SITES-AVAILABLE #ONCE AGAIN DELETE THE CONF FILE IN SITES-ENABLED cd /etc/nginx/sites-enabled rm mydomain.com.conf #and then after you have finished modifying the conf file in SITES-AVAILABLE run this once again sudo ln -s /etc/nginx/sites-available/mydomain.com.conf /etc/nginx/sites-enabled/ ``` #### For multiple MERN apps repeat from STEP 10 and replace mydomain.com with anotherdomain.com and make sure the backend is running on a different port, also update the port for the backend in your sites-available conf file proxy_pass http://localhost:differen-port;