How To Run Parse Server on Ubuntu 16.04

How To Run Parse Server on Ubuntu 16.04

I wanted to test Parse. Naturally, I first tried to find installation instructions for my target system (Ubuntu 16.04), but I didn’t find any. So, I took the closest version from Digital Ocean, which was for Ubuntu 14.04. However, it was outdated, and I needed to tune the installation process in several places. Also, once the server was running, I wanted to proceed a bit further. I installed parse-dashboard and process manager (pm2) to keep everything running nicely. Digging out all the information needed took some time, so I decided to document the process in case it would be helpful for somebody else.

For the documentation, I borrowed the page format and a lot of wording from the Digital Ocean guide mentioned above, giving credit for their good instructions on many topics.

Prerequisites

This guide assumes that you have a clean Ubuntu 16.04 system, configured with a non-root user with sudo privileges for administrative tasks.

I use a LXD container in my VPS, but you may use something else.

Step 1 – Install MongoDB

First, we will need to install MongoDB

Mongo Step 1 — Importing the Public Key

In this step, we will import the MongoDB GPG public key.

MongoDB is already included in Ubuntu package repositories, but the official MongoDB repository provides the most up-to-date version and is the recommended way of installing the software. Ubuntu ensures the authenticity of software packages by verifying that they are signed with GPG keys, so we first have to import they key for the official MongoDB repository.

To do so, execute:

$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 2930ADAE8CAF5059EE73BB4B58712A2291FA4AD5

After successfully importing the key, you will see:

Output
gpg: Total number processed: 1
gpg:               imported: 1  (RSA: 1)

Note: The Mongo project will change the signing key after every release. You can read more about that here. In case you get any errors installing MongoDB with these instructions, you can find up-to-date instructions on the Mongo site.

Mongo Step 2 — Creating a List File

Next, we have to add the MongoDB repository details so that APT will know where to download the packages from.

Issue the following command to create a list file for MongoDB.

$ echo "deb http://repo.mongodb.org/apt/ubuntu "$(lsb_release -sc)"/mongodb-org/3.6 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.6.list

After adding the repository details, we need to update the package list.

$ sudo apt-get update

Mongo Step 3 — Installing and Verifying MongoDB

Now, we can install the MongoDB package itself.

$ sudo apt-get install -y mongodb-org

This command will install several packages containing the latest stable version of MongoDB 3.6 along with helpful management tools for the MongoDB server.

After package installation, you need to start MongoDB.

$ sudo service mongod start

You can check that the MongoDB is running with the following command.

$ service mongod status

If MongoDB is running, you’ll see an output like this (with a different process ID).

Output
mongod start/running, process 1611

You can also stop, start, and restart MongoDB using the service command (e.g. service mongod stop, service mongod start).

Step 2 — Install Node.js and Development Tools

Begin by changing the current working path to your sudo user’s home directory:

>$ cd ~

NodeSource offers an Apt repository for Debian and Ubuntu Node.js packages. We’ll use it to install Node.js. NodeSource offers an installation script for the the latest stable release (v9.x at the time of this writing), which can be found in the installation instructions. Download and run the script with curl:

$ curl -sL https://deb.nodesource.com/setup_9.x | sudo -E bash -

It will add the node repository for apt and update the apt.

Once the script has finished, NodeSource repositories should be available on the system. We can use apt-get to install the nodejs package. We’ll also install the build-essential metapackage, which provides a range of development tools that may be useful later, and the Git version control system for retrieving projects from GitHub, as well as one necessary library – libkrb5-dev

$ sudo apt-get install -y nodejs build-essential git libkrb5-dev

Step 3 — Install an Example Parse Server App

Parse Server is designed to be used in conjunction with Express, a popular web application framework for Node.js which allows middleware components conforming to a defined API to be mounted on a given path. The parse-server-example repository contains a stubbed-out example implementation of this pattern.

Retrieve the repository with git:

$ git clone https://github.com/ParsePlatform/parse-server-example.git

Enter the parse-server-example directory you just cloned:

$ cd ~/parse-server-example

Use npm to install dependencies, including parse-server, in the current directory:

$ npm install

npm will fetch all of the modules required by parse-server and store them in ~/parse-server-example/node_modules directory.

