2015-08-12

What is “deploying?”

When we talk about deploying an application, what we really mean is making that application accessible to others outside of our own computer or our local network. When we “deploy” something, we send it to one of a few targets: different environments where our application will run. Depending on the type of application we’re building and what we need to test, we generally deploy to one of the following environments:

Development

While not necessarily an environment that we deploy to, our development environment is sort of like the mothership. This is where the bulk of our work occurs. This is your local computer (or your teammate’s computer) where you run your application in isolation and actually develop it. For example, this is where we can throw random bits and bobs of data into the database without worrying.

Staging

A staging environment is another name for an environment that closely mimics our final production environment, but isn’t accessible by users or customers. We use this environment to “stage” our application for testing purposes. Why? Well, as much as we’d like our application to behave in production exactly as it does on our local machine, unfortunately, that’s rarely the case.

Because our live application is interacting with so many different parts (e.g. our database might live on a service independent of our hosting service), we have to test and account for this. A staging environment, then, allows us to do this without breaking things for real-world users or paying customers.

Production

Another environment—the one we think of most when we say “deployment”—is the production environment. This is the environment that users and customers have access to. In other words, the production environment is sacred ground. As best as we can, we need to ensure that the code we’re deploying to this environment is stable and working; hence our use of the staging server!

What is Modulus?

Modulus is a PaaS (Platform-as-a-Service) company that offers hosting for Node.js, PHP, Java, Static Sites, and most importantly: Meteor applications (technically a Meteor application built as a Node.js application). It’s a favorite of Meteor developers because they offer an easy workflow (similar to Meteor’s meteor deploy) that allows for fast deployment of applications. Additionally, they also handle the more difficult aspects of configuring servers, meaning our focus as developers is kept on writing the software, not managing the systems that host our software.

Did Modulus sponsor this post?

Nope! Modulus just happens to be a favorite of mine and is the service used to power all of the Meteor applications behind the scenes at The Meteor Chef. If anything, this is a fanboy post. No paid shilling here :)

Alternatives to Modulus

Before we dig into getting set up on Modulus, you may be wondering…”are there alternatives to Modulus?” Of course! Here’s a quick look at some of the more popular options for hosting a Meteor application (and how they differ) with Modulus:

Digital Ocean

Digital Ocean is a popular choice for hosting Meteor applications due to its value. The service is fairly inexpensive and offers a “blank slate” server using one of six operating systems: Ubuntu, Fedora, Debian, CentOS, CoreOS, or FreeBSD. The difference between Digital Ocean—“D.O.” (DEE-OH) as you may hear in nerd-to-nerd conversations—and something like Modulus is that installation and configuration of all the software needed to run your application is left up to you. For example, you will need to install Node.js, MongoDB, and all other tools needed to get up and running.

Though inexpensive, D.O. is best reserved for developers who have some experience with system administration, or, aren’t afraid to get their hands dirty.

Amazon EC2

Another option for hosting our Meteor applications is Amazon EC2. This service is similar to Digital Ocean in that it allows you to spin up virtual “instances” (copies) of your application. Again, configuration and management of these instances is up to you so working with EC2 requires a fair bit of system administration knowledge to get up and running.

A loophole!

If you’re interested in saving a bit of cash using something like Digital Ocean or Amazon EC2—and don’t mind getting your hands a little bit dirty—you can make use of the wonderful Meteor Up tool built by Arunoda Susiripala. Up gives you an easy-to-configure file that automatically installs and configures the software you need to run a Meteor application on Debian/Ubuntu and Open Solaris backed servers.

Heroku

Possibly the closest option to Modulus at the moment, Heroku, allows you to easily deploy your application and add support for different things like databases, sending email, and error logging through something they call “add-ons.” To make the initial configuration of Heroku a bit easier, you can make use of the Heroku Buildpack for Meteor by Jordan Sissel.

What’s the best?

Oh, silly you, can you guess the answer? It’s up to you! All of these services essentially get us the same end using different means. My advice: experiment. Put aside a few days (or even weeks) to evaluate the different options and figure out what is most comfortable for you and/or your team.

