Seeking advice about securing postgres on Fly

Learning as I go here, and grateful for any advice and clarification:

I have an Fly app running a newsletter service, connected to a Fly postgres app. I’d like secure traffic to and from postgres.

Fly app to/from postgres app:

The newsletter service (listmonk) includes an SSL mode for securing traffic between the app and the postgres database. Enabling this requires setting up an nginx reverse proxy.

However, Fly’s private networking should eliminate the need for setting up SSL for app-to-database traffic, correct?

External traffic to/from postgres app:

The only external interaction with the postgres database is when I’m managing it in a terminal (psql, pg_dump, etc), and I’m doing that only through fly proxy and fly postgres connect.

Are the postgres data and postgres password sent and received securely when running psql commands through fly proxy? Or would it be ideal to set up an nginx reverse proxy to handle SSL for these intermittent interactions?

You are correct. Our private network makes SSL between your app and the DB unecessary.

fly proxy and fly postgres connect both create the equivalent of a VPN connection to your private network. This is also Wireguard, so traffic between your local machine and database is also encrypted.


Thank you. One follow-up on the same topic of postgres security:

I saw this comment from last December.

Is this still the case?

No, that’s no longer true. Restores work fine on encrypted volumes now.


Awesome. Can flyctl encrypt existing volumes, or does a new encrypted one need to be created?

Ok, here’s what I did to encrypt my existing unencrypted postgres volume(s):

  1. Create a replica outside of my postgres primary region with fly postgres create and fly scale count. If I actually want to finish with a replica in that region, then make it an encrypted replica.
  2. Use these steps to change the primary region to the new region.
  3. Wait until fly status shows the new region as leader, and the original region as replica.
  4. Delete the volume in the original region.
  5. Create an encrypted replica in the original region.
  6. Go through the instructions linked in step 2 again, this time to change the primary region to the original region.
  7. Wait until fly status shows the original region as leader, and the new region as replica.
  8. Delete unencrypted replicas and create encrypted replicas as needed.
1 Like

Since SSL is not supported with Fly Postgres, it would be helpful to have ?sslmode=disable appended to the DATABASE_URL. This would resolve default connection failures that make the service feel broken.

Hey @paulrudy! Thank you for the steps. I don’t see anything in the docs for the fly postgres create command that would force the encryption on. Without it, I assume it’ll default to unencrypted still? Are you able to share how you did it?

1 Like

New volumes (and therefore new Postgres apps) now default to encrypted!


Glad they were useful!

The command is actually the other way around: fly postgres create and fly volumes create default to creating encrypted volumes unless the --no-encryption flag is used. In the docs:

Volumes are, by default, created with encryption-at-rest enabled for additional protection of the data on the volume. Use --no-encryption to instead create an unencrypted volume for improved performance at deployment and runtime.

But as @shugel said, it looks like the fly launch creates encrypted Postgres volumes by default now, so the steps I outlined are only needed if you started with an unencrypted Postgres volume.

1 Like

Good idea! We are making it the default Pass sslmode=disable in postgres DSN by dangra · Pull Request #1435 · superfly/flyctl · GitHub and will ship today as of flyctl v0.0.427 (soon)