Using Heroku Postgres From A Fly App

In a previous article, we showed how simple migrating a database-using application. But what we didn’t mention was that you don’t have to migrate an application from Heroku to Fly to use Heroku’s databases. You can use Heroku databases with a native Fly application.

Heroku supports applications with no apps in them and only add-ons, like Postgres, as a way of providing those services to other applications. As we showed, you can access Heroku Postgres from Fly so it makes it a useful way to get yourself a database for some storage.

So let’s step through the process of what you need to do, and what you need to look out for.

Getting Heroku Prepared

First, sign up for Heroku and get your free account there. For this example we’ll be using their Hobby plan so there’s no expense involved.

Now, you should arrive, once logged in to Heroku, at the Heroku dashboard. Select New on the right of the dashboard and New App in the dropdown menu. On the next screen, give your application a name and select whether you want the database to work out of the US or Europe. Then click Create App and arrive at the initial application setup screen. The details shown won’t be of much relevance to you for this task. Select the Overview tab to get a higher-level view of the app.

You should see entries about the configuration of the app, including at the top, Installed add-ons. Select Configure add-ons in that section and you’ll be taken to a page which doesn’t obviously say it’s for add-ons. That’s underneath the top section for Dynos. The add-ons section has a text field where you can type add-on names. Type postgres into there and select Heroku Postgres. You should see a dialog inviting you to choose a plan - stay on Hobby Dev for a 1GB database capable of holding up to 10,000 rows to keep things free - then click Provision.

Getting Your Credentials

And now, there’s a Heroku Postgres database listed in your add-ons. Click on the database name in the add-ons list to drill down into the database’s configuration. Select Settings and then View Credentials. You’ll want to take a note of what is now displayed, but the most important line in the credentials is the URI line. It’s a long one, with a long hostname, database, username, and password, but it contains all you need to connect to the new database. This is the value that turns up in Heroku apps as DATABASE_URL but for our purposes, we’re going to have to manually transfer it to our app.

Also, pay attention to the warning: Please note that these credentials are not permanent. Heroku rotates credentials periodically and updates applications where this database is attached.. You won’t get any warning that credentials have changed, but if you do have an issue in the future, make checking the credentials your first port of call.

Preparing To Fly

For this example, we’re going to use Node and Sequelize to create a simple Postgres-backed REST API server for storing truefacts. The part we’re most interested in is setting up the connection. Here’s the opening of the main code:

const express = require("express");
const bodyParser = require('body-parser');
const { Sequelize, DataTypes } = require("sequelize");
var parse = require("pg-connection-string").parse;

const connectionString = process.env.DATABASE_URL;

We have to make some modifications to the DATABASE_URL which we got from Heroku. To do those changes as reliably as possible, we use pg-connection-string to parse the URL into its component parts (in terms of Postgres).

connector = parse(connectionString);

Once parsed, we can create the Sequelize connection, and add in the changes needed to connect to Heroku:

const sequelize = new Sequelize(
    connector.database,
    connector.user,
    connector.password,
    {
        dialect: "postgres",
        host: connector.host,
        dialectOptions: {
            ssl: { sslmode: "require", rejectUnauthorized: false },
        },
    }
);

As you can see, we pass over the database, user, password, and host untouched to the Sequelize constructor. What we do add is in the options object. That dialectOptions value requires SSL (because external access to Heroku demands SSL be turned on) and then turns off the rejection of self-signed certificates on the server’s certificate chain, an issue which Heroku’s Postgres has.

The rest of the example application is a simple REST API, where you add true facts about something by POSTing a JSON object to one endpoint and retrieving those facts as JSON objects. You’ll find the code in the truefacts repository in fly-examples.

That’s pretty much all you need to know to get a connection to Fly, apart from how you pass your database credentials to the application. For this, you need to set a secret in the form:

fly secrets set DATABASE_URL="yoururlfromherokupostgres"

Now you are ready to fly deploy your application. It’ll connect up to the backend Postgres on Heroku. Remember that’s limited to 20 connections unless you upgrade to a paid plan.

Wrapping up

We’ve shown how to connect to Heroku’s Postgres without a Heroku application being migrated. Using Heroku’s services is an option for users who need a database option right now, and with Heroku’s data centers in the US and Europe, the database won’t be too far away, while your Fly application can be as close as possible to the user.

Want to learn more about Fly? Head over to our Fly Docs for lots more, including a Hands On where you can get a free account and deploy your first app today.