Hosting on AWS with Bitnami
Summary: This is going to help you get the MeanSeed application deployed to a Bitnami MEAN stack on AWS. It assumes that you have an AWS account and have worked through setting up a Key Pair.
References:
- https://scotch.io/tutorials/deploying-a-mean-app-to-amazon-ec2-part-1
- https://gorails.com/setup/ubuntu/14.04
Steps:
- Create a Bitnami MEAN EC2
- Get settings from AWS
- Log in to your instance
- Install Compass and Global Node packages
- Open ports
- Clone the MeanSeed and get the directory ready
- Test the code in a browser
- Set up your database to be accessible
- Start the server
Create Bitnami MEAN EC2
Go to the AWS Marketplace here: https://aws.amazon.com/marketplace
Search for MEAN powered by Bitnami > Select MEAN powered by Bitnami > For Region = same as your EC2 instance [can be tricky. Us-west-2c = US West (Oregon)] > Continue > EC2 Instance Type = t2.micro [for free tier], VPC Settings = VPC that allows public DNS, Key Pair = {your key pair} > Launch with 1-click.
You should see information like this:
Get Settings from AWS
To login, go to AWS EC2 Management Console: https://console.aws.amazon.com/ec2/ Instances > Select the Instance you just made [See note below about Status Checks] > Copy information about this instance:
Info | Sample | How to find |
---|---|---|
Public DNS | ec2-35-163-153-53.us-west-2.compute.amazonaws.com | On Instances grid, select your instance, click on Description tab and look for it on the right |
Key pair name | first | On Instances grid, select your instance, click on Description tab and look for it on the right |
Root password | IfLcYAtkSeu7 | right-click on the row of your EC2 instance and navigate to Instance Settings -> Get System Log Scroll through the System Log to the very end. You should see a bright box with the words: Setting Bitnami application password to followed by a password. |
Warning: You will only have one chance to get the Root password.
Note: If you don't have a public DNS, you may have to try again with different settings on your VPC. Check to see what the VPC ID is for your instance. This will be in the description of the EC2, the same place as the Public DNS. Then, look for VPC Services > Your VPC > select the VPC ID > Actions > Edit DNS Hostnames > DNS hostnames = YES > Save. You also have to set the subnet to allow auto-assignment of public ip. Subnets (underneath Your VPCs) > Select Subnet that corresponds to the VPC and right-click > Modify auto-assign IP settings > Enable auto-assign public IPv4 address > Save. Try making the EC2 again.
Status Checks: On the Instance grid, there is a Status Checks column. While your instance is initializing this status column looks like this:
When it has finished, it looks like this:
Log into your instance
For a Windows machine, you need to use PuTTY.
On a Mac, you can go to where you have the Key pair *.pem file saved and type this:
ssh -i {key pair name}.pem bitnami@{Public DNS}
The first time you try it, you may need to answer 'yes' to this question:
Are you sure you want to continue connecting (yes/no)?
You should get something that looks like this:
Install Compass and Global Node packages
The Bitnami profile already has many of the things we need installed, but there is still work to be done. The basic idea is that you need to install Compass, Bower, Grunt, and some Node Packages. This is what worked for me:
Install Compass
You need Ruby and Gem to install compass, so here goes:
sudo apt-get update
sudo apt-get install git-core curl zlib1g-dev build-essential libssl-dev libreadline-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt1-dev libcurl4-openssl-dev python-software-properties libffi-dev
git clone https://github.com/rbenv/rbenv.git ~/.rbenv
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
exec $SHELL
git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
echo 'export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"' >> ~/.bashrc
exec $SHELL
rbenv install 2.3.1
rbenv global 2.3.1
ruby -v
gem install sass
And finally:
gem install compass
Install Global Node Packages
sudo npm install -g bower
sudo npm install -g grunt-cli
sudo npm install -g nodemon
sudo npm install -g forever
Note: I got the following warning, but I didn't do anything about it, and haven't seen any problems:
npm WARN optional Skipping failed optional dependency /nodemon/chokidar/fsevents:
npm WARN notsup Not compatible with your operating system or architecture: [email protected]
Clone the MeanSeed and get the directory ready
In the root directory of you EC2 instance (in a terminal), you should have these directories:
apps htdocs stack
The apps directory can be write protected, so I "clobbered" it into submission from the home directory:
sudo chmod 777 apps/
Next, clone the MeanSeed code. Inside the apps directory:
git clone https://github.com/amnotafraid/MeanSeed.git
Note: If you want to copy a file, filename, from OSX, you can use SCP like so:
$scp -i ~/Desktop/{key pair name}.pem {filename} bitnami@{Public DNS}:{directory}
In the apps/MeanSeed/client directory:
npm install
bower install jquery
grunt --force
In the apps/MeanSeed/Server directory:
npm install
Test the code in a browser
Note: To get this to work you need to open up port 3000. See Open up ports below.
By this point, you should be able to get the code running and look at it in a browser.
From the server directory, execute this command:
npm start
Open up a browser and point it to:
http://{Public DNS}:3000/#/
If it looks something like this, you have been successful:
Set up your database to be accessible
If you get to this point, the mongo database is not accessible. You need to open up the ports and change the Mongo configuration.
Open up ports
Note: I haven't had time to update the documentation, but it's not necessary to open up Mongo to the outside world, because in the MEAN stack application that I built, only the backend reads and writes to the Mongo database. So, the bind-ip
does not need to change. I think the directions in this entire subheading are unnecessary. And opening up the Mongo db to the internet is not security best practices.
In the AWS EC2 Management Console: https://console.aws.amazon.com/ec2/
Click on 'instances' in the left hand bar, then select the instance you are working with. In the bottom, make sure the tab 'Description' is selected. Search for 'Security groups', and then click on the link there. In the Security group, choose the Inbound tab below, click Edit. You need to add a Custom TCP Rule on Port 27107 and open it to any IP address: 0.0.0.0/0 or just select 'Anywhere' from the dropdown. This is for Mongo. Also, add a Custom TCP Rule on Port 3000 for the MeanSeed application.
Once you have added these rules, refresh the security group using the menu button on the top right.
Database User access
Create a Mongo User with admin privileges
To get to the Mongo database, type this from the command line:
sudo mongo admin --username root --password {Root password}
Think of an admin user name, {username} and password, {password}. Inside the Mongo cli, enter these commands:
show dbs;
use admin;
db.createUser(
{
user: "{username}",
pwd: "{password}",
roles: [ "root" ]
}
)
Exit the Mongo cli: <ctrl>c
Try it out by typing this in the terminal:
sudo mongo admin --username "{username}" --password "{password}"
Test the privileges by creating a database for MeanSeed and inserting a user:
show dbs;
use MeanSeed;
db.users.insert({item:"test})
Test to see if you can see it:
db.users.find().pretty()
It will look like this:
{ "_id" : ObjectId("58267c0bd5fa7a86bb9ec6a1"), "item" : "test" }
Open Mongo port
Note: I haven't had time to update the documentation, but it's not necessary to open up Mongo to the outside world, because in the MEAN stack application that I built, only the backend reads and writes to the Mongo database. So, the TCPIP rule on 27017 is not needed.
The mongo database needs to be open to all IP addresses. On your EC2 instance, edit ~/stack/mongodb/mongodb.conf:
sudo vim ~/stack/mongodb/mongodb.conf
bind_ip should be changed from 127.0.0.1 to 0.0.0.0
noauth should be true:
noauth = true
#auth = true
From ~/stack, restart mongo:
sudo bash ctlscript.sh restart mongodb
Try to access the mongodb from the command line in a local terminal:
mongo {Public DNS}/MeanSeed -u {username} -p {password}
Sometimes it can take a while for the changes to propagate, so if you get "[thread1] Error: Authentication failed" try waiting awhile to see if the situation improves. Or, try using this syntax:
mongo MeanSeed --host {Public DNS} -u {username} -p {password}
Login to mongo and change the authorization schema and create a user:
From the EC2 terminal:
sudo mongo admin -u {username} -p {password}
From the mongo cli, execute these commands:
use admin;
var schema = db.system.version.findOne({"_id": "authSchema"});
schema.currentVersion = 3;
db.system.version.save(schema)
Think of another username and password:
username: dbUser password: dbPassword
Create an admin user for the MeanSeed database with a different username {dbUser}, and password {dbPassword}:
show dbs;
use MeanSeed;
db.createUser({
user: "{dbUser}",
pwd: "{dbPassword}",
roles: [
{
"role": "readWrite",
"db": "MeanSeed"
}
]
})
Change the noauth back to auth:
sudo vim ~/stack/mongodb/mongodb.conf
#noauth = true
auth = true
From ~/stack, restart mongo:
sudo bash ctlscript.sh restart mongodb
Check that you can login from a local terminal with your new password:
mongo {Public DNS}/MeanSeed -u {dbUser} -p {dbPassword}
Edit ~/apps/MeanSeed/server/database/index.js so that it accesses the database with the user you set up:
Change from this:
var productionDb = 'mongodb://localhost/test';
to this:
var productionDb = 'mongodb://{dbUser}:{dbPassword}@{Public DNS}/MeanSeed;
Start the Server
In the ~/apps/MeanSeed/server directory:
NODE_ENV=production forever -o out.log start ./bin/www
tail -f out.log
You should see you application in a web browser and be able to sign up a user:
http://{Public DNS}:3000/#/