Quarkus: Datasource '<default>': FATAL: no pg_hba.conf entry for host - postgresql

I wrote a Quarkus JPA/Hibernate app with PostgreSQL DB perfectly working with a JVM - run by 'quarkusDev' gradle task.
When I compile the native application with
#!/usr/bin/env bash
export QUARKUS_PROFILE=****
export PG_USERNAME=*****
export PG_PASSWORD=*****
export JAVA_HOME=/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home
./gradlew build -Dquarkus.package.type=native
the compilation goes fine, but when I run the native image I get:
14:41:23 WARN [io.ag.pool] Datasource '<default>': FATAL: no pg_hba.conf entry for host "***.***.***.***", user "xxxxxxxxxxxxxx", database "*****", SSL on
14:41:23 WARN [or.hi.en.jd.sp.SqlExceptionHelper] SQL Error: 0, SQLState: 28000
14:41:23 ERROR [or.hi.en.jd.sp.SqlExceptionHelper] FATAL: no pg_hba.conf entry for host "***.***.***.***", user "xxxxxxxxxxxxxx", database "*****", SSL on
14:41:23 ERROR [io.qu.application] Failed to start application: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
I tried to add a pg_hba.conf file:
# TYPE DATABASE USER ADDRESS METHOD
host all all 0.0.0.0/0 md5
and put it to
/src/main/resources
and/or to the native image directory, but without luck.
Also, I configured the resources for my native image adding a 'resources-config.json' to '/src/main/resources':
{
"resources": [
{
"pattern": ".*\\.yaml$"
},
{
"pattern": ".*\\.conf$"
},
{
"pattern": ".*\\.txt$"
},
{
"pattern": ".*\\.html$"
}
]
}
I added the following line to 'application.yml'
quarkus:
native:
additional-build-args: -H:ResourceConfigurationFiles=resources-config.json
But even doing so, the pga_hba.conf is not found, and when run, the native image keeps on complaining.

The issue is with the pg_hba.conf being used by the Postgres server. You need to find it and add an entry that will match the connection parameters you are sending to the server.

It turned out that I missed to pass environment variables to the executable.
Of course - obvious after realizing what the problem was! - you not only need to pass DB Environment Variables when you compile the native image - so the tests can be run - but you also need to pass them when you launch it.
So, a script like this solves the issue:
#!/usr/bin/env bash
export PG_USERNAME=*****
export PG_PASSWORD=*****
./build/my-native-image.runner

Related

Hostname resolving error in Stepzen Graphiql explorer when connecting with Supabase Postgresql database

I have set up Stepzen as described in the Getting Started Docs. I get the following error when running stepzen start:
{
"data": {
"getProfilesList": null
},
"errors": [
{
"message": "database error: can't prepare the statement for execution failed to connect to `host=postgres user=root database=`: hostname resolving error (lookup postgres on 10.97.0.10:53: no such host)",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"getProfilesList"
]
}
]
}
The message shows wrong hostname, user and empty database, although my config file has the correct credentials:
configurationset:
- configuration:
name: postgresql_config
uri: postgresql://postgres:[My Password]#[My Supabase DB Host]/postgres
I have also tried to connect to the DB directly from a GUI client and the connection was successful.
Why this issue is coming up when trying to connect from Stepzen Graphiql explorer running on localhost?
Postgres requires the password to be URL Encoded when using some characters that have a special meaning.
You can learn more about percent-encoding to handle special characters in Postgres passwords here: How to handle special characters in the password of a Postgresql URL connection string?

Getting correct socketPath for TypeORM config

