Deploying your MEAN project
Buy your domain name and Sign up for Digital Ocean
Buy your domain name. namecheap.com or hover.com have been our favorites. Namecheap is typically cheaper, Hover has better customer support.
Pick a domain name that is your name. If you need to, throw in a middle initial or name, but make sure it is something professional. For greater variety, you don't have to use .com either. For me, ericnatejones.tech would be a good option.
Digital Ocean
Get a friend to send you a sign up link for some discounted prices on Digital Ocean. Or don't. Either way. Get an account.
Deployment Guide
This guide will lead you through how to:
- Create a VPS (droplet)
- Forward requests to digital ocean
- Set up name records on digital ocean
- Install all dependencies on our droplet(git, nginx, mongodb, node, pm2)
- Set up SSH
- Clone project
- Create server block
- Run server
It is important to take your time, comb through this step by step, and double check every step in this tutorial.
Navigate to the Droplets tab. Click "Create Droplet."
Click, "One-click apps." Click NodeJS 6.10.2 on 16.04. That's node version 6.10.2 and ubuntu version 16.04
Choose the smallest size.
Choose a data center in the US.
Get at or create your ssh key.
ssh is short for secure key. It's kind of like a password that your computer will remember for you. It's something you can give to a server or to other services like git hub, where they can check to see if you're ok to be doing the stuff you're trying today.
Scroll down to the "Add your SSH keys" area. Open your terminal. From any directory type cat ~/.ssh/id_rsa.pub
. Make sure to tab complete this path.
If you don't have an ssh-key, type ssh-keygen
and just hit enter (to select the defaults) until you get the key's randomart image. And then type cat ~/.ssh/id_rsa.pub
Copy everything that outputting starting with ssh-rsa
and ending with the name of you computer.
In digital ocean, click "New SSH key" and paste the key you just copied.
In the name slot, put what your computer is called. I would name it "Eric's 2013 MacBook Pro" for mine. Yours would obviously be different.
In the "Choose a hostname" box, but something that would be easy to recognize as this droplet. Your domain name would be a good one.
Click create.
SSH into droplet
It should give you an IP address and a. Copy the IP address. Go back to your terminal and type ssh root@[your IP address]
. Mine would be ssh root@107.170.88.206.
This will log you into the server that your droplet is on. You will be controlling a terminal that's based in California or New York or somewhere else super cool!
Press enter and hopefully you will get the following message:
The authenticity of host '107.170.88.73 (107.170.88.73)' can't be established.ECDSA key fingerprint is SHA256:hYFdiDrQgIWhUYEy++5/jnF2zjNPsRrK06ms3679PKc. Are you sure you want to continue connecting (yes/no)?
Type out yes
and hit enter. It should output some more stuff and you'll be in!
Install everything else on droplet
Install Nginx Digital Ocean
apt-get install nginx
In a linux environment, there's a package installer called apt-get. It's kind of like homebrew, but for Linux.
It will "Do you want to continue," type "y."
Install Mongo
Run a few commands:
apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv EA312927
echo "deb http://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/3.2 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.2.list
apt-get update
apt-get install -y mongodb-org
nano /etc/systemd/system/mongodb.service
This will open your editor. Enter in the following:
[Unit]
Description=High-performance, schema-free document-oriented database
After=network.target
[Service]
User=mongodb
ExecStart=/usr/bin/mongod --quiet --config /etc/mongod.conf
[Install]
WantedBy=multi-user.target
Save and quit. crt o
and then enter
and then ctrl x
will save and quit in nano.
Do a systemctl start mongodb
.
This will just go to the next line without outputting anything. It actually started Mongo for you in the background.
For a sanity check, you can do a systemctl status mongodb
.
Do a systemctl enable mongodb
. This will ensure that if we ever restart our droplet, it will restart mongo.
Git came for free! Go ahead and check with git --version
. It will tell you a version.
Major aside
FOR YOUR INFORMATION. When you have a brower, and someone types in the url name (google.com or bob.com whatever) The browser actually needs an IP address. The browser goes out to a registrar list to check who registered bob.com. If namecheap.com did, namecheap.com is then asked what IP address the browser needs to hit up for bob.com. Namecheap might be pointing to Digital Ocean, and in that case, that query for the IP address is forwarded to Digital Ocean.
DNS
Go to your domain name provider and click manage DNS or Manage on your domain dame. You should see things like A name, and C name. You are looking for something like "Custom name servers, or Custom DNS" Select that one.
For namecheap, you:
-sign into namecheap.com,
-go to dashboard,
-click "manage" on the domain you're working on,
-click "Domain" tab,
-in the name server section change the dropdown from basic DNS to Custom DNS
In the nameserver boxes put
ns1.digitalocean.com
ns2.digitalocean.com
click "add namesever" and add a third.
ns3.digitalocean.com
This says, "You're not going to find the IP address here, go to digitalocean."
After you add these, check the checkmark to save.
Switch over to digital ocean.
In digital ocean, there is a "networking" tab at the top. Click on it.
The domain name needs to match the domain name as you purchased it.
Put the "@" symbol in the HOSTNAME box. Without the quotes. And nothing else.
In the second box. The WILL DIRECT TO box. Dropdown to yours.
The third box should default to what it should be. 3600 or something.
Click "Create record".
To check everything is working, Go to whatsmydns.net
and search your domain name. You should see at least a couple green checkmarks. This may take some time, which is a bummer. People 95% of the time see at least a few green checkmarks within minutes.
Getting your app out there
Go into your terminal. Make sure you are SSH'ed in. Enter these commands:
cd /var/www/
ssh-keygen
(Hit enter to accept the default file name, then enter 2 more times to enter no passphrase for the SSH key. Once that completes you should see a "random art" image before doing step 3)cat ~/.ssh/id_rsa.pub
Copy that key for later.
Deploying static site
We will start small and just deploy a static site. From end stuff only. But, if you're deploying a full stack site, you'll follow many of these steps.
Go to github and login. Go to settings. On the left, go to SSH and GPG keys.
The title will be something to remind you what the SSH key is for. Something like "bob.com digital ocean droplet"
Paste your key in the "Key" box.
Save that SHH Key.
Go to your repository. Click, clone or download. Make sure ssh is selected by clicking "use ssh". Copy that address.
Go back to your server terminal. Make sure you're in /var/www.
Do a git clone [paste the address here]
One could look like git clone git@github.com:bob/portfolio.git
It will complain about the authenticity, type yes to signify that you're ok.
You should then get some text that indicates everything is running smoothly.
Once you do this, your projects repository will be on that server and you can do git pull
s in the future to update your website.
You're still in /var/www
.
Aside
Nginx is a server environment, a bit like express.
We are just going to use it as a reverse Proxy
When there is an incoming request, we are setting up Nginx to be able to take that incoming request to that IP address (the one that digital ocean is pointing to. Remember?) and Nginx will tell your browser where to find index.html or whatever.
We will need to write some config files for it.
Config files
To get to those config files, enter:
cd /etc/nginx/sites-available
We are going to create some server configuration blocks. Saying, "When you're at this url, go to this file."
By default, it points to a helpful html page. Go to your domain. No www or anything. Just your domain. You should see "Welcome to Nginx."
The file itself also has some helpful notes.
root /var/www/html
say "the root of our website is found here." It looks for an index.html there.
If you were to go that folder and cat index.html
, you would see our cool "Welcome to Nginx" stuff in HTML!
In that sites-available folder (/etc/nginx/sites-available), we will create a new config file.
nano portfolio
We should now be in nano and be able to write in this file. Start with:
If you see square brackets, [], do not include them. They just mean that yours will be unique.
server {
listen 80;
server_name [domain name that you purchased];
root /var/www/[path to the folder where index.html lives]
index index.html;
}
so, Bobs looks like this:
server {
listen 80;
server_name bobziroll.com;
root /var/www/portfolio;
index index.html;
}
Save and quit. control o
and then enter
and then control x
will save and quit in nano.
Sim link
We need to link this file to sites-enabled
The pattern for this is:
ln -s [what file to link] [where to link it to]
We are linking the sites-available file to a sites enabled file
Bobs looks like this:
ln -s /etc/nginx/sites-available/portfolio /etc/nginx/sites-enabled
Hit enter. There will be no output.
Do a nginx -t
You should see that the test is successful.
Do a service nginx reload
There will be no output.
CHECK OUT YOUR SITE!!!
You should see it.
Create new record for WWW in Digital Ocean
Many people still like to type www. before domain names, so we'll write some code to help redirect them from www.bob.com
to bob.com
In the networking tab in digital ocean, type www
into the HOSTNAME box, select your droplet in the "WILL DIRECT TO" box and click create.
Go to your servers terminal. cd /etc/nginx/sites-available
if you're not there already.
nano portfolio
Add another server block.
server {
listen 80;
server_name www.[your domain name];
return 301 http://[your domain name];
}
control o, enter, control x to save and quit that file.
Enter service nginx reload
See if the www.
version of your site redirects.
Deploy full stack app
Make sure your .gitignore is good.
.DS_Store
.idea/
*.orig
node_modules/
bower_components/
config.js
Let's also clean stuff up for if we've accidentally save this stuff.
Merge your branches and make sure you're on master branch.
git rm -r --cached
this command will untracked all your files.
We will now track them again, excepet the ones that are in your .gitignore
do a git add -A
git commit -m "cleaning up"
git push
Make sure that you have all your packages in package.json. In the dependency block. If you don't, install and --save them and then do another add, commit, and push.
Go to git hub, find your repo, click "clone or download", take the SSH link and copy it.
Go to your server terminal, cd /var/www
, and git clone what you just copied. Like before.
git clone git@github.com:blahblahblah/whatever.com
cool
We will now be working with pm2.
Nodemon runs our server, but takes the terminal window. Pm2 will run it in the background.
npm install -g pm2
cd into your project.
This folder should have server.js
or some server file and a package.json.
Do the following commands one at a time and in order and don't ask questions:
-
fallocate -l 1G /swapfile
-
chmod 600 /swapfile
-
mkswap /swapfile
-
swapon /swapfile
-
cp /etc/fstab /etc/fstab.bak
-
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
-
sysctl vm.swappiness=10
-
nano /etc/sysctl.conf
^^ This will open nano. Once inside, add this to the very bottom: -
vm.swappiness=10
now save and exit (control o, enter, control x) -
sysctl vm.vfs_cache_pressure=50
-
Back into nano:
nano /etc/sysctl.conf
-
At very bottom, add:
vm.vfs_cache_pressure=50
-
Save and exit nano (I'm not going to tell you how anymore)
Breath for a minute.
The next for commands will need to be entered one at a time. You might need to tell npm "y" for yes after some of these. It needs to be lower case.
sudo npm install node-gyp -g
sudo apt-get install python
sudo apt-get install make
sudo apt-get install g++
Do an npm install
. This will install all the dependencies that are in your package.json file.
In your server file, you've told your server to run on a specific port. If you need to see that, you can run cat server.js
cd into cd var/www/[your project]
create a config file (because you .gitignored it)
nano config.js
Write the file the same as in your project.
Then do a:
pm2 start server.js
and witness some rad art.
Hopefully your uptime is more that 0 or 1 seconds.
You can also do a pm2 list
to check.
pm2 logs
will log errors.
Check that all your packages are there, and none that you don't have. You may need to install or uninstall stuff depending.
Alright, now back to sites-available.
cd /etc/nginx/sites-available
Create a new file and name it what your project is.
nano [file name]
Put this guy in there:
server {
listen 80;
server_name [YOUR.URL.HERE];
location / {
proxy_pass http://localhost:[YOURPORTHERE];
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
}
}
If this a calendar app, YOUR.URL.HERE should be calendar.bob.com.
Save and quit nano.
Create a sim link. Tab complete everything.
ln -s /etc/nginx/sites-available/[file-naem] /etc/ngins/sites-enabled/
Make sure it's in sites-enabled.
Reload Nginx.
service nginx reload
Go to Digital Ocean, the network tab, and do that stuff.
Everything should work.