TUTORIAL: How to deploy an NGINX API gateway on Heroku

Control Access, Monitor Traffic & Manage your API with 3scale

At 3scale’s API management platform and business services provider we recommend using Nginx as an API proxy for several reasons, among them its outstanding performance and its extensibility thanks to the Lua scripting support.

When used to integrate with 3scale’s API Management service, it is hands down the best way to add an access control layer to your existing API.

The following tutorial describes the required steps in order to deploy Nginx acting as an API Gateway proxy on the Heroku platform. Heroku provides a fantastic fully managed platform as a service for your application, so the required maintenance effort for your part will be minimal. Thanks to Nginx being very lightweight, the free offering from Heroku will be enough for most cases.

High-level overview

We will create a Heroku application with a custom buildpack including Lua and Luarocks, and will deploy the Openresty distribution of Nginx using a Luarock especially tailored for Heroku. We will then use the Nginx configuration files generated by 3scale from your API dashboard, and we will tweak them to work properly with our Nginx at Heroku.

Prerequisites

  • a 3scale account. You can sign up for a free account here.
  • a Heroku account
  • the Heroku toolbelt must be installed in your computer. You can get it here.

Summary

  • Set up your API in 3scale and download the auto-generated Nginx config files
  • Clone the git repository with template files
  • Create an empty Heroku app
  • Copy your 3scale Nginx config files into your project directory to replace the templates
  • Modify the Nginx config files to adapt them for deploying in Heroku
  • Push the git repository to deploy Nginx on Heroku
  • Check that everything works

Step by step tutorial

This tutorial will show you how to use Nginx hosted in Heroku as a proxy to integrate your API with 3scale. If you already have an API you can use that. Otherwise you should jump now to the “Deploying a sample API to Heroku” section of this tutorial, where you will deploy a test API in minutes.

Once you have an API to use with the proxy, you can carry on from here.

We will need to deploy the OpenResty web app server, which essentially is a bundle of the standard Nginx core with almost all the necessary 3rd party Nginx modules built-in.

For an easy start, you can fork and clone the repository at https://github.com/Taytay/api-proxy-3scale-heroku.

git clone https://github.com/Taytay/api-proxy-3scale-heroku

This repository contains some boilerplate files required by Heroku. Later on, you will only need to modify the nginx.sample.conf and nginx_3scale_access.lua. You will see a package.rockspec file is included. This is a special type of file that defines Lua dependencies and makes sure that the declared dependencies are fetched and installed when we push our repository to the server. There is only one dependency in this case, which is OpenResty.

After cloning the repository change into the directory that was just automatically created, named “api-proxy-3scale-heroku”.

Heroku doesn’t support the Lua runtime by default, so we will need to create the application using a custom buildpack that includes:

  • Lua 5.1
  • LuaRocks 2.0.7.1, a Lua package manager

You just need to execute this:

heroku create --buildpack http://github.com/leafo/heroku-buildpack-lua.git

The output of this command will show an URL similar to this one:

http://random-heroku-name.herokuapp.com

There is where your will be able to reach your Nginx API proxy.

Heroku create command output

Now we have created an empty Lua application in Heroku. Before deploying Nginx with our configuration, we need to replace the nginx.sample.conf and nginx_3scale_access.lua by our own Nginx configuration files, which we will download from 3scale.

Go through the following steps to download your customized configuration files:

  • sign into your 3scale account
  • go to the API section
  • select the service (will be named “API” if you only have one)
  • select the Integration subsection in the sidebar
  • click on the Proxy tab

There will be some fields that you will have to fill in with information about your API. This data will be used to automatically generate configuration files for Nginx already customized to integrate your API with 3scale.

The most important field right now is the one at the top, namely: “Your API backend”. You should type here the complete URL of your API service, complete with port. For instance:

http://my-api-backend.herokuapp.com:80

If you need further guidance on what how to fill the rest of these fields, visit this tutorial.

One thing to note is that, in case your API is also hosted on Heroku (like the one we are using below for testing), you will also need to fill the hostname rewrite field. Check the previously linked tutorial to find out more about this.