I'm trying to connect a Cloud Run service to Cloud SQL postgres instance. I believe I'm nearly there, but am having some trouble getting the deployed instance to connect properly. My local environment can connect (via SSL) to the database intended for production, but the deployed version can't...
I'm using TypeORM, and have everything setup properly in the configuration...
#Module({
imports: [
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (configService: ConfigService) => {
const socketPath = configService.get('DB_SOCKET_PATH');
const extra = socketPath ? {
socketPath: socketPath,
ssl: {
rejectUnauthorized: false,
ca: Buffer.from(process.env.DB_SSL_CA, 'base64').toString('ascii'),
cert: Buffer.from(process.env.DB_SSL_CERT, 'base64').toString('ascii'),
key: Buffer.from(process.env.DB_SSL_KEY, 'base64').toString('ascii'),
}
} : { };
return ({
type: 'postgres',
host: socketPath || configService.get('DB_HOST'),
port: configService.get('DB_PORT'),
username: configService.get('DB_USER'),
password: configService.get('DB_PASS'),
database: configService.get('DB_NAME'),
extra: extra,
entities: [__dirname + '/../../modules/**/*.entity{.ts,.js}'],
namingStrategy: new SnakeNamingStrategy(),
synchronize: true,
});
}
})
]
})
export class DatabaseModule { }
Despite that I'm getting an error when I try to use the socketPath as the host rather than the actual host variable (necessary for GCP). It seems that TypeORM is adding extra characters, /.s.PGSQL.5432, at the end of my connection string that I don't want. And just to clarify, the socket path is in the form of /cloudsql/<PROJECT_ID>:<REGION>:<INSTANCE>.
[Nest] 28532 - 02/15/2021, 2:25:07 PM [ExceptionHandler] connect ENOENT <DB_SOCKET_PATH>/.s.PGSQL.5432 +3ms
Error: connect ENOENT <DB_SOCKET_PATH>/.s.PGSQL.5432
at PipeConnectWrap.afterConnect [as oncomplete] (net.js:1141:16)
At an older point in time, this used to work for me but I guess something changed in the TypeORM library. Does anybody have any ideas on this? Thanks!
EDIT: As of now I've gotten it to connect to the server correctly, but it's now giving me an error that says the server doesn't support SSL connections, which makes no sense given that I can connect via SSL fine on my local machine...?
SOLUTION: The issue does not seem to any code's fault, but rather some networking stuff on the GCP side. I configured the service and database to run through a VPC then just used a private IP address for the host.
It seems that TypeORM is adding extra characters, /.s.PGSQL.5432
This is actually intended - the Postgres spec requires that the unix sockets end with this suffix.
[Nest] 28532 - 02/15/2021, 2:25:07 PM [ExceptionHandler] connect ENOENT <DB_SOCKET_PATH>/.s.PGSQL.5432 +3ms
The error means that the socket wasn't found - usually because there was a misconfiguration and the Cloud SQL proxy couldn't start. You can check your logs at the instance start up to see if the proxy left any errors, but generally it'll come down to the following:
The Cloud SQL Admin API needs to be enabled
Your service account needs to have Cloud SQL Connect IAM role (or equivalent)
The service needs to be configured for Cloud SQL.
For a full list of instructions, see the Connecting from Cloud Run to Cloud SQL page.

Heroku can't connect with Postgres DB/Knex/Express

I have an Express API deployed to Heroku, but when I attempt to run the migrations, it throws the following error:
heroku run knex migrate:latest Running knex migrate:latest on ⬢
bookmarks-node-api... up, run.9925 (Free) Using environment:
production Error: connect ECONNREFUSED 127.0.0.1:5432
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1117:14)
In my knexfile.js, I have:
production: {
client: 'postgresql',
connection: {
database: process.env.DATABASE_URL
},
pool: {
min: 2,
max: 10
},
migrations: {
directory: './database/migrations'
}
}
I also tried assigning the migrations directory to tableName: 'knex_migrations' which throws the error:
heroku run knex migrate:latest Running knex migrate:latest on ⬢
bookmarks-node-api... up, run.7739 (Free) Using environment:
production Error: ENOENT: no such file or directory, scandir
'/app/migrations'
Here is the config as set in Heroku:
-node-api git:(master) heroku pg:info
=== DATABASE_URL
Plan: Hobby-dev
Status: Available
Connections: 0/20
PG Version: 10.7
Created: 2019-02-21 12:58 UTC
Data Size: 7.6 MB
Tables: 0
Rows: 0/10000 (In compliance)
Fork/Follow: Unsupported
Rollback: Unsupported
I think the issue is that for some reason, it is looking at localhost for the database, as if the environment is being read as development though the trace shows Using environment: production.
When you provide an object as your connection you're providing individual parts of the connection information. Here, you're saying that the name your database is everything contained in process.env.DATABASE_URL:
connection: {
database: process.env.DATABASE_URL
},
Any keys you don't provide values for fall back to defaults. An example is the host key, which defaults to the local machine.
But the DATABASE_URL environment variable contains all of the information that you need to connect (host, port, user, password, and database name) in a single string. That whole value should be your connection setting:
connection: process.env.DATABASE_URL,
You should check to see if the Postgres add-on is setup as described in these docs since the DATABASE_URL is automatically set for you as stated here.

Vapor Framework : Configure a postgres connection with SSL

