Surviving the Parse Apocalypse [tutorial]
Part 2/2 Set up the Parse Server, update your mobile apps & set up the dashboard.
Setting up the Parse Server
By now we all (hopefully) have heard the news. Parse is shutting down January 2017. In Part 1 of this tutorial we began to tackle the issue of ensuring the safety of your apps that rely on Parse. If you missed that, you can catch up here.
*NOTE: We had to work our way around Medium’s formatting and font constraints to make this tutorial was as clear as possible. So, lines of code are noted as bolded italic text within paragraph blocks.
As we mentioned in the first Part 1 of this tutorial, the Parse server is entirely self-contained and built on node.js. Once you have it installed, it’s fairly simple to start up:
$ parse-server --appId APPLICATION_ID --masterKey MASTER_KEY
--databaseURI mongodb://admin:password@localhost/mydb
(Where APPLICATION_ID and MASTER_KEY are determined by you.)
This will work, but it’s not very robust. You want it running constantly in the background. You want it to restart if it crashes, or even if the server itself is rebooted. Fortunately, there’s a tool that’s perfect for that: PM2.
PM2 is a process manager for node.js servers, which makes it ideal for the Parse server. It allows you to define and manage an instance (or even multiple instances) of Parse and keep it running. It also has some nice tools to manage and monitor running instances. You should go to the link above and read up about PM2; our knowledge of it only goes as far as we needed for this project, but there’s a lot more to learn.
Because PM2 is a node.js package, you’ll need to install it with npm:
$ sudo npm install pm2 -g
Once installation is complete, you’ll want to set up a configuration file to define your Parse instance that PM2 will run and maintain. In your project directory (which, for the purposes of this article, we’ll call /home/user/project), create a file called ecosystem.json. Put this in it:
{
"apps" : [{
"name" : "my-app",
"script" : "/usr/local/bin/parse-server",
"watch" : true,
"merge_logs" : true,
"cwd" : "/home/user/project",
"env": {
"PARSE_SERVER_CLOUD_CODE_MAIN":
"/home/user/project/cloud/main.js",
"PARSE_SERVER_DATABASE_URI":
"mongodb://admin:password@localhost/myd b",
"PARSE_SERVER_APPLICATION_ID": "ID1234567",
"PARSE_SERVER_REST_API_KEY": "APIKEY1234567",
"PORT": "1337",
"PARSE_SERVER_MASTER_KEY": "MASTERKEY1234567",
"PARSE_PUBLIC_SERVER_URL": "http://myapp.com:1337/parse/"
}
}]
}
A few things to take note of:
-“name”, of course, is arbitrary. It can be whatever you want.
-“script” is the location of the parse-server binary; it will be wherever npm installed it, but probably /usr/local/bin.
-“watch” is a very useful feature. It tells PM2 to automatically restart the process if any file changes in your project. This is especially nice when making changes to Cloud Code.
-“env” defines some critical environment variables for your Parse instance, some of which you’ll recognize from the earlier parse command:
- PARSE_SERVER_CLOUD_CODE_MAIN: The path to your Cloud Code, if you have any.
- PARSE_SERVER_DATABASE_URI: The URI to connect to your MongoDB database.
- PARSE_SERVER_APPLICATION_ID and PARSE_SERVER_REST_API_KEY: These are the keys that provide access to your back-end from mobile or web apps. Obviously the ones included here are examples; you’ll want something more secure. If you want, you can just copy the existing ones from your current Parse app, but either way, make sure you keep them protected.
- PORT: The port that your Parse server will listen on.
- PARSE_SERVER_MASTER_KEY: This is not needed for your mobile/web apps, but it will be needed if you want to set up the open-source Parse Dashboard, which we’ll discuss later.
- PARSE_PUBLIC_SERVER_URL: Also required for the Parse Dashboard; it should point to the host name of your server and the port you have defined for the Parse server.
There are other settings available that we did not use in this case. You can find more information here.
Be sure to back up ecosystem.json to a safe place. You may or may not want to check it into a repository, since it contains API keys that need to be kept secure. That’s up to you.
Now that you have defined your Parse instance, it’s time to start it up with PM2. In your project folder, type the following:
$ pm2 start ecosystem.json
$ pm2 save
The first command tells PM2 to start up the app(s) defined in ecosystem.json. The second command, pm2 save, tells it to save the newly loaded configuration to a file called dump.pm2, located in the .pm2/ directory in your home path. From now on, PM2 will automatically look for this file any time it starts up.
Now, you should have your Parse app running on the server. To verify this, type:
$ pm2 list
And you should see a list of running apps.
If you ever need to make changes to your configuration, just update ecosystem.json, and run the following commands (I’ve actually wrapped them up into a bash script called reset-parse-apps.sh for convenience):
$ pm2 stop all
$ pm2 delete all
$ pm2 start ecosystem.json
$ pm2 save
This should be fairly self-explanatory: stop all running apps and delete the configuration saved to dump.pm2, reload everything from ecosystem.json, and save the new configuration to dump.pm2.
If you ever need to just stop or restart your running apps, you can use the commands pm2 stop all (followed by pm2 start all to start them up again) or pm2 restart all, respectively. If you have more than one app running, you can apply these commands selectively to them by replacing all with the numeric ID that appears under the id column in the list shown by running pm2 list.
Now, if everything went well, you should have a new instance of Parse server running on your own server, pointing to your own database, which contains the data that was previously in your app hosted on Parse’s servers. You’ll want to test it and make sure everything is working; the easiest way to do this is with some simple Cloud Code functions. First, you can create a “Ping” function in your Cloud Code, like this:
Parse.Cloud.define("ping", function(request, response) {
response.success("OK");
});
If you then make a call to http://myapp.com:1337/parse/ping (where myapp.com, of course, is replaced with your host name) with the correct App ID and REST Key in the headers, you should get the response:
{
“result”: “OK”
}
You also want to test database connectivity. You can do this by creating a table named TestTable in your database through the Parse dashboard (remember, the dashboard at https://dashboard.parse.com/apps now points to the MongoDB instance on your own server) with a String field named test. Then, create a Cloud Code function to write to that database:
Parse.Cloud.define(“testdb”, function(request, response) {
var query = new Parse.Query(“TestTable”);
query.first().then(function(object){
if (object == undefined) {
object = new Parse.Object(“TestTable”);
}
object.set(“test”, “OK”);
object.save();
response.success(object);
});
});
As you can see, this function is pretty simple. It queries TestTable for the first object available; if there isn’t one, it creates a new one. It then updates the test field to have the text “OK”, and saves the object.
Once this Cloud Code has been uploaded to your server, you can make a call to http://myapp.com:1337/parse/testdb. Go check TestTable on the Parse dashboard and make sure that there is a new entry with “OK” in the test field, and a recent timestamp under updatedAt.
Once you have verified that your new Parse server is working correctly, it’s time to update the mobile apps.
Updating your Mobile Apps
Now you need to take care of the other side of the equation: the apps that actually connect to your Parse server. Fortunately, this should be the easiest part.
If you haven’t done so already, the first thing you need to do is update to the latest version of the Parse SDK. The instructions for doing that can be found here (for iOS) or here (for Android). Not much has changed, but there is one crucial difference: you now have the ability to specify the Parse URL, which you will obviously need to point the SDK to your new server. The method for doing that differs based on which platform you’re using, so you should read the instructions at the above URLs for that information.
Now build your new mobile apps and verify that they work correctly; reading and writing to your new MongoDB database, calling the necessary Cloud Code, etc.
If everything looks good, you’re ready to update your users to the new app. And again, this is where Parse makes things easier for you. One of the big problems with updating client-based software is that you have no control over when your users will receive the update, and when (or whether) they will install it. This can make it a nightmare to keep things in sync when you’re doing something as tricky as moving to a new API. But in this case, it doesn’t really matter. Users on the old app will be going to the old Parse instance, and users on the new app will be going to your new open-source Parse Server — but they’re both pointing to the exact same database. So as long as all of your users update before January 28, 2017, when Parse shuts down for good, they’ll be fine.
So you should be in good shape now. You have your own Parse server and database running on your own system. You also have released an update to your mobile apps that points to this server instead of the soon-to-be-dead official Parse servers. You could decide to be done at this point, but there’s one more thing you should probably do: set up the Dashboard. We’ll cover that in the final segment of this series.
Setting up the Dashboard
In the previous two posts, we walked you through the process of setting up your own open-source Parse Server and updating your mobile apps to point to it. This might be sufficient for your needs, but there’s one other piece that you’ll be missing: the Dashboard. Parse’s dashboard provides a useful web interface for your app, giving you access to the data directly from your browser. Fortunately, this has been opened up as well, and you can set up your own Dashboard to run alongside your Parse Server.
Note that this is, unfortunately, a somewhat slimmed down version of the Parse Dashboard you are used to. Some features have not (yet, at least) made the transition, including Cloud Code and Analytics. This blog post on Savvy Apps has a more complete list of what’s missing.
To get started, you’ll first need to install parse-dashboard. Like parse-server, you install it with npm:
$ sudo npm install -g parse-dashboard
As with parse-server, you can run it directly from the command line, but that’s not what we want to do here. We want to control it with PM2, alongside our parse-server instance. Fortunately, it’s pretty easy to add a new app to our ecosystem.json configuration file. You’ll notice that the apps entry in the file is a JSON Array, currently with only one entry. We just need to add a new one:
{
"apps" : [{
"name" : "my-app",
"script" : "/usr/local/bin/parse-server",
"watch" : true,
"merge_logs" : true,
"cwd" : "/home/user/project",
"env": {
"PARSE_SERVER_CLOUD_CODE_MAIN":
"/home/user/project/cloud/main.js",
"PARSE_SERVER_DATABASE_URI":
"mongodb://admin:password@localhost/mydb",
"PARSE_SERVER_APPLICATION_ID": "ID1234567",
"PARSE_SERVER_REST_API_KEY": "APIKEY1234567",
"PORT": "1337",
"PARSE_SERVER_MASTER_KEY": "MASTERKEY1234567",
"PARSE_PUBLIC_SERVER_URL": "http://myapp.com:1337/parse/"
}
},
{
"name" : "my-app-dashboard",
"script" : "/usr/local/bin/parse-dashboard",
"watch" : true,
"merge_logs" : true,
"cwd" : "/home/user/project",
"env": {
"PARSE_DASHBOARD_APP_ID": "ID1234567",
"PARSE_DASHBOARD_MASTER_KEY": "MASTERKEY1234567",
"PORT": "4041",
"PARSE_DASHBOARD_APP_NAME": "My App",
"PARSE_DASHBOARD_USER_ID": "admin",
"PARSE_DASHBOARD_USER_PASSWORD": "password",
"PARSE_DASHBOARD_ALLOW_INSECURE_HTTP": "1",
"PARSE_DASHBOARD_SERVER_URL": "http://myapp.com:1337/parse"
}
}]
}
So now ecosystem.json has two entries: the parse-server instance we created earlier, and a new parse-dashboard instance. A few important notes about env:
- PARSE_DASHBOARD_APP_ID and PARSE_DASHBOARD_MASTER_KEY must match the corresponding values in the parse-server entry.
- PORT can be whatever you want, but the default is 4041.
- PARSE_DASHBOARD_APP_NAME is also up to you. This is the name that displays on the Dashboard.
- When a user opens the Dashboard in their web browser, they will be asked to log in with Basic HTTP Auth. PARSE_DASHBOARD_USER_ID and PARSE_DASHBOARD_USER_PASSWORD define the username and password they will need.
- If PARSE_DASHBOARD_ALLOW_INSECURE_HTTP is 1, then the Dashboard will work over http. Otherwise, it will require SSL. It’s probably OK to set it to 1 to start with, but you should enable SSL and install a certificate as soon as possible.
- PARSE_DASHBOARD_SERVER_URL tells your Dashboard where to find the Parse server. Note that it should match PARSE_PUBLIC_SERVER_URL in the parse-server configuration.
Once you have finished updating ecosystem.json, it’s time to reload your apps with PM2:
$ pm2 stop all
$ pm2 delete all
$ pm2 start ecosystem.json
$ pm2 save
Now type pm2 list. You should see two entries in the table: parse-server, and parse-dashboard. Open your browser and go to your Dashboard URL (http://myapp.com:4041/apps, in our example). Enter the username and password you put in your configuration file, and you’ll be taken to the Parse Dashboard.
Wrapping Up
And that’s pretty much it! A few days’ worth of work allows you to get your Parse app off of a sinking ship and into its own secure, stable environment, without causing any disruption to your end users. For those of us who have relied on Parse for its ability to get an API and back-end up and running quickly and easily, this is a real lifesaver.
Please leave a comment if you’ve got any questions. We’re happy to help. Also, if there are any other tech tutorials you’d like to see let us know!