如何解决NestJS部署Heroku时出现的no pg_hba.conf entry for host错误
修复Heroku部署NestJS+TypeORM时的PostgreSQL SSL连接错误
问题背景
本地使用SQLite运行NestJS API正常,但部署到Heroku后出现以下错误:
error: no pg_hba.conf entry for host "xx.xxx.xxx.xxx", user "foofoofoof", database "foofoofoof", no encryption
相关配置文件如下:
ormconfig.js
const dbConfig = { synchronize: false, migrations: ['migrations/*.js'], cli: { migrationsDir: 'migrations', }, }; switch(process.env.NODE_ENV){ case 'development': Object.assign(dbConfig, { type: 'sqlite', database: 'db.sqlite', entities: ['**/*.entity.js'], }); break; case 'test': Object.assign(dbConfig, { type: 'sqlite', database: 'test.sqlite', entities: ['**/*.entity.ts'], migrationsRun: true, ssl: { rejectUnauthorized: false } }); break; case 'production': Object.assign(dbConfig, { type: 'postgres', url: process.env.DATABASE_URL, migrationsRun: true, entities: ['**/*.entity.js'], }); break; default: throw new Error('unknown environment') } module.exports = dbConfig;
Procfile
web: npm run start:prod
AppModule配置
import { Module } from '@nestjs/common'; import { ConfigModule } from '@nestjs/config'; import { TypeOrmModule } from '@nestjs/typeorm'; import { AppController } from './app.controller'; import { AppService } from './app.service'; import { IngredientsModule } from './ingredients/ingredients.module'; import { RecipesModule } from './recipes/recipes.module'; import { UsersModule } from './users/users.module'; @Module({ imports: [ ConfigModule.forRoot({ isGlobal: true, envFilePath: `.env.${process.env.NODE_ENV}`, }), TypeOrmModule.forRoot(), UsersModule, IngredientsModule, RecipesModule, ], controllers: [AppController], providers: [AppService], }) export class AppModule {}
package.json脚本部分
"scripts": { "prebuild": "rimraf dist", "build": "nest build", "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", "start": "cross-env NODE_ENV=development nest start", "start:dev": "cross-env NODE_ENV=development nest start --watch", "start:debug": "cross-env NODE_ENV=development nest start --debug --watch", "start:prod": "node dist/main", "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", "test": "cross-env NODE_ENV=test jest", "test:watch": "cross-env NODE_ENV=test jest --watch --maxWorkers=1", "test:cov": "cross-env NODE_ENV=test jest --coverage", "test:debug": "cross-env NODE_ENV=test node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", "test:e2e": "cross-env NODE_ENV=test jest --config ./test/jest-e2e.json --maxWorkers=1", "typeorm": "cross-env NODE_ENV=development node --require ts-node/register ./node_modules/typeorm/cli.js" },
解决方案
错误原因是Heroku的PostgreSQL数据库要求强制SSL连接,但当前生产环境的TypeORM配置中缺少SSL相关设置。只需修改ormconfig.js的生产环境配置,添加SSL参数即可:
修改case 'production'部分的配置:
case 'production': Object.assign(dbConfig, { type: 'postgres', url: process.env.DATABASE_URL, migrationsRun: true, entities: ['**/*.entity.js'], // 添加以下SSL配置 ssl: { rejectUnauthorized: false } }); break;
说明
rejectUnauthorized: false:Heroku的Postgres使用自签名证书,禁用证书校验可以避免连接失败,这是Heroku环境下的标准配置方式。- 确保Heroku环境变量中的
NODE_ENV已设置为production,这样TypeORM才会加载上述生产环境配置。
修改后重新部署到Heroku,即可解决连接错误。
内容的提问来源于stack exchange,提问作者r00k13
相关产品推荐
相关产品推荐