I'm trying to connect to my Heroku PostgreSQL database but I have the following error :
cannotEstablishConnection("FATAL: no pg_hba.conf entry for host \"37.167.93.189\", user \"clpnkpyttmdtyq\", database \"d3h6147v73mgtu\", SSL off\n")
I know that Heroku postgres databases need to use an SSL connection but I don't know how to configure the connection on my Droplet object.
This is my postgresql.json configuration file :
{
"host": "ec2-54-163-224-108.compute-1.amazonaws.com",
"user": "clpnkpyttmdtyq",
"password": "99201aa07c48e18e7bdf210937857b85bee37cd8d8cb904381b1ddff934c7a4f",
"database": "d3h6147v73mgtu",
"port": 5432
}
Maybe there is ssl parameter that I don't know ?
How I add the VaporPostgresSQLProvider :
let drop = Droplet()
// Tell the droplet to use our SQL provider service
try drop.addProvider(VaporPostgreSQL.Provider.self)
Any ideas ?
When I try with my local postgres database, it works, because it don't need ssl connection.
For Heroku we need unverifiedTLS transport.
https://api.vapor.codes/postgresql/latest/PostgreSQL/Classes/PostgreSQLConnection/TransportConfig.html
let pgURL = Environment.get("DATABASE_URL") ?? "postgres://user:password#host:port/database"
let pgConfig = PostgreSQLDatabaseConfig(url: pgURL, transport: PostgreSQLConnection.TransportConfig.unverifiedTLS)!
it's a process that personally cost me a lot, this solution works for me, try this
On file Config > secrets > postgresql.json add this configuration (for use on local or remote, if this file not exist, create this)
{
"host": "127.0.0.1",
"user": "your_user_pc",
"password": "",
"database": "your_user_pc",
"port": 5432
}
The user can get it from Terminal
$ cd ~
On your file Procfile (sited on your project, show via finder) edit and add this code
web: App --env=production --workdir="./"
web: App --env=production --workdir=./ --config:servers.default.port=$PORT --config:postgresql.url=$DATABASE_URL
Now you can re-launch your application to heroku, you should consider having the server configured correctly from heroku with all its credentials and add-ons of Postgresql from the interface of Heroku
Note: And do not forget every change you make, run "vapor build" or "vapor build --clean"
Vapor 4 + build stack heroku-20 + Heroku Postgres's standard plan
Rijel David's suggestion did the trick for me
But unverifiedTLS syntax has slightly changed
if let databaseURL = Environment.get("DATABASE_URL"), var postgresConfig = PostgresConfiguration(url: databaseURL) {
postgresConfig.tlsConfiguration = .forClient(certificateVerification: .none)
app.databases.use(.postgres(
configuration: postgresConfig
), as: .psql)
} else {
// ...
}
Check out Vapor doc - https://docs.vapor.codes/4.0/deploy/heroku/

Flyway cannot connect to db after Heroku Postgres upgrade

I am upgrading my heroku database from a hobby dev to Standard 0 (using the official instructions https://devcenter.heroku.com/articles/upgrading-heroku-postgres-databases#upgrade-with-pg-copy-default).
All went well, until I promoted the new database and restarted the app. I then get the following error:
o.s.boot.SpringApplication : Application startup failed
...
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flywayInitializer' defined in class path resource [org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration$FlywayConfiguration.class]: Invocation of init method failed; nested exception is org.flywaydb.core.api.FlywayException: Unable to obtain Jdbc connection from DataSource
...
Caused by: org.flywaydb.core.api.FlywayException: Unable to obtain Jdbc connection from DataSource
...
Caused by: org.postgresql.util.PSQLException: FATAL: no pg_hba.conf entry for host "54.xxx.xx.xxx", user "u94bf9vxxxxxx", database "d2mqk0b6xxxxxx", SSL off
...
If I swap back to the old database again, everything works again. The only thing that I am changing is the promoted database.
Is there a difference between connecting to hobby and standard databases that I need to be aware of?
The relevant part of my application.yml looks as follows:
spring:
datasource:
driverClassName: org.postgresql.Driver
url: ${JDBC_DATABASE_URL}
username: ${JDBC_DATABASE_USERNAME}
password: ${JDBC_DATABASE_PASSWORD}
flyway:
enabled: true
locations: classpath:db/migrations
Any suggestions on how I can debug this would be very welcome too.
Looks like you aren't connecting with SSL where it is required by Heroku PostgreSQL installs.
See Herokus documentation on SSL for PostgreSQL.
See also Herokus documentation for enabling SSL on JDBC connections.
You will need to add something like &ssl=true&sslfactory=org.postgresql.ssl.NonValidatingFactory to your JDBC URL.