I've built a simple Vapor 3 API that I'd like to deploy on Heroku. I'd like it to be backed by a PostgreSQL database which is also attached to another Heroku app (I have successfully attached the DB in the Heroku dashboard – and the DB works correctly in the other application). However, my Vapor app never completes starting up, crashing with the following error:
Fatal error: Error raised at top level: ⚠️ PostgreSQL Error: no pg_hba.conf entry for host "[the IP addr]", user "[heroku postgres username here]", database "[heroku psql db here]", SSL off
- id: PostgreSQLError.server.fatal.ClientAuthentication
I used vapor heroku init
to set up the Heroku app. I've Googled around, and tried adding a Procfile
and messing with configure.swift
, but so far no luck. Here are all the relevant files I can think of:
Procfile:
web: Run serve --env production --hostname 0.0.0.0 --port $PORT --config:postgresql.url $DATABASE_URL
configure.swift:
import FluentPostgreSQL
import Vapor
/// Called before your application initializes.
public func configure(_ config: inout Config, _ env: inout Environment, _ services: inout Services) throws {
/// Register providers first
try services.register(FluentPostgreSQLProvider())
var contentConfig = ContentConfig.default()
/// Create custom JSON encoder
let jsonEncoder = JSONEncoder()
if #available(OSX 10.12, *) {
jsonEncoder.dateEncodingStrategy = .iso8601
} else {
jsonEncoder.dateEncodingStrategy = .millisecondsSince1970
}
// jsonEncoder.keyEncodingStrategy = .convertToSnakeCase
/// Register JSON encoder and content config
contentConfig.use(encoder: jsonEncoder, for: .json)
services.register(contentConfig)
/// Register routes to the router
let router = EngineRouter.default()
try routes(router)
services.register(router, as: Router.self)
/// Register middleware
var middlewares = MiddlewareConfig() // Create _empty_ middleware config
/// middlewares.use(FileMiddleware.self) // Serves files from `Public/` directory
middlewares.use(ErrorMiddleware.self) // Catches errors and converts to HTTP response
services.register(middlewares)
// Configure a database
let dbConfig: PostgreSQLDatabaseConfig
if let url = Environment.get("DATABASE_URL"), let psqlConfig = PostgreSQLDatabaseConfig(url: url) {
dbConfig = psqlConfig
} else {
dbConfig = PostgreSQLDatabaseConfig(hostname: "localhost", port: 5432, username: "admin", database: "development", password: nil)
}
let postgresql = try PostgreSQLDatabase(config: dbConfig)
/// Register the configured SQLite database to the database config.
var databases = DatabasesConfig()
databases.add(database: postgresql, as: .psql)
services.register(databases)
/// Configure migrations
var migrations = MigrationConfig()
migrations.add(model: Visit.self, database: .psql)
services.register(migrations)
}
Package.swift:
// swift-tools-version:4.0
import PackageDescription
let package = Package(
name: "SubwayNyc",
dependencies: [
// 💧 A server-side Swift web framework.
.package(url: "https://github.com/vapor/vapor.git", from: "3.0.0"),
// 🔵 Swift ORM (queries, models, relations, etc) built on PostgreSQL.
.package(url: "https://github.com/vapor/fluent-postgresql.git", from: "1.0.0"),
.package(url: "https://github.com/vapor/sql.git", from: "2.1.0")
],
targets: [
.target(name: "App", dependencies: ["FluentPostgreSQL", "Vapor"]),
.target(name: "Run", dependencies: ["App"]),
.testTarget(name: "AppTests", dependencies: ["App"])
]
)
How can I get PostgreSQL hooked up to my Vapor 3 app on Heroku?
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)!
:D
The original error is the key here, in particular: SSL off
.
This error is thrown by Heroku Postgres when the client is attempting to connect without SSL. Not familiar with Vapor myself, but a quick look around suggests that configure.swift is where you can make configuration changes. Once you enable SSL from the client, you should be able to connect to this database instance without issue.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With