4. Deploying Apollo Server

🚀 Deploying our server

Let's get our GraphQL server up and running in production using Heroku!

Heroku is a cloud service platform that enables us to deploy our app without having to worry about the infrastructure specifics. This course uses Heroku because it can sync to a GitHub repository and it has a free tier that lets us run our app without a credit card!

First, create an account on Heroku. Next, let's create a new app.

Screenshot of the Heroku dashboard showing the Create new app button

Give it a good name, select your region, and click Create app.

Screenshot of the Heroku dashboard showing the app creation page

After the app is created, we have a few options for deployment methods. We could use the Heroku Git CLI, or GitHub.

For this course, we'll use GitHub. Heroku will pull the content from our GitHub repo and use it to build our app. To deploy your app using the Heroku CLI instead, refer to the collapsible section below.

With the Connect to GitHub option selected, make sure you have your GitHub account authenticated with Heroku. We can then search for the repository to connect to and select the server app first.

Screenshot showing the GitHub option selected and server repository to connect to

2️⃣ Deployment options

We now have two options: automatic or manual deploys.

With automatic deploys, Heroku deploys your updated app after every commit you make to a particular GitHub branch.

For now, we'll stick with manual deploys, which means clicking on Deploy Branch every time we want to push the latest changes from our GitHub main branch to Heroku. This gives us control over when we want to push to production.

Before we do that, we need to make one change to our code. Heroku needs our server to run on a port specified by the PORT environment variable, which is set behind the scenes.

🔌 Setting the PORT

Let's open up our server repo. In the src folder, open up the index.js file.

Right now, by default, Apollo Server is listening on port 4000. We need to update this by specifying an options object in the listen method.

await server.listen({port: process.env.PORT || 4000});

The port property should be set to process.env.PORT (with PORT in all-caps). To make sure our server still works locally on our own machines however, we'll add an "or" (||) and specify 4000 as our port number.

And that's it! Let's make sure to add and commit these changes, and push it up to our GitHub repo.


Code Challenge!

Edit the code below to configure Apollo Server to listen to a port specified by process.env.PORT, or if that doesn't exist, a hard-coded port number 4000.

🌲 Adding the environment variables

The last thing we need is to grab the three variables we saw earlier when we created a new graph in Apollo Studio. We need to make them available as environment variables to our Apollo Server so that we can complete the process of registering this schema.

In Heroku, we'll click Settings and scroll down to the Config Vars section. Click Reveal Config Vars to see where we can add key-value pairs as our environment variables.

One by one, add the three environment variables that Apollo indicated.

Screenshot of adding the environment variables in Heroku's Config Vars section

Note that this process will look different on platforms besides Heroku, so make sure to consult your chosen platform's documentation.


👆🏽 Starting the deploy process...

Going back to the Deploy page, we can finally click Deploy Branch and wait for the output to complete successfully.

Screenshot of the Deploy Branch button on the Deploy page

Did it work? Let's click View, and we're redirected to our Heroku app URL for the server. This is our production URL, which the client app will be using later on.

Screenshot of Apollo Server landing page in production

This page looks a bit different from what we would normally see if we had run our server locally. We don't have the option to query our server through Apollo Sandbox. This is because by default, Heroku sets the NODE_ENV environment variable to production, which alerts our Apollo Server to switch itself to production as well, automatically disabling introspection.

🤔 What is GraphQL introspection?

Introspection is a GraphQL feature that enables us to query a GraphQL server for information about the underlying schema. This includes data like types, fields, and field-level descriptions. Tools like Apollo Sandbox use introspection to build and run queries.

Illustration of introspection in development environments

The problem is that having introspection in production can be a major security issue. It exposes all of our graph's structure and what we can do with it to the whole world. In most cases, that's not what we want! This is why Apollo Server disables introspection by default in a production environment.

Illustration of introspection in production environments, where introspection is turned off

What information can we query from a GraphQL server through the introspection feature?

Which of these statements are true about the introspection feature?

How do we test our server if we can't query it with tools that rely on introspection? Well, thanks to the schema registry, we now have a secure way to access our graph and run queries on it using Apollo Explorer.

We can continue to use the Explorer to test a deployed graph, in the same way we've been using it for our local graph.

Navigate to the Explorer and test out the tracksForHome query below:

query GetTracks {
tracksForHome {
author {

Note: The first time you try to run the query, the Explorer will prompt you for the URL of your production server!

Screenshot of Apollo Explorer connection settings for deployed graph


Amazing, our server is live in production! 🎉 Next, let's tackle the client app.