Remark: The fly.toml has two[[services]] in it. One for port 5432 and a second one for port 5433. Both mapped. I didn’t touch it.
fly services list
Services
PROTOCOL PORTS HANDLERS FORCE HTTPS PROCESS GROUP REGIONS MACHINES
TCP 5432 => 5432 [PG_TLS] False app fra 1
TCP 5433 => 5433 [PG_TLS] False app fra 1
DB is running. Health check ok. Now how to connect to it?
With shared-IP
Assigned shared-IP => does not work
Connect via public hostname liquido-db-fly-int.fly.dev => did not work
Via comand line
> psql "sslmode=require host=liquido-db-fly-int.fly.dev dbname=postgres user=postgres"
psql: error: connection to server at "liquido-db-fly-int.fly.dev" (66.241.125.63), port 5432 failed: server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
Same test with dedicated-IP
(Some other forum post mentioned that this might be neccessary.)
> psql "sslmode=require host=137.66.21.126 dbname=postgres user=postgres"
psql: error: connection to server at "137.66.21.126", port 5432 failed: SSL error: unexpected eof while reading
… I am running out of ideas. Any tips? Any more information I can provide?
Aahh fly postgres connect -a liquido-db-fly-int works. Mmh but what is it doing differntly. Can I somehow see the sql connection string that it creates internally?
Hey fly team your network setup needs work. psql postgresql://postgres@213.188.223.237 (static assigned-IP address) works. But SQL clients with exactly the same connection string, complain with a SSL SYSCALL error: EOF detected. Seems like someone (proxy?) interrups the connection.
This is really weired. psql command line works. But for example java-quarkus also throws the same error:
javax.net.ssl.SSLHandshakeException: Remote host terminated the handshake
Caused by: java.io.EOFException: SSL peer shut down incorrectly
I’ve not tried this, but I wonder if there is something that one would need to do to make the SSL cert valid in Postgres. This might explain why it works when you disable SSL on the client side; it is avoiding an invalid/absent certificate.
If your db server is offering ports for plaintext and SSL, could this command just be plumping for the unencrypted one?
I assume this is from an external connection. Which port did you specify here?
At least for my backend, the TLS terminates at the Fly Proxy. I assumed this would be the same for the DB image provided by Fly.io For testing my backend this is quite handy. Fly offers a valid letsencrypt cert for *.fly.dev So I can connect to the fly proxy via HTTPS on port 443 and that forwards an unencrypted connection via the private intranet to my backend. => But I just realize this only seems to be the case for webapps on Port 443 according to that doc.
The connection to postgres by default goes over port 5432. There is this pg_tls handler but I couldn’t get it to work.
It now works. I think mostly because DNS bindings are now up to date and have propagated.
My main learnings are (sharing for everyone):
Your client (e.g. JDBC, Postico)
|
| TLS handshake (Postgres-native)
v
Fly Global Edge Proxy (pg_tls)
|
v
Postgres process inside your VM (usually plain TCP)
A postgres server has its own native TLS handshake (not HTTPS!)
If you want to connect to your database from the outside via TLS you need:
a static IP adress assigned to your machine
fly.toml with both ports mapped (5432 and 5433)
must use .fly.dev as host in the connection string (not the IP! otherwise the cert is rejected
and you must wait (a minute up to hours) until that sub domain is associated with your static-IP also in your local uplink providers DNS.
Example command lines
Using Fly Tools: Connect to db CLI
fly postgres connect -a <your-db-app-name>
Forward local 5400 (just an example) to the remote 5432
Then you can connect your DB client to postgres://localhost:5400
fly proxy 5400:5432
Plain psql client CLI
psql postgresql://postgres@<your-db-app-name>.fly.dev:5432
All this is only if you need to securely connect to your database from the outside, from the public internet. A backend running on another fly machine can simply directly connect to your DB without TLS and without the need for a static IP. Just internal private flycast.