Step 4 — Test the Sample Application

Use npm to start the service. This will run a command defined in the start property of package.json. You got it from the parse-server-example git. There it is defined that it runs node index.js:

$ npm start

Output

> parse-server-example@1.0.0 start /home/ubuntu/parse-server-example
> node index.js

DATABASE_URI not specified, falling back to localhost.
parse-server-example running on port 1337.

You can terminate the running application at any time by pressing Ctrl-C.

Output “DATABASE_URI not specified, falling back to localhost.” can be ignored. Everything will work just fine. This message comes from the first lines of index.js and if it bothers you, you can remove that check by removing those lines from the file.

The Express app defined in index.js will pass HTTP requests on to the parse-server module, which in turn communicates with your MongoDB instance and invokes functions defined in ~/parse-server-example/cloud/main.js.

In this case, the endpoint for Parse Server API calls defaults to:

http://your_server_IP/parse

In another terminal, you can use curl to test this endpoint. Make sure you’re logged into your server first, since these commands reference localhost instead of a specific IP address.

We can call a hello function defined in ~/parse-server-example/cloud/main.js:

curl -X POST \
  -H "X-Parse-Application-Id: myAppId" \
  -H "Content-Type: application/json" \
  -d '{}' \
  http://localhost:1337/parse/functions/hello

Output


{"result":"Hi"}

And now as it works, we can proceed. In your original terminal, press Ctrl-C to stop the running version of the Parse Server application.

That was the Parse installation.

Next, we go a bit further by installing a dashboard. When Parse was still run by a company, one nice feature of the service was the clear dashboard that allowed users to see what was stored in the service. Dashboard was also one of the first things that were made after the Parse was open sourced. Of course, I wanted to install that, too. It is very easy to do, as it is also an express/nodejs service and we just installed express/nodejs.

Step 5 – Install Parse-Dasboard

Installation is easy, just

$ sudo npm install parse-dashboard

(make sure that you are in the /parse-server-example/ directory)

but after that it needs a bit of configuration before it can be used. We will just need to set up a new configuration file (.js) for it and launch it the same way as we did with Parse earlier.

(That configuration could also be combined in the same configuration file and then both apps could be launched with one command. However, that approach cannot be extended easily so we will make a separate configuration file for it.)

Then there is still one issue: how to keep apps running? There are many options for that, such as nohup, screen, tmux commands/apps, but there are also specific process managers for nodejs. Here, we use one of those as it is also very easy and gives more visibility and control. So let’s install pm2 (=Advanced node.js process manager).

Step 6 – Install PM2

$ sudo npm install -g pm2

and then we can test it at once.

Launch Parse with it by typing

$ pm2 start index.js

The output is a nice table that lists your app and its information.

Let’s then close it by typing

$ pm2 stop index.js

There are a lot of commands and options for pm2. You can check them out in their cheatsheet, but here are a few of them as an example.


$ pm2 install pm2-logrotate
$ pm2 set pm2-logrotate:compress true 
$ pm2 set pm2-logrotate:retain 14

I guess that the above commands are quite self-explanatory and we can just go forward.

Step 7 – Configure Parse-Dashboard

Next, we will make a new configuration file for the dashboard to test that it works. Let’s also “rename” index.js so that we get a bit more of a structure to our files. So:


$ cp index.js app1.js 
$ cp index.js dashboard.js

App1.js is fine for starting Parse, as it is just a plain copy of the index.js file. But we need to edit dashboard.js, as currently it is also just a plain copy of index.js. So, open it in your favorite editor. I will use nano.

$ pm2 nano dashboard.js

There are several changes, so instead of listing them here, I will let you check them out in the clip below. If you haven’t edited a Parse start file before, you can just copy & paste it from below and only modify the <your_domain> part. <your_domain> should be an address that your web browser can access.

// Example express application adding the parse-server module to expose Parse
// compatible API routes.

var express = require('express');
var ParseDashboard = require('parse-dashboard');

// You might need this. Use 'true' or 'false' depending your connection.
var options = {allowInsecureHTTP: true };

var app = express();

// Set up parse dashboard