After you have completed all the fields, first click on the “Save” button at the bottom right side of the page and then download them by clicking on “Download Nginx config”, located on the left.

Nginx proxy configuration screen

A few changes are required to the files you just downloaded.

  • move them into your “api-proxy-3scale-heroku” directory.
  • delete the existing nginx.conf and nginx_3scale_access.lua files
  • rename your new .conf file, downloaded from 3scale, to nginx.conf
  • do the same for your new .lua file, renaming it to nginx_3scale_access.lua
  • set your API provider key as an environment variable: heroku config:set 3SCALE_PROVIDER_KEY=1239832745abcde
  • modify nginx.conf
    • add to the top of the file the following lines:
      daemon off;
      error_log stderr;
    • replace listen 80; at the beginning of the server block for listen ${{PORT}};. This is necessary since Heroku can change the port where our process is listening. This way it will be filled in from a environment variable.
    • on the next line change the servername to be the hostname of your Heroku app for the Nginx proxy e.g. in the example above random-heroku-name.herokuapp.com;
    • replace access_by_lua_file lua_tmp.lua
      for access_by_lua_file nginx_3scale_access.lua
    • on the two lines beginning set $provider_key replace them with
      set $provider_key "${{3SCALE_PROVIDER_KEY}}";

Now we are all set and ready to deploy your customized Nginx. Commit the changes and push them to Heroku:

git commit -am "deploying proxy with custom configuration from 3scale"
git push heroku master

Testing

Now we have Nginx adding an access control layer on top of our API. We will make sure that it is working properly by making an authenticated request to your API.

Go back to the 3scale admin portal and get the credentials of one of the sample applications which you created when you first logged into your 3scale account (if you missed that step just create a developer account and an application within that account).

If your API endpoint is:

http://your-api-domain.com/words/hello.json

To use the API proxy you should now make a request to the following URL:

http://your-nginx-herokuapp-domain.com/words/hello.json?app_id=APP_ID&app_key=APP_KEY

Deploying a sample API to Heroku

To test your API proxy you will need an API backend. Here we will walk you through the steps of deploying an API in Heroku. For this tutorial have picked the Sentiment API, which is an API that returns the sentiment rating of a given word.

Bear in mind that you need to create an additional Heroku application to host this API. You cannot have Nginx and the API in the same Heroku application.

The basic endpoint of this API is:

http://api-domain-name/word/good.json

The previous request would return:

{"word":"good","sentiment":3}

We have already prepared a repository containing the Sentiment API and the required configuration files to deploy it in Heroku. You can find this repository here: https://github.com/vdel26/sentiment-api-heroku.git.

If you prefer to deploy your own API onto Heroku, the way you should prepare it depends on your programming language of choice. You can find all the information at the Heroku Dev Center.

To deploy the Sentiment API on Heroku, you should follow this steps:

  • clone the repository into your computer git clone https://github.com/vdel26/sentiment-api-heroku.git
  • move into the repository directory that was created in your computer with the name “sentiment-api-heroku”
  • run heroku create (the console output will show an URL. This will be your API domain.)
  • run git push heroku master

To test that the API was deployed successfuly you can make a request like the following one to the URL that was generated after executing heroku create:

http://myapp-heroku-name.herokuapp.com/word/good.json

Of course this is completely bypassing the access control layer. Note that once your API Gateway is in place, you will want to make sure that public access to your API is blocked. For this purpose you can define your own “proxy secret token” in your 3scale Integration Proxy wizard under Advanced settings. Then your backend app simply verifies that the shared secret is correct.

Troubleshooting

If there is any problem after deploying to Heroku, it is always useful to check the production logs. You can do so by running the following command:

heroku logs

During debugging, it might be useful to temporarily lower the level for error logging. You just need to edit the line that was added at the top of the nginx.conf file and append the desired level (all the possible options are described here):
error_log stderr info;

For further help, we strongly recommend you to check the Heroku Dev Center.

Credits

Full credit goes to Taylor Brown for proposing this solution as an alternative to deploying Nginx on Amazon EC2. Check it out here.

Also many thanks to Leaf Corcoran, creator of the Lua buildpack for Heroku and the awesome OpenResty luarock.