MeLightningspirit's Blog

How to redirect a Heroku subdomain

Road street sign way.

This article covers how to redirect all requests from my-app.herokuapp.com to another address, like my-app.github.io or my-app.com.

The same approach can be used in other situations where you need a permanent redirect to maintain consistency with previous URLs.

We faced this challenge when planning to migrate some apps from Heroku to our own Kubernetes instance.

These apps also had a custom domain configured, so we needed to redirect all incoming requests to the new domain pointing to our Kubernetes cluster.

To do this, I created a small Node.js app that responds to every request with an HTTP/1.1 301 Moved Permanently status, keeping the path structure intact.

We monitored the Heroku instance for a few months and saw a gradual decrease in requests over the first few days, eventually reaching zero in the last 30 days. After that, we shut it down and completed the migration.

How to use?

It's all done in four simple steps.

The source code is available in this Github repository and you can use it for your own purposes.

The codebase is a simple Node.js app that creates an HTTP server and handles a raw HTTP response using the native http.createServer method.

It also includes a Procfile, which will be activated as soon as it’s deployed to Heroku.

Steps

1. Clone the repository

First, clone the repository and configure the Heroku git remote to push:

$ git clone https://github.com/lightningspirit/permanent-redirect-server.git
$ git remote add heroku https://git.heroku.com/my-app.git

2. Run the tests

Make sure you'll run the automated tests before using this for real.

$ npm test

If anything went wrong in this part, you should not proceed but file an issue in the repository.

3. Configure the address to redirect

Now, you need to tell the script where to redirect all new requests by adding a new environmental variable to the container:

$ heroku config:set NEW_BASE_URL=https://my-app.com -a my-app
Setting NEW_BASE_URL and restarting my-app... done, vX
NEW_BASE_URL: https://my-app.com

All set! Now we just need to deploy it.

4. Zero-downtime deployment

Heroku's deployment strategy aims to minimize downtime when uploading a new version. The existing containers are only removed once the new one is ready and all current requests are completed.

There's even a pre-boot option for apps that need to warm up their content, but for this case, you can ignore it.

Before taking this step, make sure the new instance is properly working and can handle the traffic shift from Heroku.

So, let's deploy it:

$ git push heroku master

Wait for the build process to finish, and test it:

$ curl http://my-app.herokuapp.com/foo/bar?param=value -v
< HTTP/1.1 301 Moved Permanently
< Location: http://my-app.com/foo/bar?param=value

And that's it! From now on, all requests will be redirected to the new instance.

Featured image by Gratisography