This tutorial will cover launching an EC2 instance, setting up the Node.js/MongoDB stack, and keeping your app running as a service so that it is resilient to failure. Most everything is taken directly from the official documentation for the various packages, and I included links. That way you can refer to the tutorial as a general guide, and still use official documentation to get into the nitty-gritty details.
Right, then. Let's get started!
First, a Note About Keypairs
When you launch a new instance, it's pretty funky that Amazon doesn't let you paste or upload your public key to use for authentication. You can either generate a new private key to download, or select an existing key from your account. I recommend that you upload your public key beforehand, by going to the AWS Console -> EC2 -> Key Pairs -> Import Key Pair.
If you do this beforehand, your key will show up in the web interface for you to select when launching. Otherwise, AWS will generate the private key for you to download.
Provision your EC2 instance
I chose Ubuntu Server 13.10 for my AMI. You'll want to use 64-bit for optimal MongoDB support (see this post). Make sure to read through all the options in the wizard to configure your instance for your needs. MongoDB recommends an instance type that is EBS-optimized. More on that shortly.
If you use an automatically assigned IP address, you'll lose it when your instance is stopped or terminated. So, to prevent any DNS-related interruption of service, you'll want to reserve a dedicated IP address, which Amazon refers to as an Elastic IP (EIP). You can't assign an EIP until you've already launched your EC2, so we'll revisit that later. For right now, automatically assign a public IP.
The AWS storage documentation recommends using EBS for persistent data that you care about–like your database. From the documentation:
An Amazon EBS volume behaves like a raw, unformatted, external block device that you can attach to a single instance. They persist independently from the running life of an Amazon EC2 instance. After an EBS volume is attached to an instance, you can use it like any other physical hard drive. As illustrated in the previous figure, you can attach multiple volumes to an instance. You can also detach an EBS volume from one instance and attach it to another instance.
This comes in handy if you need to upgrade your EC2 instance, or provision a new one for any reason. Again, MongoDB recommends an EBS-optimized EC2 instance with a Provisioned IOPS EBS volume. So set up an EBS volume, and we'll be mounting it for MongoDB to use. It would make good sense to utilize Amazon S3 for static assets, but that's outside the scope of this article.
Configure Security Group
You'll want to have SSH (port 22) open to any IP you might access it from. You'll also want HTTP and HTTPS ports accessible from any IP.
You didn't upload your SSH key beforehand, did you? That's okay, I didn't figure that out until afterwards, either. So I generated a key, and copied my normal SSH key into the
authorized_keys file afterwards. Assuming you've placed the key in your
1 2 3 4 5 6 7 8
Now you can setup ssh agent forwarding for handy stuff like connecting to Github!
Onwards: Install and Configure MongoDB
Again, this is all based on MongoDB's official documentation. They recommend using separate EBS stores for your data, journal, and log, but I'm just going to cover putting it all on a single EBS to keep things a little simpler.
First, let's install MongoDB. These commands are directly from their tutorial:
1 2 3 4 5 6 7 8
Now that that's done, let's configure it to use the EBS volume we setup earlier. The AWS console will say your volume is something like /dev/sdb, but the actual device name in Ubuntu will be something like /dev/xvdb.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
Now configure MongoDB to use these paths:
sudo nano /etc/mongodb.conf
See the official wiki for more information about installing Node.js on Ubuntu. Ubuntu's default Node package lags behind the latest stable release. If that's okay, then go ahead:
1 2 3 4
But if you want to install the latest version of Node, you're gonna have to do this:
1 2 3 4 5 6
Listening on port 80 requires root privileges. Instead, Node will listen on port 3000, and we'll redirect requests from port 80 to there:
Add the command (minus
sudo) to your rc.local file to make sure this applies on boot as well:
sudo nano /etc/rc.local
Keep your app running forever
For this, we're going to use Forever and Upstart. Forever is used in production at Nodejitsu, and restarts your app if it crashes. Upstart registers your app as a service, starting it on boot and cleanly stopping it on shutdown. The configuration that follows is directly from this awesome guide on exratione.com.
First, install Forever:
Then, create the following Upstart configuration:
sudo nano /etc/init/myapp.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
Now you can start, restart, and stop your app like this:
1 2 3
Now your environment is ready to rock'n'roll—you just need to figure out a deployment methodology. Perhaps I'll cover an automated build/deployment process for a MEAN stack app next?
Post a comment if you have any questions, and I'll be happy to do what I can to help.