Deploy Maka-CLI Apps to AWS using Meteor, Nginx, PM2, and NVM.
Hey everyone, I have some pretty neat news! I’ve been working at integrating the AWS CLI into Maka-CLI, as well as working out an alternative to deploying Meteor Apps using MUP (Meteor-Up) to AWS.
Why did I make an alternative to MUP? Welllll, ok. SO I like MUP. I really do. Lately, however, I’ve been having some growing pains with MUP. Again, not that there is anything WRONG with MUP. I was just interested in taking out the Docker component (GASP!) of the MUP deployment scheme. I know, I know… Docker is the best thing since sliced bread… but I am a bit of purest and Docker (and it’s containers) add another layer of abstraction and maintenance that I don’t really need. I also had a very, very, terrible time deploying my Meteor app to a Raspberry PI using MUP… but that’s another story.
On to the Maka-CLI update! As of version 2.17.35, if you run “maka aws”, you’ll now get a helpful(ish) list of some of my more common AWS operations. It’s not an exhaustive list by any-means of what the aws-cli is capable of, but for a start it’s not too shabby.
$ maka aws
I’ve also updated the “maka deploy” command to deploy to, seemingly, any server you have access to. Another update is to the maka generators; I’ve add a “maka:config” option in order to setup new configuration environments. The configuration environments also have been reworked, specifically to include PM2, Nginx (SSL / Non-SSL), SSH, and the standards settings configuration files. So, blah blah, I’ve made a bunch of updates — lets get started and you can see them in action.
Prepare: AWS Tokens and AWS-CLI
Before we start on our project, you’ll need to install AWS-CLI and configure it with your AWS Token and Secret. It’s pretty straight forward, here’s some steps to help you out:
- Download the aws-cli python application:
pip install awscli
2. Obtain your secret token and key. Login into your AWS Console:
3. Configure your aws-cli:
4. From here, you are all setup to use aws-cli. I encourage you to learn how to use it directly, however, for this article I’ve proxied many commands that are needed in maka-cli to aws-cli.
First, setup a bare maka project. If you aren’t familiar, head on over to my intro articles and see what I’m talking about.
$ maka create aws-app
If you’re familiar with maka, you may notice that the configuration folder (config) no longer has three directories (development, staging, and production) but just the one development directory. The new generator now scaffolds out the config environments, and there is a new option to configure an environment with SSL; in case you need to make an environemnt with SSL in staging, for example. Now, “cd” into the “aws-app” directory.
Ok. So here you are. Sitting at the root of aws-app project. Now what? Well, you can modify the project however you like, for as long as you like, but what we’re trying to get done here is deploy it to an AWS EC2 instance.
Let us begin.
$ maka aws create-key-pair --env dev
(“dev” gets automagically mapped to “development”)
What this has just done, if your AWS is configured correctly, is create a key-pair that we’ll use in the new container in order to log into it via SSH.
Next, create a security group:
$ maka aws create-sg
No environment needed here. It’s a firewall rule for EC2 instances, and can be used for any environment you like. You’ll need to specify a Virtual Private Cloud (VPC) to assign the security group to. You probably only have one option.
Now, go ahead and create the instance:
$ maka aws create-instance --env dev
The first prompt is to choose a key-pair for the instance… use the one we just created:
Next, it’ll ask for a VPC to place the instance in. Again, you likely only have one, but just choose the one that you configured for your security group:
Up next, is the security group selection. Yup, you guessed it. Use the one we created:
The next option has to query a very large list of amazon machine images (AMIs), so it may take a moment to load. It’s filtered out to only (current) images that are compatible with the deployment process of maka-cli. I plan on adding more to this list. It’s sorted by date, so the first one is the most recent.
Next, we need to assign a subnet. Unless you have a burning desire to place this sample application somewhere special, just choose the first subnet:
Now, this will seem strange, but it’s a required question for AWS-CLI. You need to set the min and max instances to use. I recommend leaving it as the default. The format is min:max, and it’s set to 1:1. That is, we only want to create 1 instance.
Next, decide the instance type. By default, it’ll choose a very small container. But heck, if you want to throw down with a C-type instance for this bad ass test project, be my guest.
Finally, review what you’re about to create. If you’re good for taking a hit on some pennies (for the life of this example) then say “y” and proceede.
I cannot stress this enough… you are now paying MONEY to amazon. Not a lot, but you are. So lets continue. Don’t worry, we’ll tear it down when we get to the end.
Now that the instance is running, we need to set our SSH config file (ssh.json) to use the new public IP address of the instance.
$ maka aws set-host --env dev
This command will show you the currently running instances, and ask you to make a choice. Don’t mess up. J/k. It’s ok if you mess up. But don’t.
Choose the instance we just created in my case, it’s ID 1 (aws-app-development). Then choose the public IP options (default). The reason you are asked, is because each EC2 instance (when deployed with a public IP) has both a public and private IP.
Now, you should have everything ready to deploy your project to the EC2 instance.
$ maka deploy --env dev --mongo
The “mongo” option is to configure a local mongo server. Omit this if you have another mongo server you’d like to use.
You’ll be prompted with a usual SSH warning to confirm that you are indeed trying to access a remote server. Next, a deploy.sh script is created for you and it’s important that you review it. Reason is, it’s up to YOU (yes, you) to ensure the security of your deployment. The deploy.sh script will run several commands as sudo, and if you’re not happy with all of them… you need to fix it.
Up next, if you don’t have an app.tar.gz bundle already created, maka-cli will create one to deploy. Once it’s finished, it’ll upload it along with several configuration scripts that can be found in the configuration environment (development).
Now, the deploy.sh script will run and install PM2, Nginx, and NVM. NVM is a Node Virtual Manager and it’s able to set the node version programatically. Maka-cli will pass into the develop.sh script the current Meteor Node version, ensuring that it’s compatible. Nginx is the reverse proxy, and will serve up the NodeJS (meteor built) application over port 80 (http), and PM2 will manage the NodeJS app and ensure it starts up after a reboot…among other things.
For real?! Yup. Head on over the IP address that finalized the deployment and you’ll see that the app is happily running. You’ll also see that there is nothing impressive on this EC2 instance worth keeping around. So, instead of paying hard earned pennies for it. Lets terminate it.
$ maka aws terminate-instance
Again, you’ll be prompted with a list of instances that have been deployed by Maka-CLI that you control. Now, don’t get jumpy here… you’re actually about to destroy an EC2 instance. Make sure it’s not one you really need!
And that is that. Your short lived, EC2 instance is no more.
So, there you are. You have created a full fledged web application running on NodeJS, with a React front-end, and deployed it to a cloud-based environment using Maka-CLI and AWS-CLI. This instance, has a full mongo server, process manager and application load balancer (PM2), and reverse proxy (Nginx) running which takes FAR less resources (and has working network interfaces) and a lot less storage space requirements than a configuration with Docker.
You can manage your next instance (or this one, if you haven’t yet terminated it) with the integrated SSH command:
$ maka ssh --env dev
If you have any questions, or comments, or… whatever, feel free to message me on Gitter.im. (@maka-io)