DEV Community

Cover image for Render Deployment (free tier) of MERN App
Greg
Greg

Posted on

Render Deployment (free tier) of MERN App

A guide to deploying your full stack MERN app to Render

Prereqs:

TLDR

Sign in to Render and create web service for your back end (Node, Express, MongoDB) and a static site for you front end (React).

Deployed App - Contact Bank
(warning Deployed link will take 30 seconds to spin up)

There are several ways to architect a full stack app for deployment on Render.
This tutorial is based of a MERN app with following file structure

Contact-Bank (root)/
├── client/
   ├── src
   ├── public
   ├── node_modules
   ├── .env
   ├── .gitignore
   ├── package-lock.json
   └── package.json
├── config
├── models
├── node_modules
├── routes
├── seed
├── .env
├── .gitignore
├── package-lock.json
├── package.json
└── server.js
Enter fullscreen mode Exit fullscreen mode

Workflow

Workflow

(If you don't have an fully functional production ready MERN app, follow these steps below, otherwise go here)

The MERN Application

  • main branch for Render deployment
  • dev branch for Vercel deployment *optional (front end testing only)

We are focusing on the main branch. I created a MERN App called Contact Bank that is a basic CRUD app with contact information. I seeded 1000 contacts in the MongoDB.

  • If you need to test your state prior to seeding the database I have included a data folder on front end with contacts.json

I am using the ContextAPI for the state management, if you want to use hooks and prop drill that won't effect the deployment permitting all things are equal.
Steps:

  1. Clone the repo git clone repo
  2. Add your MongoDB connection string from MongoDB as an environment variable (do not hardcode this, it should be in your .env file) ex:

    MY_MONGO_URI='mongodb+srv:...mongodb.net/contact-bank?retryWrites=true&w=majority'
    
  3. Seed the MongoDB

    • Run this command in your CLI
       node seed/seeds.js
    

    from the same level as the server or the .env variables === undefined

  4. In the root directory package.json scripts needed are

    //package.json
    
      "scripts": {
          "start": "node server.js",
          "server": "nodemon server.js",
          "client": "npm start --prefix client",
          "clientinstall": "npm install --prefix client",
          "dev": "concurrently \"npm run server\" \"npm run 
           client\"",
          "render-postbuild": "NPM_CONFIG_PRODUCTION=false 
          npm install --prefix client && npm run build -- 
          prefix client"
        },
    
  5. In the root directory CLI npm run dev and everything should run and changes in the UI should be reflected in the database.

  6. Serve static assets in production, inside the server.js

if (process.env.NODE_ENV === 'production') {
    //*Set static folder up in production
    app.use(express.static('client/build'));

    app.get('*', (req,res) => res.sendFile(path.resolve(__dirname, 'client', 'build','index.html')));
  }
Enter fullscreen mode Exit fullscreen mode

This step must be completed to move on to deployment.

Render

(If you have a fully functional production ready MERN App start here)

- Web Service

  • Create a Web Service Create a web service
  • Settings

I have concurrency running with this script npm run dev
Settings

  • Environment

Environment variable for the MongoDB connection string
Environment

  • Logs Logs

- Static site

  • Create A Static Site
    Start a static site

  • Settings
    I am telling Render to use this script to create a build folder from the root npm run render-postbuild and the path to the build folder is ./client/build since all of the npm commands are called in the root folder
    Settings

  • Environment
    Environment

  • Redirects/Rewrites
    My route https://contact-bank.onrender.com/api/* must be the top rule since my routes in the server.js are created with /api/
    Redirects/Rewrites

  • Logs
    Logs

Finally

Then after about 30 minutes the static site link https://contact-bank-a72l.onrender.com/ will be live

Live site is deployed
Yahooooo

I created this tutorial in light of the Heroku announcement so developers working with the MERN stack had some pathway to deploy their projects moving forward

Thanks for reading and Happy coding

Links 🔗

Conact-Bank Repo
Github Account
Render Account
MERN MongoDB
MongoDB
tree.nathanfriend.io

❤️❤️❤️

Social

Twitter
Linkedin
Portfolio
Github

🤘
Happy Coding

Top comments (13)

Collapse
 
sparezanin profile image
Slavko Parezanin

Hi Greg,
Great tutorial!
I followed steps from this tutorial, but i can't connect /api calls to my express server.
My project is at:
github.com/SlavkoPar/support-mern
Instead of redirection, i added 2 env variables:
REACT_APP_HOST: support-knowledge.onrender.com
REACT_APP_PORT: 4001
so i get a call:
support-knowledge.onrender.com:400...
i even created test call:
support-knowledge.onrender.com:400...
but I always get the response:
net::ERR_CONNECTION_TIMED_OUT
Do you have any suggestion?
Regards!

Collapse
 
sparezanin profile image
Slavko Parezanin

In my Web Service I tried:
curl -X POST 127.0.0.1:4001/api/test
and received the response: 'Welcome to GeeksforGeeks'

Collapse
 
sparezanin profile image
Slavko Parezanin

My site is: support-knowledge.onrender.com/
I found solution for my /api/* calls, setting my Web Service link to ‘Rewrite rules’:

/api/*
support-knowledge-service.onrender...
Rewrite

Best Regards !

Collapse
 
kunalukey profile image
Kunal Ukey

Great guide! 🤝

Collapse
 
bhuwancloud profile image
Bhuwan Bhatt (Bhuppi)

great tutorial

Collapse
 
hnhtran profile image
Tran Huynh • Edited

Hi Greg, if you can give me advice please?
I tested in local host successful..
I have succeeded deployed web service, but cannot deploy static site, it keeps saying

npm ERR! code EINVALIDTYPE
npm ERR! typeerror Error: Argument #5: Expected object but got string
Enter fullscreen mode Exit fullscreen mode

Great appreciation!

Collapse
 
hnhtran profile image
Tran Huynh

Issue resolved! For anyone running into same issue as me, instead of
"render-postbuild": "NPM_CONFIG_PRODUCTION=false npm install --prefix client && npm run build --prefix client"
I delete config string, become
"render-postbuild": "npm install --prefix client && npm run build --prefix client"

Collapse
 
opyjo profile image
opyjo

The build Command in the webservice has yarn which does not seem correct. what did you change it to?

Thread Thread
 
hnhtran profile image
Tran Huynh

I still use yarn without any issue opyjo. You had any issue? can post the error, we see together?

Thread Thread
 
gregpetropoulos profile image
Greg

Thanks for the feedback share your repo and errors and I will help debug. The 'yarn' in the build command input box for Web Services is not in use, thus you shouldn't have any issues with that. Essentially I am not building anything from the services(backend server), but you certainly could do it that way. Since my repo has the frontend and backend in one repo when the script render-postbuild is ran it comes from the root folder housing the frontend and backend. I know when the "NPM_CONFIG_PRODUCTION=false this is just a way to set the production to false until the npm run build is compiled then on the NODE_ENV side it will know we are in a production environment.

Hope this helps.

Collapse
 
joniedev profile image
Okoro John

That's great. I've gotten what I am looking for... timely.

Collapse
 
dineshraj100 profile image
Dineshraj • Edited

hello Greg, I need your help in this deployment. I did as you mentioned above. but for some reason my backend is failing to deploy. only thing i changed from your step was in build command. i changed yarn to npm install. help me with this issue please

the error in pic actually shows that concurrently is not found. i even tried to run it with yarn, its showing the same thing. But in my local machine concurrently runs with the same command "npm run dev"

my project github link: githublink

Image description

Collapse
 
dineshraj100 profile image
Dineshraj

ok. I solved this error by adding the dev dependencies inside the dependencies in package.json file. thanks for this guide greg