In order to get started with deploying to Modulus we need to set up an account on their site. Let’s hop over their now and get set up!

Setting up an account on Modulus

The easy part! Well…this is actually all pretty easy (a good thing). Pretty much what you’d expect. Hop over to the Modulus site and hit their signup page.



One of the nice things—and something that’s made myself and clients very happy—is that you get a credit for signing up with Modulus so your servers will run for about one month 100% free. This is really handy if you’re on the fence and don’t want to pay any money just yet and want to get a hands-on feel for the service.

Once this is in place, we’re going to pause on the dashboard for a bit and get the Modulus CLI installed.

Installing the Modulus CLI

The CLI—command line interface—for Modulus is really handy. This is what we can use to quickly and easily deploy our application to the service and perform some administrative and maintenance tasks. To install it, we need to make sure we have Node.js/NPM is installed first (they should be, but just in case you get an error). Once that is in place, we can hop into our terminal and get on with it:

Terminal

This will get Modulus installed on our machine and give us access to the CLI via the modulus command. Just to make sure we’ve got everything setup correctly, go ahead and run modulus login to login to the account we set up earlier.



If all is well we should get the Signed in as user <username> message! Now that we’ve got this squared away, we need to set up a server and a database on Modulus. This is just as easy, but we need to pay attention so we have the right information for setting up our app.

Setting up a server and a database

If we hop back over to the Modulus dashboard, we can create a server and a database pretty quickly. From your dashboard, click on the “Create a New Project” button to spin up a server:



Okay, this is where we need to pay attention. First, we need to give our server a name. This can be anything you’d like, but make sure to jot it down. This is case sensitive, so make sure to use something easy that you will remember.

Next, we need to pick which type of project we’re going to set up. Where’s Meteor? Didn’t they advertise that on the home page? They did, but—sneaky, sneaky—technically a Meteor application is just a Node.js application. As we’ll learn in a bit, to get our app working on Modulus we need to convert it from a Meteor app into a plain Node.js app so that it works. Don’t worry, Modulus has automated this for us. For now, let’s just select the NODE.JS option.

After this, we get into some more specific details about our server, specifically, how much memory we want allocated to it. How much do we need? It depends on the application. Memory is where your server stores data that it’s going to either write or read from the database. Think of it like a waiting room for your CPU (central processing unit). The amount of memory you have is the size of your waiting room.

If your application has a lot of traffic—translating to user interactions resulting in read/write operations on your database—your memory will fill up as things “wait” to either go into the database or come out of the database. Just like a waiting room, data—or people—are only there temporarily. When the computer turns off (or the data is no longer required), it empties out.

Contrast this with a hard drive which is meant as a more permanent storage: staying in the hospital for a few weeks because you “just had to see if I could jump my bike off the roof.”

So, what does this translate to? We need to select memory size based on the relative amount of usage our application will have. If our application is only for internal use or deployed to a small set of users, we can probably get away with a lower amount of memory like 192MB or 396MB. This is also a good size for a staging server which will only ever have a handful of people on it at once (trivial for memory).

In terms of a production application that’s seeing regular usage, the 512MB and up options are probably a better fit. Keep in mind, though, don’t just max out your memory for the hell of it. Start with whatever you think the lowest possible amount you can use is and then monitor usage. One of your responsibilities as a Sworn Knight of Production is conserving resources as much as possible; yes, even you Silicon Valley cowpokes with your bottomless bank accounts. Every penny counts!

Okay, enough preaching. Last step…what is this dropdown? This is where we can configure the location of our server. Wait…what? This deserves an explanation. When we say “server” in the Wild Wild Cloud West, what we really mean is a virtual server. As cool as it would be for a team of folks to board a golf cart and briskly install a rack mounted server into a cabinet every time we add a new server to our account…that’s not quite what’s happening here. Instead, we’re actually spinning up a “virtual” server which is like running a computer within a computer but only using software. Huh?

Think about how we start our servers locally. With Meteor, when we call meteor in our terminal (from within a Meteor project), our app is automatically booted on localhost:3000. That port, 3000 can be thought of as an “instance” or copy of our application. Locally, we only need one copy running at any given time because it’s just us using it. When it comes to deploying our app into production, though, we potentially need to have several instances or “copies” running because a single copy of our application can only handle so much traffic. So…how does that work?

