Postgres-over-TLS Example
July 7, 2026 ยท View on GitHub
Summary
The Postgres-over-TLS example shows how to proxy PostgreSQL connections while serving HTTPS on the same port (443/tcp).
Configuration
Caddyfile
{
servers {
listener_wrappers {
layer4 {
@tls-pgsql tls {
# including the ALPN condition below
# lets Caddy serve HTTPS requests
# for the same server name
alpn postgresql
sni pgsql.example.com
}
route @tls-pgsql {
tls {
# the connection policy below is required
# because PostgreSQL 17+ direct TLS client
# offers only `postgresql` as the ALPN value;
# it is safe to omit the connection policy
# if the client offers `h2` and/or `http/1.1`,
# but the matcher above has to be adjusted as well
connection_policy {
# supported by PostgreSQL 17 or later
alpn postgresql
}
}
# decrypted traffic is presumed to be PostgreSQL,
# so no other checks are made before proxying it
proxy localhost:5432
}
}
tls
}
}
}
*.example.com {
respond "OK" 200
}
JSON
{
"apps":{
"http":{
"servers":{
"srv0":{
"listen":[
":443"
],
"listener_wrappers":[
{
"routes":[
{
"handle":[
{
"connection_policies":[
{
"alpn":[
"postgresql"
]
}
],
"handler":"tls"
},
{
"handler":"proxy",
"upstreams":[
{
"dial":[
"localhost:5432"
]
}
]
}
],
"match":[
{
"tls":{
"alpn":[
"postgresql"
],
"sni":[
"pgsql.example.com"
]
}
}
]
}
],
"wrapper":"layer4"
},
{
"wrapper":"tls"
}
],
"routes":[
{
"match":[
{
"host":[
"*.example.com"
]
}
],
"handle":[
{
"handler":"subroute",
"routes":[
{
"handle":[
{
"body":"OK",
"handler":"static_response",
"status_code":200
}
]
}
]
}
],
"terminal":true
}
]
}
}
}
}
}