Deploying A Heroku App Steps - estermer/ericstermer.com GitHub Wiki
title: Deploying a node Application type: lesson duration: "1:30" creator: name: Colin Hart, adapted from Gerry Mathe competencies: Deployment
After this lesson, students will be able to:
- Explain Heroku as a service and why it's useful
- Deploy a Node.js app
- Push and pull from MongoDB using a live web interface
When we have finished developing a version of our app, we might want to put it on the internet for other people to see.
Most of what we've developed so far has just run on our own computers. Both our database and our web server have been on our computer. We've done this because it's much easier to develop locally because we don't actually need an internet connection. However, people can't access it easily unless they are also on our local network.
So what are your options?
1. Buy another Computer
We could just buy another computer somewhere else and use it to run our applications - or even more than one, if needed, and by the way, a server is a computer. We could connect this other computer to the internet and with a bit of configuration, we could allow people to connect to it using a URL.
However, we'd have to buy and look after this computer, have somewhere to store it and ensure that it was working and always connected to the internet. Also, if someone hit an error when they used our app, we might have to stop and start it? Maybe there is a better way?
2. Virtual machines
What if we could write a program that pretends to be a computer? If we could do this, then we could run another operating system within it? This is called a virtual machine.
3. Cloud hosting platform
Heroku is a cloud-based service. Essentially it's virtual machines that run on Amazon Web Services (EC2) and hosts your application code in the cloud. By using the git, you can deploy your code directly to Heroku's - they call them "dynos" - and seconds later your changes will be live in production.
By the way: All of Heroku lives on Amazon's Web Services
To deploy an app to Heroku, it's a fairly straightforward step-by-step process.
First you need to link your machine to your Heroku account - a similar process to what we did with GitHub.
##Codealong - Setting up Heroku and our machines (10 mins)
Go to heroku.com and make a free account. Make sure to remember your password!
Very similar to when we setup GitHub, we need to add our ssh-keys to Heroku so that Heroku can know we're authenticated users.
So let's add our ssh-key to Heroku. First, we need to copy our ssh-key:
cat ~/.ssh/id_rsa.pub | pbcopy
Then we need to go to Heroku.
Email > Manage Account > SSH Keys.
Next we need to install the Heroku Toolbelt.
This is a command-line tool that allows us to use commands in the terminal, similar to the way that we use git.
Once it is installed, you need to login with your heroku credentials:
brew install heroku
$ heroku login
Enter your Heroku credentials.
Email: [email protected]
Password (typing will be hidden):
Authentication successful.
We've learned how to use Node.js and mongoDB, but again, a web app hosted on your laptop is not really useful. Today, you'll deploy your Unit 2 Project to a server online so that everyone can access it on the web. There are a few configurations we must make to our application to ensure we can successfully push to production.
First, we'll need a functioning git repository with our application that includes a package.json file - remember, this is used by Node’s dependency manager. The package.json file determines the version of Node.js used to run your application and includes any dependencies your application needs to run. Upon deployment, Heroku reads this file and installs the correct versions and appropriate dependencies using the npm install
command.
Make sure you have a .gitignore
file with node_modules listed.
To verify that the Heroku CLI tool belt is properly working , type:
heroku auth:whoami
This should display the email corresponding to the logged in account.
Make sure you are in your Project repository!
Heroku requires that we have initialized our app as a git repo, luckily you've all done this already and have been committing and pushing to GitHub.
A Procfile
is a text file you create in the root directory of your application to explicitly tell Heroku what commands should be run. For our the purpose of this lesson we only care about one command:
web: node server.js
(or whatever name you used for your server file)
This command says that this process type will be attached to the HTTP routing stack of Heroku and take web requests when the application goes live. It is important to note that, by default, Heroku looks to your package.json for your start command, but because we may not have declared a start script, or the start script is specific to non-production needs, it is always best practice to define it within your Procfile.
run $node --version
Add engines with the version number under dependencies:
"engines": {
"node": "<version number>"
}
You can either let heroku create a random generated name or you can try to find a combination that isn't taken.
heroku create <name of app>
Here we use the heroku
command to create and name the app we wish to host.
Also, let's set the environment of our Heroku app to production:
heroku config:set NODE_ENV=production --app <your heroku app name>
First, we must integrate the Heroku add-on, mongolab, into our app. An add-on provides our production app with extra functionality, and in this case, a production Mongo database.
heroku addons:create mongolab
Now that we have a production database, we must find its connection URI that has been automatically stored to our app's config variables by mongolab:
heroku config | grep MONGODB_URI
A production URI will be returned and we export it for use:
heroku config:set MONGODB_URI=<production URI returned>
If you take a look in app.js
, you should see the code that creates the connection to mongoDB:
mongoose.connect('mongodb://localhost/<your-db>');
The URL 'mongodb://localhost/<your-db>'
is obviously only valid when we are running the app locally, but for Heroku, we need to use the connection URI for our production database we just generated.
To access environment variables in a node app, we can use process.env
.
var mongoURI = process.env.MONGODB_URI || 'mongodb://localhost/<your-db>';
mongoose.connect(mongoUri);
Now our conditional statement above simply instructs the application to use MONGOLAB_URI in production if it exists, and if not, use our local database URI.
We'll have to apply the same logic we wrote for the db connection to the the port where the app is running. This port will be automatically assigned by Heroku and stored under the key PORT
in the environment variables. Around the line 22 in our app.js
file, you can see the port where the app is open:
app.listen(3000)
Replace this code with:
app.listen(process.env.PORT || 3000 )
git add
and git commit
all the changes and then deploy them by typing
git push heroku master
Note that we are deploying to Heroku's remote, and not our typical remote origin. Heroku and GitHub are two totally different clouds that must be given commands explicitly. A push to GitHub will not automatically push to Heroku.
Now run the one-time command heroku ps:scale web=1
to start up your app's dynos, essentially starting up your app's process!
Once the deployment is done, open Google Chrome and go to http://YOURHEROKUAPP.herokuapp.com/
and you should see the index page online! Remember, you can always type in heroku open
to launch the application from the command line.
Note: Demonstrate the following using the app we deployed previously.
There are a couple of tools we can use in production for troubleshooting and error handling:
heroku restart
will let us restart our server and make sure all of our configuration details are up-to-date. You'd be surprised how much can be fixed by simply restarting the server; it's a big reason Heroku restarts every one of its applications daily!
Again, for efficiency, heroku open
will open up your app in the browser.
If there are errors, you can use the command heroku logs
to get a print out of the production/server logs for your application. These are just like the logs we had printing to our console in development mode. With this, you'll be able to search for what caused your application to crash and debug. Remember any changes you make to your application locally will require you to add, commit, and push to Heroku again. You do not need to repeat the database configuration.
Choose any other Express code base you've built and push it live. Use what you just learned from lecture and the code we wrote, too. Share the url with your instructor via Slack.