Load balancers! Hooray! A load balancer is basically a routing mechanism that takes user requests from a given domain (e.g. http://app.com) and redirects each request to an instance of our application. Can you guess how that works? Ports! For each instance of our server we create, it’s assigned to a port number. The load balancer, then, is responsible for routing traffic to a given port (running copy of our application). This quite literally spreads traffic out over a number of servers, effectively balancing the load of requests hitting the application. How neat is that?!

Okay…that all makes sense but weren’t we talking about this dropdown and locations or something? Right. Long story short, this dropdown allows us to setup where our virtual machines are spawned. The Matrix aside, the names here actually have significance. Each of the names in this list represent a provider and a region where that provider offers servers. When we say provider, we mean the company or service that’s going to host our application.

Wait, I thought Modulus is going to host our application? In theory, yes. But, really what Modulus offers is more of a well-thought out, user friendly version of deploying our application to other services like Amazon EC2.

How Modulus Works

Remember how we mentioned Amazon EC2 as an alternative earlier in this post and suggested only using those types of services if you understand the more complicated parts? Modulus understands those parts and have created a service that removes the thinking for us when deploying to those services. Woof. It’s a bit Inception-y, but it means making stuff like hosting a cloud application a lot easier for your average developer (like us). Don’t feel silly. This is a great thing to have as a developer.

Okay! So after we push the magic “Create Project” button, we should have a shiny new Modulus server set up. Let’s take a peek at setting up a database on Modulus so we can complete the circle of services needed to deploy our application.

Setting up a database on Modulus

Setting up a database is pretty easy. First we need to hop over to the “Databases” tab in our dashboard. Once we’re there, we need to click the big ol' “Create Database” button in the top right. From there, we’ll get a little modal action like this:

Same rules as spinning up a server apply, albeit a little less complicated here. The label, username, and password behave how you’d expect. Keep the username and password top secret. If someone gets this, they get access to your database. For the region, this is an identical concept to creating our server. Pick the region that’s closest to you/where your users will primarily be. If you’re in New York, NY, for example, any of the “east” options will fit the bill. If you’re international and don’t see anything close to you, set this to the next closest thing (it should work just as well).

Once we’re up and running, we should be presented with some information about our database. Under that Mongo URI subheading we’ll find our connection string. This is the MongoDB friendly URL we can use to connect to our database. Let’s see how we can make use of this along with some other details when configuring our server.

Configuring a server

Okay, so, even though Modulus gets us down to the least possible amount of configuration necessary for spinning up a cloud-based server for our Meteor app (it’s really quite impressive), we do have to do a little bit of config. Don’t hate. It’s just as easy as everything else we’ve seen. A few form fields, a double check, and off to Mars we go.

Environment Variables

First up, we need to configure a handful of environment variables. Environment variables are like the normal variables you might use in your application, except that they’re specific to the server environment our application is in and are what the server uses to get our server ready for prime time when it boots. To set these—again, from our dashboard—we need to click on the project we set up earlier and then click on the “Administration” tab.

Once we’re here, we need to scroll down a ways until we see a table labeled “Environment Variables.” Here, we need to add a handful of settings. By default we’ll only have one setting, NODE_ENV which is assigned a value of production. We can leave this as-is, but based on the name and it’s value we can guess what this does. Remember when we talked about deploying to an environment earlier? This setting gives our server a way to identify as a specific environment.

This particular value, NODE_ENV is mostly helpful for accessing in your application code when you need to limit certain functionality to a given environment (e.g. I only want to post tweets from the application in the production environment). Make sense? Let’s look at the rest of our values and then get it all set up.

NODE_ENV

production

PORT

The default port number our application will run on. For Modulus, this will be 8080.

ROOT_URL

Our app’s URL: either our Modulus domain (found at the top of the project page) or our custom domain like http://bestappever.com.

MONGO_URL

The connection string we got from Modulus earlier, with our actual username and password replacing the <user> and <pass> placeholders after the mongodb:// part.

METEOR_SETTINGS

{ "private": {}, "public": {} }

Most of this should make sense. After our NODE_ENV setting, we pass a PORT number. This is the port number our application will need to run on in order for Modulus to properly route requests to it using its load balancer. We set this here so our application can reference it when it starts up.

Next, we have our ROOT_URL. This is something that’s specific to Meteor and used by the platform for generating absolute URLs in our application via the Meteor.absoluteUrl() method. Generally we won’t use this in our own application, but a lot of the core packages do make use of it, so we need to make sure it’s set; otherwise we’ll get an error when we try to boot our app.

This next one, MONGO_URL should make sense. Remember that connection string we got earlier after we set up our database? This is where it goes! The only thing to note is that we need to replace the <user> and <pass> placeholders at the beginning of the string with our actual username and password for the database.

Protect your connection strings

A connection string with a username and password in it is like pure gold for anyone that wants to get access to your database. When it comes to handling these values, make sure to store them in a secure place and only let the people who absolutely need access to them to see them. This is not a joke; if this gets out, you run the risk of exposing all of your users/customers data, so be careful.

Ok! Last up is METEOR_SETTINGS and this one is optional depending on how you’ve built your app. If you’ve used a settings.json file in your application, this value will need to be set equal to the contents of your settings.json file. This can be copy/pasted into the field, or, set via the Modulus CLI (we’ll learn how to automate this in a bit).

Once we click “Save” beneath the list of environment variables, we’ve got our app configured! This should be all we need to do in order to successfully deploy our application. Real quick, we should make a nod to SSL and get an understanding for how it’s set up on Modulus.

SSL

In order to keep our applications a little more secure, we can add SSL to our application so that any data moving between the browser and our server is kept private with encryption. When you load up an app and see the URL turn green (or display a lock) and change the protocol from http to https, this signifies that an application is using SSL and that your connection to that application is secure.

Depending on the type of application we’re running, we may need to add support for SSL. Any application that transmits any form of secure data for users (e.g. credit cards)—whether to a third-part service or otherwise—should use SSL. To “use” SSL, we need to acquire an SSL certificate from a provider. We won’t cover obtaining this here, but a quick search for SSL providers will turn up a lot of different options. My personal recommendation is Namecheap as their basic certificates are relatively inexpensive and the turnaround time for getting a certificate is pretty quick (a few minutes to a few hours).

For now, let’s focus on setting up an SSL certificate on Modulus. From the “Administration” tab of your project’s dashboard, locate the Custom SSL block.

When we click that red plus + symbol on the right, we’ll be presented with a modal for inputting our “Private Key” and our “Certificate.” The “Private Key” field is where you’ll place the RSA Private Key you receive when you generate a CSR. A CSR is what a certificate provider will require in order to generate your certificate. In that second field, “Certificate” we’ll paste in the SSL certificate we receive from our provider. Note: this isn’t a “file” like you might expect it to be. Instead, this is just plain text with some specific formatting that the browser can recognize as an SSL certificate. Here’s an example of what you might have:

Web Server Certificate

You might also have an “Intermediate CA” (some SSL providers will include this, some might not) which is similar to our Web Server Certificate:

Intermediate CA

Combined, these two form an SSL “chain” confirming the identity of your server, allowing connections to be served over SSL. Oof. Back on Modulus, if we just have a Web Server Certificate, we can paste this into our “Certificate” field. If we have both a Web Server Certificate and an Intermediate CA, we want to paste both into the “Certificate” field; the Web Server Certificate first followed by the Intermediate CA. Something like this:

In case you’re wondering, yes, you need to include the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- lines in both certificates. Paste these exactly as you receive them from your SSL provider.

Once we have this in place, we should be all set on Modulus for SSL.

The Force SSL Package

If we’re using SSL in our app, we can ensure that our users are connecting via SSL by adding the Force SSL package by MDG. Once installed, this will make sure that any connections to your application are served over SSL by default (e.g. if a user attempted to connect to http://app.com they would be automatically redirected to https://app.com).

Deploying to Modulus

Okay! Finally! We’ve got our app configured, so now it’s time to deploy. Back in our application directory in the terminal, all we have to run is:

Terminal

Nice, right? When we do this, we’ll be prompted by Modulus to select the server we’d like to deploy to. If we only have one, we’ll be given a simple prompt to enter yes like this:

Once we enter yes, Modulus will get to work. You may notice something interesting. As soon as we do this, Modulus will display a message like Meteor project detected... and then display some information about determining a Meteor version and building your Meteor application. What’s this?

Remember earlier when we mentioned that Modulus technically only hosts Node.js apps and not Meteor apps as-is? This is where we make the connection. Here, Modulus is using a tool they’ve built called Demeteorizer which converts our Meteor app into a vanilla Node.js app. Cool, eh? This functionality is built into the Modulus CLI by default, but we can install Demeteorizer on its own to convert our app for hosting on other PaaS providers, too!

After a few seconds, our app will be deployed! If everything worked as expected, we should be able to point our browser to the URL for our application (e.g. http://demo-femo-50073.onmodulus.net) and see our application up and running. Hell yeah!

Congratulations: you just deployed an application into production. Not as scary as you thought, huh? Granted, this is just one piece of going into production, but it’s a big one. From here, we can focus on improving the performance and security of our application trusting that all of that work has a place to live!

Before we part ways, we should chat about automating this process a bit.

Automating deployments

This is entirely optional but something that’s really smart to consider when putting an application into production. When it comes to running an application for users and customers, we need to keep in mind that things will change. Hopefully that just means that we’ll deploy new features or upgrade our app, but sometimes that can mean having to fix bugs and other problems that crop up in the day-to-day of running an application.

In light of this, it’s smart to have a well-tuned workflow that we can rely on when it comes to deploying our application. Even though something like Modulus makes all of this fairly simple, there’s still a small margin of error that crops up when we start to do things like host multiple servers on Modulus (e.g. staging vs. production) and making use of a settings.json file. Automating all of this means thinking about all of the steps involved and baking them into a simple, easy-to-remember process that performs all of the steps for us.

To do this, we’re going to rely on something we actually get from NPM: “scripts.” A tip picked up from Gerard Sychay over at Differential, we can use NPM scripts to automate our workflow a bit by creating short-hand commands that combine a longer string of shell commands. Confused? Let’s take a look.

package.json

To use NPM scripts, we have to create a file called package.json in the root of our application. Here, we add a few items to describe our application (not 100% necessary but nice to have) and then we add an object called "scripts". Inside, we store a handful of key/value pairs that represent commands we can call from the terminal when we’re inside of our project directory. Notice that each command corresponds to a longer string of commands. Here, we’ve set up a few things to help us account for using multiple settings files and making sure that we deploy to the correct environment, either staging or production.

Above, we only setup a single server so this may be a bit confusing. Recall back to the beginning of this recipe where we discussed having different environments. This is where something like this comes into play. Here, we’re creating commands that point to one of those environments. For example, let’s look at the value of our “production” script:

This one string is actually responsible for two things:

Taking the contents of our settings-production.json file and setting it equal to the METEOR_SETTINGS environment variable that we looked at earlier (notice, Modulus gives us a handy command for doing this from the command line) for the specified project name.

Calls to modulus deploy, passing the name of the project we want to deploy to.

See what this does? When we call our production script, we’ll automatically get our METEOR_SETTINGS value set to the current contents of the settings file we pass in \"$(cat settings-production.json)\" and then deploy our application. Not only does this save us a few keystrokes, but it protects us from doing things like using the wrong settings file or deploying to the wrong server. Further, this means that now we can call a single command to deploy our latest work into the specified environment. Okay! Sold! But how do we call it?

Terminal

When we call this, each of the commands in the string above will be called in order for us. Let’s take a look at how it looks in action.

So cool! Notice that this behaves just like us typing out each command ourselves. Again, the benefit being that we make sure the right commands get called in the right order each and every time.

Wrap Up & Summary

In this recipe we learned about taking a Meteor app into production using the Modulus PaaS. We learned about setting up a server on Modulus, setting up a database, and configuring our server to get our deployment up and running. We also learned how to deploy our project from the command line and automate the process of deployment using NPM scripts!

Show more