
The MERN stack consists of MongoDB, Express, React, and Node.js. Together, they allow developers to build applications on the web.
Prerequisites
- Deploy a fresh Ubuntu 20.04 LTS cloud server at Vultr.
- Setup a non-root user with sudo.
- Update your server.
1. Install Node.JS
Install the latest LTS version of Node.js via the NodeSource repository to ensure maximum compatibility with any packages or dependencies in the app.
Import the package signing key.
$ wget -qO- https://deb.nodesource.com/gpgkey/nodesource.gpg.key | sudo apt-key add -Add the NodeSource repository.
$ echo 'deb https://deb.nodesource.com/node_14.x focal main' | sudo tee -a /etc/apt/sources.listUpdate package lists.
$ sudo apt updateInstall Node.JS.
$ sudo apt install -y nodejs
2. Install MongoDB
MongoDB is the database that stores all the data for the application. MongoDB also provides a recommended repository for Ubuntu with the latest version.
Import package signing key.
$ wget -qO- https://www.mongodb.org/static/pgp/server-4.4.asc | sudo apt-key add -Add MongoDB repository.
$ echo 'deb [arch=amd64] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/4.4 multiverse' | sudo tee -a /etc/apt/sources.listUpdate package lists.
$ sudo apt updateInstall MongoDB Community Edition.
$ sudo apt install -y mongodb-orgEnable and start MongoDB.
$ sudo systemctl enable --now mongod
3. Setup the NPM Project
Create a new directory for the app.
$ mkdir -p app && cd appCreate a
package.jsonfile.$ npm init -yInstall the project dependencies: Express web framework, MongoDB driver, React, React DOM, Webpack, Babel, and Dotenv.
$ npm i express mongodb react react-dom webpack webpack-cli html-webpack-plugin @babel/core @babel/preset-env @babel/preset-react babel-loader dotenvCreate directories for the code.
$ mkdir src $ mkdir src/publicCreate
src/index.js, which contains the main server code for Express.$ nano src/index.jsPaste the following:
if (process.env.NODE_ENV !== "production") { require("dotenv").config(); } const path = require("path"); const express = require("express"); const app = express(); const { MongoClient } = require("mongodb"); (async () => { const mongo = new MongoClient(process.env.MONGODB); try { await mongo.connect(); } catch (e) { console.log("Failed connecting to MongoDB"); console.log(e); process.exit(1); } console.log("Connected to MongoDB"); app.use(express.static(path.join(__dirname, "../dist"))); app.listen(process.env.PORT); console.log(`HTTP listening on ${process.env.PORT}`); })();Save and exit the file.
Create
src/public/App.jsx, which includes the main code for the React portion of the app.$ nano src/public/App.jsxPaste the following:
import React from "react"; import ReactDOM from "react-dom"; const App = () => ( <div> <h1>App</h1> </div> ); ReactDOM.render(<App />, document.querySelector("#app"));Save and exit the file.
Create
src/public/index.html, which includes the base HTML which the compiled React code will be injected into. It also has the root element that it will render in.$ nano src/public/index.htmlPaste the following:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>MERN App</title> </head> <body> <div id="app"></div> </body> </html>Save and exit the file.
Create
webpack.config.js, which tells Webpack how to bundle the project.$ nano webpack.config.jsPaste the following:
module.exports = { entry: "./src/public/App.jsx", module: { rules: [ { test: /\.(js|jsx)$/, use: "babel-loader", }, ], }, plugins: [ new (require("html-webpack-plugin"))({ template: "./src/public/index.html", }), ], };Save and exit the file.
Create
.babelrc, which configures Babel to compile the React code.$ nano .babelrcPaste the following:
{ "presets": ["@babel/preset-env", "@babel/preset-react"] }Save and exit the file.
Create
.env, which configures the port and MongoDB database URL.$ nano .envPaste the following:
PORT=8080 MONGODB=mongodb://localhostSave and exit the file.
Build the app.
$ npx webpackStart the app.
$ node src/index.js
The app should now be available on port 8080.