Deploy Parse Server, MongoDB and Parse Dashboard on Ubuntu 18.04
Parse is an excellent mBaaS developed by Parse Inc. (acquired by Facebook) then abandoned/Open Sourced. It has an active community and can help you build your mobile apps very fast.
Parse has SDKs for native android, javascript/react native and is very straightforward to integrate into your app.
If you would like to avoid the hassle of setting up and maintaing your own infrastructure, I recommend using back4app.com which provides good support for parse and offer a fair free tier service: * Ideal for developing, learning and prototyping * No credit card required10k Requests * 250 MB Database * 1 GB Transfer * 1 GB Storage
In my case, I always prefer maintaining my own servers and infrastructure. This tutorial can be automated by using ansible. but for now we will do the installation manually.
Install and secure MongoDB
On a fresh Ubuntu 18.04 VPS, use apt to install the latest available version of MongoDB:
$ sudo apt install -y mongodb
After the install finishes, check that the service is running:
$ sudo systemctl status mongodb
Output:
● mongodb.service - An object/document-oriented database
Loaded: loaded (/lib/systemd/system/mongodb.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2020-03-09 09:59:32 UTC; 11s ago
Docs: man:mongod(1)
Main PID: 31917 (mongod)
Tasks: 23 (limit: 2291)
CGroup: /system.slice/mongodb.service
└─31917 /usr/bin/mongod --unixSocketPrefix=/run/mongodb --config /etc/mongodb.conf
[...] systemd[1]: Started An object/document-oriented database.
Let’s also check that we can connect to mongodb:
$ mongo
MongoDB shell version v3.6.3
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.6.3
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see
http://docs.mongodb.org/
Questions? Try the support group
http://groups.google.com/group/mongodb-user
> db.runCommand({ connectionStatus: 1 })
{
"authInfo" : {
"authenticatedUsers" : [ ],
"authenticatedUserRoles" : [ ]
},
"ok" : 1
}
Important: don’t forget to secure access to the database
Check that mongodb only accepts connections from localhost. If you want to make the server accessible over the Internet, you can tweak your firewall settings. I recommend however connecting to the db server through an ssh tunnel.
$ sudo nano /etc/mongodb.conf
bind_ip = 127.0.0.1 should be uncommented Configure Access Control
By Default, no authentication is configured to access the db server.
$ mongo
2020-03-09T09:59:34.649+0000 I CONTROL [initandlisten]
2020-03-09T09:59:34.649+0000 I CONTROL [initandlisten] ** WARNING: Access control is not enabled for the database.
2020-03-09T09:59:34.649+0000 I CONTROL [initandlisten] ** Read and write access to data and configuration is unrestricted.
2020-03-09T09:59:34.649+0000 I CONTROL [initandlisten]
On the mongo console, switch to the admin database and create a new user:
> use admin
> db.createUser(
{
user: "superuser",
pwd: "changeMeToAStrongPassword",
roles: [ "root" ]
}
)
Successfully added user: { "user" : "superuser", "roles" : [ "root" ] }
Shutdonwn server:
> db.shutDownServer()
Edit /etc/mongod.conf to enable authorizations:
#auth = true <------- uncomment and save the file
Now you can log back in to the mongo cli and create your desired dbs and app specific users:
$ mongo admin -u <admin_user> -p <admin_password>
...
> use <new_db_name>
...
> db.createUser(...)
Install Parse Server
This step requires having nodejs installed on your machine.
We are going to use the Node.js application that uses the Parse Server module on Express and can be easily deployed to various infrastructure providers. This app is available here
Make sure to have git installed:
user@zeitouna:~# apt install git
Reading package lists... Done
Building dependency tree
Reading state information... Done
git is already the newest version (1:2.17.1-1ubuntu0.5).
Clone the parse-server-example and install dependencies:
$ cd /opt
$ git clone https://github.com/ParsePlatform/parse-server-example.git
$ cd parse-server-example
$ npm install
Create a .env file:
PARSE_SERVER_DATABASE_URI=mongodb://localhost:27017/<database_name>
PARSE_SERVER_APPLICATION_ID=<your_app_desired_id>
PARSE_SERVER_MASTER_KEY=<generate a strong master key and keep it scret!>
PARSE_SERVER_URL=http://localhost:1337/parse
Now to be able to load these variables from the .env file, we need to make some changes to the index.js file:
$ npm install --save dotenv
Open index.js:
var express = require('express');
var ParseServer = require('parse-server').ParseServer;
var path = require('path');
// read .env file
var dotenv = require('dotenv');
dotenv.config();
// also edit variable names accordingly!
...
You need to add the .env file to .gitignore :
# env file
.env
Configuring the Server
First it is important to impose a strong user password policy. In order to do this, edit index.js:
// add the following to the new ParseServer({}) object
passwordPolicy: {
// enforce password with at least 8 char with at least 1 lower case, 1 upper case and 1 digit
validatorPattern: /^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.{8,})/,
// a callback function to be invoked to validate the password
validatorCallback: (password) => { return validatePassword(password) },
doNotAllowUsername: true, // optional setting to disallow username in passwords
maxPasswordHistory: 5,
resetTokenValidityDuration: 24*60*60, // expire after 24 hours
}
Manage server with pm
Install pm globally:
$ sudo npm install -g pm2
Run the server with pm:
$ pm2 start index.js
$ pm2 startup
$ pm2 save
Install and configure Parse Dashboard
Install the dashboard from npm.
$ npm install -g parse-dashboard
Edit index.js to configure parse-server and parse-dashboard to run on the same server/port:
...
var ParseDashboard = require('parse-dashboard');
var api = new ParseServer({
// Parse Server settings
});
var options = { allowInsecureHTTP: false };
var dashboard = new ParseDashboard({
// Parse Dashboard settings
}, options);
var app = express();
// make the Parse Server available at /parse
app.use('/parse', api);
....
var dashApp = express();
// make the Parse Dashboard available at /dashboard
dashApp.use('/dashboard', dashboard);
// Parse Server plays nicely with the rest of your web routes
dashApp.get('/', function(req, res) {
res.status(200).send('Parse Dashboard App');
});
var httpServerDash = require('http').createServer(dashApp);
httpServerDash.listen(4040, function() {
console.log('dashboard-server running on port 4040.');
});
We configure Parse Dashboard with one app and one user:
"apps": [
{
"serverURL": process.env.PARSE_SERVER_URL,
"appId": process.env.PARSE_SERVER_APPLICATION_ID,
"masterKey": process.env.PARSE_SERVER_URL,
"appName": "applicationName"
}
],
"users": [
{
"user": process.env.PARSE_DASHBOARD_USERNAME,
"pass": process.env.PARSE_DASHBOARD_PASSWORD
}
],
"trustProxy": 1
Don’t forget to edit .env with the new variables PARSE_DASHBOARD_USERNAME and PARSE_DASHBOARD_PASSWORD
Installing NGINX and Let’s Encrypt
We will be setting up a reverse proxy to redirect all https traffic to parse server. In order to make this happen, we need to install nginx and configure SSL certificates from Let’s Encrypt.
Intsall nginx:
$ sudo apt install nginx
Then, add certbot repository:
$ sudo add-apt-repository ppa:certbot/certbot
$ sudo apt install python-certbot-nginx
Generate the SSL certificate:
$ sudo certbot -d <app.domain.com> --nginx
Now we are going to set the reverse proxy to route traffic to Parse. Open the corresponding nginx conf file:
...
# Pass requests for /parse/ to Parse Server instance at localhost:1337
location /parse/ {
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:1337;
proxy_ssl_session_reuse off;
proxy_set_header Host $http_host;
proxy_redirect off;
}
# Pass requests for /dashboard/ to Parse Server instance at localhost:4040
location /dashboard/ {
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:4040/dashboard/;
proxy_ssl_session_reuse off;
proxy_set_header Host $http_host;
proxy_redirect off;
}
...
restart nginx:
$ sudo service nginx restart
Conclusion
Login to https://app.domain.com/dashboard and you should be able to view and connect to Parse Dashboard correctly: