Chapter 5: DigitalOcean

DigitalOcean

DigitalOcean is a cheap, fast, and flexible option for hosting web applications, but is it the best option for hosting a Meteor application?

The answer: “It depends.”

The problem with flexibility is that a lot more can go wrong along the way, so while you have the freedom to tweak the server to your precise preferences, you’re also left with the ability to break everything without having any idea of how to fix it.

That said:

  1. The barrier-to-entry isn’t overwhelmingly massive.
  2. You’ll want to learn how to work with a barebones server sooner or later.
  3. This guide will help get you up to speed quickly and (relatively) easily.

Generally, I’d suggest that beginners get started with a service like Modulus, simply because there’s fewer variables to think about, but DigitalOcean is a great training ground to develop your skills.

Introducing, Meteor Up

Deploying a Meteor application to DigitalOcean is not just a matter of uploading some files to a web server. We also have to:

  • Install some software on the server.
  • Configure that software.
  • Make sure nothing breaks along the way.

Usually, this would involve writing out a lot of commands, and it could take an hour or two to get things working as expected, but luckily, the lovely folks at Meteor Hacks have built Meteor Up — a command line tool that automates the vast majority of the server setup and deployment process.

Here’s how it works:

  1. You install Meteor Up on your computer.
  2. You create a server (a “droplet”) on DigitalOcean.
  3. You add Meteor Up to a Meteor project.
  4. You tweak a few Meteor Up settings for that project.
  5. You initiate a setup process, which installs and configures all of the necessary software on your server (Node, Mongo, etc).
  6. You deploy your Meteor project to the server.

The tool is similar to the Modulus tool, but isn’t tied to any particular service. So while we’ll focus on DigitalOcean, everything we learn here will also apply to other server hosting companies (like Linode).

You might be wondering though: Is there any value in taking the manual approach to setting up a server?

And I’d say, “Yes. Absolutely. The manual approach is a great way to grasp what’s happening on your server and where certain problems might arise.”

But while it’s useful to understand what’s going on behind the scenes, that doesn’t mean it’s the best place to start. Meteor Up excels not just in terms of simplicity, but also in terms of providing a bird’s eye view of server setup and deployment. For that reason, it’s a great stepping-stone, even if it’s not a regular tool in your arsenal. (But chances are, you’ll fall madly in love with it like most other Meteor developers.)

Getting Started

To install Meteor Up, run the following command on your computer:

npm install -g mup

But if the command returns an error, run it again with sudo to run it with administrator permissions:

sudo npm install -g mup

Create an SSH Key

In a moment, we’ll setup a server on DigitalOcean and, by default, we’ll be sent a username and a password to login to that server. But while usernames and passwords are a familiar form of authentication, they’re not the most secure option, and when working with Meteor Up, they’re not the most convenient option either.

Instead, we’ll learn how to use SSH keys — an alternative form of authentication that can feel weird to setup, but in the end is much easier to work with for deployment.

By using an SSH key, we can make it so our DigitalOcean server “trusts” our computer, meaning we’ll no longer need a username or password. We will, however, need to take a couple of extra steps.

Step #1: Check if there’s already an SSH key on your computer

If you’ve never used an SSH key before, there probably isn’t one on your computer. But it still doesn’t hurt to check, just to make sure.

This can be done with the following command:

cd ~/.ssh

Then:

ls *.pub

If nothing is returned, then an SSH key is not setup. If something is returned though, then an SSH key is setup and you can skip to the third step.

Step #2: Generate an SSH key

SSH keys are long strings that are generated using complex algorithms. You can generate an SSH key for your computer with the following command:

ssh-keygen -t rsa -C "email@domain.com"

(Make sure to replace the “email@domain.com” part with your own email.)

You’ll be asked where you want to save the file, but the default location is fine, so just tap the “Return” key.

You’ll also be asked if you would like to set a passphrase for the SSH key, but this is not something we want to do since it’ll interfere with Meteor Up. As such, just tap the “Return” key twice to continue.

Step #3: Retrieve the SSH key

After an SSH key has been generated, we can retrieve it with the following command:

cat ~/.ssh/id_rsa.pub

Copy the returned value to the clipboard before continuing.

Step #4: Add the SSH key to DigitalOcean

If you haven’t registered for a DigitalOcean account, do that. You only pay when you have an active server, so there’s no cost to simply registering.

Once logged-in, navigate to the “Your Settings” page:

Your Settings

Click the “Security” tab.

Setting Page

Scroll down to the “Add an SSH Key” section:

Add an SSH key

Then enter a name for the SSH key. (You might like to name the key after the computer it was generated on, such as “Personal Computer”.)

Paste the SSH key into the text area:

SSH key in text area

…and click the “Create SSH Key” button.

Step #5: Pat yourself on the back

Leaving behind the familiarity of usernames and passwords might feel like a grand adventure, but since we only need to setup an SSH key for each computer we want to deploy from — rather than setup an SSH key for each server we want to deploy to — we won’t have to think about (or repeat) this process very often. We’re also now ready to focus on the fun stuff.

Create a Droplet

From inside the DigitalOcean control panel, click the “Create Droplet” button:

Create Droplet button

Note: A “droplet” is just DigitalOcean’s word for “virtual private server”.

On the page that loads, choose a hostname for the server. This would be something like meteortips.com or davidturnbull.com. (For this example though, the precise hostname doesn’t matter since we’ll only be referencing the server’s IP address.)

Create Droplet page

Then define the following settings:

  • Size. The $5 per month option is fine. It’s not enough for an application that has an active userbase, but it’s good enough for messing around.
  • Location. Choose somewhere close to your primary audience (which, at this point, might just be you). Google Analytics can help figure this out.
  • Available Settings. Leave these unchecked. (The backup option is decent when used with other safe-guards, but isn’t exactly necessary during development.)

Under the “Distributions” tab, select the “Ubuntu” option and leave the version number set to the default value.

Distributions

Beneath the “Add SSH Keys” heading, select the key that we setup in the previous section. This will allow us to login to our server without a username or password.

Add SSH Keys

Then click the “Create Droplet” button.

It’ll take about a minute to provision the server and, once it’s ready, copy its IP address to the clipboard so you’re ready for the next step.

Server Setup

Before we can deploy a Meteor project to the server, we’ll need to install and configure a few fundamental pieces of software to that server. Luckily, this is something that Meteor Up can handle for us.

To begin, navigate into the folder of a Meteor project. I’ll be using “Todos” as an example, which is inside a “Meteor” folder I created:

cd Meteor/todos

Then run the following command:

mup init

This is a Meteor Up command that prepares a project for deployment by creating two files in the project’s root folder:

  • mup.json
  • settings.json

Open the mup.json file, but don’t be overwhelmed by the settings. We’ll break this down into bite-sized chunks and it’ll make sense soon enough.

Project files

Step #1: Configure the server details

The first chunk of code is the following:

"servers": [
    {
        "host": "hostname",
        "username": "root",
        "password": "password"
        // or pem file (ssh based authentication)
        //"pem": "~/.ssh/id_rsa"
    }
]

These are the settings that allow Meteor Up to connect to a server, and this is what we need to do with them:

  1. Set the “host” value to the IP address of the droplet.
  2. Leave the “username” property set to the value of “root”.
  3. Comment out the “password” property.
  4. Uncomment the “pem” property.

With these changes, we’re telling Meteor Up to connect to the server as the root user, but instead of authenticating with a username and password, we’re authenticating with the SSH key that we attached to the server.

The modified code should look something like this:

"servers": [
    {
        "host": "104.236.160.167",
        "username": "root",
        // "password": "password"
        // or pem file (ssh based authentication)
        "pem": "~/.ssh/id_rsa"
    }
]

Step #2: Choose what software to install

By default, Meteor Up is configured to install the following pieces of software during the setup process:

  • Node
  • Mongo
  • Phantom

This is what the code looks like:

"setupMongo": true,
"setupNode": true,
"nodeVersion": "0.10.36",
"setupPhantom": true,

The only strictly necessary software is Node, so don’t touch either of the statements that relate to Node.

If you’re using an externally hosted database, you won’t need Mongo on the server, so feel free to comment out the “setupMongo” property.

Phantom is used to optimise Meteor applications for search engines, but if you’re not planning on using it, comment out the “setupPhantom” property.

Step #3: Define the remaining settings

The last chunk of code is the following:

"appName": "meteor",
"app": "/path/to/the/app",
"env": {
    "ROOT_URL": "http://myapp.com"
},
"deployCheckWaitTime": 15

Here’s what to do with it:

Set the “appName” property to the name of the application.

Set the “app” property to the path of the application. Because the mup.json file is in the project’s root directory, set this value to a period.

Set the “ROOT_URL” property to the IP address of the server. Make sure to include the “http” part at the start of the address.

To connect the project to an external database, add a “MONGO_URL” property that holds the value of a Mongo URI (example below).

Note: If you don’t define a “MONGO_URL” property, a database will be created on the server and associated with the project. The name of the database will be the same as the “appName” property. (In this case, make sure Mongo is installed during setup.)

The “deployCheckWaitTime” property is the amount of seconds that Meteor Up will wait after deployment before checking that the application is online. Leave this set to the default value of “15”.

In the end, this chunk of code should resemble:

"appName": "todos",
"app": ".",
"env": {
    "ROOT_URL": "http://104.236.160.167",
    "MONGO_URL": "mongodb://myusername:mypassword@ds041238.mongolab.com:41238/dturnbull"
},
"deployCheckWaitTime": 15

Or, if you’re not using an externally hosted database, then there won’t be the “MONGO_URL” property:

"appName": "todos",
"app": ".",
"env": {
    "ROOT_URL": "http://104.236.160.167"
},
"deployCheckWaitTime": 15

Step #4: Begin the setup process

With this configuration in place, run the following command:

mup setup

This will initiate the setup process, installing and configuring the software on the droplet. It should only take a few minutes.

mup setup command

Deployment

As was the case with Modulus, the setup process is where most of the effort lies, so once the setup is out of the way, the deployment process is easy.

While inside a project’s folder, run the following command:

mup deploy

This command will:

  • Upload the project’s files to the droplet.
  • Connect the project to the Mongo database.
  • Make the project accessible via the hostname (or IP address).

Whenever you need to re-deploy the project, navigate back into the project’s folder and run the mup deploy command again.

Deployed Meteor application

Resources