Deploying Node.js Remote Server to Heroku
Running a local server is fine for quickly testing changes to your application, but you will need to set up something more permanent to host persistent URL requests. Cloud services like Heroku, which is set up to be very simple for small sites, are becoming increasing popular options rather than using a complete server (either in hardware or as a Virtual Machine, VM) that takes up unnecessary resources and needs to be maintained. Like most cloud services, Heroku comes with a set of command line tools to ease the task of deploying your code to the cloud. If are already familiar with a different cloud service, like AWS or Azure, you are welcome to use it instead.
Your server cannot be hosted just on your personal machine — it must be deployed to a server that is always available to run your application. Everyone should do the steps below to ensure you have the basics setup correctly for you.
We will go through the following steps to deploy our server to the Cloud:
Getting Started
Given a project setup as a complete web app, with separate front- and back-ends, it should be fairly painless to actually deploy it (we, and Heroku, hope :).
Install Heroku CLI
Like Vue, Heroku has its own Command Line Interface to facilitate working with its services. It also serves as a good model for understanding true serve or cloud systems in general since most interaction with them will be remote, using a Terminal, since since the machines themselves do not even have monitors attached to them!
To start you will need to create a Heroku account. As a free service it limits you to only five servers, but that should be plenty for the rest of the semester.
In your Terminal, type the following to install Heroku's CLI tools:
- Mac/Linux:
sudo npm install -g heroku
This will prompt you to enter your local account password to authenticate the command, like when you install many apps for your computer (there are ways to avoid usingsudo
, but they are beyond what we can cover here, so only check it out if you have reasonable Terminal experience or already use Homebrew)
In general, be very careful running commands usingsudo
, because it provides administrative access to your computer. - Windows:
npm install -g heroku
To connect your current project to Heroku run the following commands within your project's top-level folder after you have set it up as a GIT repository (either by clone
-ing an existing one or using git init
to start a new one). This is a one time set up for each project you make that adds Heroku as a remote client (like Gitlab) for your repository.
heroku login heroku create
Save the URL assigned to your project by Heroku — it is the last line of the long output from the create
command and looks something like this:
https://whispering-harbor-84979.herokuapp.com/
You will also need to add heroku
as a remote destination for your GIT repository:
git remote add heroku https://git.heroku.com/PROJECT-NAME-ID.git
Deploying the Backend of your Web App
To prepare the server to work in Heroku's environment, you will need to make two changes to the server's code:
- When deployed, your server will be assigned a port to listen on, so you will not be able to use your favorite number:
const PORT = process.env.PORT || 3000;
-
Add a piece of middleware that explicitly allows your server to be accessed from URLs outside of
herokuapp.com
using the CORS package (it is named after the type of error it is trying to prevent :). As a reminder, this package will need to be added to yourpackage.json
file and installed using the commandnpm install
because, when using Cloud services like Heroku, it is even more important that you follow this practice because they rely on the dependencies listed in that file so they can support your server app from scratch each time it is needed.const cors = require('cors'); app.use(cors());
To actually deploy your code, simply push
it to Heroku like you would when submitting to Gitlab — that's it! Heroku takes care of the rest, automatically installing your dependencies (based on your package.json
file) and running your project (based on the start
command in your package.json
file). Note the target of the push
is given as heroku
instead of origin
so when you are finally ready to submit your project, you will want to push twice to ensure both locations have your most recent code.
Run these commands in the top-level folder of your GIT repository to push
only the server project folder, since it represents only a small piece of your overall project:
git add PROJECT_NAME/server git commit -m "Prepared server for deployment to Heroku" git subtree push --prefix PROJECT_NAME/server heroku master
After Heroku is finished receiving the code and completes setting up its environment, you can now see if the server app is running as you expect using the URL you saved in the previous step by visiting it in your browser (e.g., to see what JSON it responds with). Note, it may take a minute to start sometimes because Heroku may need to start your server environment from scratch when it is accessed (rather than actually leaving it running all the time).
https://PROJECT-NAME-ID.herokuapp.com/
Hopefully you now a response from your server displayed in your browser! If not, you may need to check Heroku's (remote) logs since nothing will be displayed in your browser's (local) console logs. If so, then you are encouraged to take some time to experiment with this process to understand how it works (including making intentional errors to see the results).
To see the affects of your changes in the actual Cloud, you will need to repeat the typical GIT process: add
, commit
, push subtree
(to heroku
). Even though the process itself is simple, it clearly takes a while to actually move the code from your machine to the Cloud, recreate the programming environment, and serve up the data so it is likely not something you will do very often --- test locally on your machine for basic changes (again, like you treat Gitlab).
The following commands may also be helpful while developing your server code:
heroku logs --tail
Show the console output from your running server (such as errors, Morgan's middleware logs, or yourconsole.log()
messages)heroku local web
Run a "local" version of your server on port 5000 (as if it were in Heroku's environment)heroku help COMMAND
Find out more about using the Heroku CLI commands online or within the Terminal
Updating the Frontend to Use Heroku
Now that the server is up and running, let's update the frontend code to interact with Heroku's remote web server rather than the one running on your local machine.
You will need to make only one change to the code to make it refer to the new server URL when making API calls, rather than relying on VS Code's proxy that links it to the server running on localhost
. For example, when using fetch()
:
const response = await fetch('https://PROJECT-NAME-ID.herokuapp.com/api/getLinks');
That's it --- the page should even update automatically if you were running your frontend Dev-Server before saving that line (i.e., you do not need to commit anything to GIT to see the results)! And thanks to the power of JavaScript's Promise (i.e., await
) architecture, the response will be filled in when the fetch()
completes, whether it happens immediately, on a slow network, or whether it has to wait for Heroku to recreate your server environment (i.e., download all those NPM packages)!!
When you are ready to see the changes to your frontend on Gitlab (i.e., probably not too often) then, as a reminder, you need to run the following commands to transpile a standard version of the code for running on a typical server and putting the code from your local machine onto Gitlab's central repository using your preferred tool (VS Code or the Terminal in the project's ui
folder as shown below):
npm run build git add dist git commit -m "Built standard JavaScript version for browsers" git push origin master
When you visit the resulting page in your browser you will be seeing a connection between your public frontend running on Gitlab Pages (or any web hosting service) and your backend's API running on Heroku (or any Cloud hosting service)!!!