var trustProxy = true;
var dashboard = new ParseDashboard({  
  "apps": [{
      "serverURL": 'https:///parse', 
      "appId": 'myAppId', // Use the same 'myAppId' what you used in parse setup
      "masterKey": '', // Use the same 'masterKey' what you used in parse setup
      "appName": "app1",
      "production": false,
      "iconName": "icon.png",
  }],
  "trustProxy": 1,
  "users": [
    {
      "user":"username",
      "pass":"password"
    }
  ],
  "iconsFolder": "icons"
}, options);

var dashApp = express();

// make the Parse Dashboard available at /dashboard
dashApp.use('/dashboard', dashboard);  

// Parse Dashboard 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.');
});

With this, we are almost ready. Now we could use pm2 to start the apps by using their own configuration files like

$ pm2 start app1.js dashboard.js

but let’s take it still a bit further, and create a configuration file for the pm2, too.

So, make a ‘apps.json’ file with your editor

$ nano apps.json

and add the following content in it. Make sure that the name, script and working directory (=cwd) match your setup.

{
  "apps": [
    {
      "name": "app1",
      "script": "app1.js",
      "cwd": "/home/ubuntu/parse-server-example",
      "log_file": "logs/app1.log",
      "error_file": "logs/app1.log",
      "log_date_format": "YYYY-MM-DD HH:mm:ss Z",
      "instances": 1,
      "exec_mode": "fork",
    },
    {
      "name": "dashboard",
      "script": "dashboard.js",
      "cwd": "/home/ubuntu/parse-server-example",
      "log_file": "logs/dashboard.log",
      "error_file": "logs/dashboard.log",
      "log_date_format": "YYYY-MM-DD HH:mm:ss Z",
      "instances": 1,
      "exec_mode": "fork",
    }
  ]
}

(Now with this structure, you can easily add more Parse apps by cloning app1.js and tuning the new file, and then by adding a new block to the apps.json file. This is needed as a new Parse server instance/process is need for each app, because the Parse server doesn’t fully support running concurrent apps.)

And now we can start the apps with the following command:

$ pm2 start apps.json

and if all looks fine, we will finally give the command

$ pm2 save 

to save the running processes and make pm2 to restart them automatically if the server is restarted or apps fail for some reason.

Step 8 – Test Parse-Dashboard

Connect to parse-dashboard by typing your installation address (/dashboard). Login with the username and password that you set up earlier in the configuration file.

At this point, everything should look fine, except for that the parse-dashboard does not have an app icon.
It can be added easily by making an ‘icons’ directory to the ‘parse-server-example’ directory and downloading an image there. You can test it e.g. with the following command.

$ wget -O MyAppIcon.png 

Reload the page, and the new icon should be visible.

Step 9 – Encrypt connections

If you installed all of this to your local machine, you can skip this part. But if you installed Parse to another server that is reachable from the web, you should encrypt the connection. You can do that by getting a certificate (e.g. from Let’s encrypt) for the Parse app directly, or by installing a web server in front of the Parse installation as a Proxy. I will provide instructions below for using an Apache web server for this, as I had Apache already in use.

Digital Ocean have good instructions for how to install apache on ubuntu 16.04 and how to install a free certificate for it.

After you have followed those guides, the only thing you need to do is to set a few rules to your web server’s configuration file. So, open the configuration file with an editor.

$ sudo nano /etc/apache2/sites-enabled/.conf

Add the following directions e.g. right after the reference to Let’s encrypt
(For me, it shows as ‘Include /etc/letsencrypt/options-ssl-apache.conf’)

 SSLProxyEngine on

 ProxyPass "/dashboard/" http://localhost:4040/dashboard/
 ProxyPassReverse "/dashboard/" http://localhost:4040/dashboard/

 ProxyPass "/parse/" http://localhost:1337/parse/
 ProxyPassReverse "/parse/" http://localhost:1337/parse/

Then you should be able to access your Parse and parse-dashboard installations with urls such as https:///parse/ and https:///dashboard/

And this is the end of this guide.


Below are some errors I encountered on the way, and fixes for them.

fatal error: gssapi/gssapi.h: No such file or directory
-> You haven’t installed ‘libkrb5-dev’

Error: Cannot find module ‘parse-dashboard’
-> you installed parse-dashboard to the wrong directory