使用Docker Compose部署全栈应用时API无法连接PostgreSQL数据库
Docker Compose部署全栈应用时API无法连接PostgreSQL的问题
在Docker Compose部署全栈应用过程中,API无法连接PostgreSQL数据库。已配置DATABASE_URL且该配置在其他设备可正常运行,尝试将localhost改为db、更换端口等操作均无效。以下是相关配置信息及问题排查方案:
.env文件内容
JWT_SECRET="palavrasecreta" NODE_ENV=production DATABASE_URL=postgres://postgres:1234@db:5432/postgres
docker-compose.yml配置
version: "3" services: app-front-end: build: charllenger-front/. container_name: front-end-ui expose: - 3000 ports: - 3000:3000 links: - api api: container_name: charllenger-back-end-Api build: Full-Stack-charlenger-API/. volumes: - ./src:/app/src expose: - 3001 ports: - 3001:3001 depends_on: - db command: bash -c 'yarn migration:run && yarn dev' links: - db db: container_name: charllenger-Api-postgres image: "postgres" env_file: - Full-Stack-charlenger-API/.env expose: - 5432 ports: - 5432:5432
TypeORM DataSource配置
import { DataSource } from "typeorm"; require("dotenv").config(); export const AppDataSource = new DataSource({ type: "postgres", host: "database", // 此处存在配置冲突问题 url: process.env.DATABASE_URL, ssl: process.env.NODE_ENV === "production" ? { rejectUnauthorized: false } : false, synchronize: false, logging: true, entities: process.env.NODE_ENV === "production" ? ["src/entities/*.js"] : ["src/entities/*.ts"], migrations: process.env.NODE_ENV === "production" ? ["src/migrations/*.js"] : ["src/migrations/*.ts"], }); AppDataSource.initialize() .then(() => { console.log("Data Source Initialized"); }) .catch((err) => { console.error("Error during data source Initialization", err); } );
Migration文件内容
import { MigrationInterface, QueryRunner } from "typeorm"; export class initialMigration1673714934213 implements MigrationInterface { name = 'initialMigration1673714934213' public async up(queryRunner: QueryRunner): Promise<void> { await queryRunner.query(`CREATE TABLE "transaction" ("transaction_id" uuid NOT NULL, "value" numeric NOT NULL, "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "debitedAccountAccountId" uuid, "creditedAccountAccountId" uuid, CONSTRAINT "PK_6e02e5a0a6a7400e1c944d1e946" PRIMARY KEY ("transaction_id"))`); await queryRunner.query(`CREATE TABLE "user" ("user_id" uuid NOT NULL, "username" character varying NOT NULL, "password" character varying NOT NULL, "account" uuid, CONSTRAINT "REL_4ab2df0a57a74fdf904e0e2708" UNIQUE ("account"), CONSTRAINT "PK_758b8ce7c18b9d347461b30228d" PRIMARY KEY ("user_id"))`); await queryRunner.query(`CREATE TABLE "account" ("account_id" uuid NOT NULL, "balance" double precision NOT NULL, CONSTRAINT "PK_ea08b54a9d7322975ffc57fc612" PRIMARY KEY ("account_id"))`); await queryRunner.query(`ALTER TABLE "transaction" ADD CONSTRAINT "FK_bbbfcdb3330cc4e5846f2d23200" FOREIGN KEY ("debitedAccountAccountId") REFERENCES "account"("account_id") ON DELETE NO ACTION ON UPDATE NO ACTION`); await queryRunner.query(`ALTER TABLE "transaction" ADD CONSTRAINT "FK_4ece0117a7c2689832bab37209b" FOREIGN KEY ("creditedAccountAccountId") REFERENCES "account"("account_id") ON DELETE NO ACTION ON UPDATE NO ACTION`); await queryRunner.query(`ALTER TABLE "user" ADD CONSTRAINT "FK_4ab2df0a57a74fdf904e0e27086" FOREIGN KEY ("account") REFERENCES "account"("account_id") ON DELETE NO ACTION ON UPDATE NO ACTION`); } public async down(queryRunner: QueryRunner): Promise<void> { await queryRunner.query(`ALTER TABLE "user" DROP CONSTRAINT "FK_4ab2df0a57a74fdf904e0e27086"`); await queryRunner.query(`ALTER TABLE "transaction" DROP CONSTRAINT "FK_4ece0117a7c2689832bab37209b"`); await queryRunner.query(`ALTER TABLE "transaction" DROP CONSTRAINT "FK_bbbfcdb3330cc4e5846f2d23200"`); await queryRunner.query(`DROP TABLE "account"`); await queryRunner.query(`DROP TABLE "user"`); await queryRunner.query(`DROP TABLE "transaction"`); } }
报错信息
无法连接到数据库,提示连接超时,目标地址为database:5432(与DATABASE_URL中的db:5432不匹配)。
解决方案
1. 修复DataSource的连接配置冲突
TypeORM中同时设置host和url会导致参数冲突,优先使用单独的host配置。解决方式二选一:
- 删除
host: "database"这一行,完全通过DATABASE_URL指定连接信息; - 将
host值改为"db",与docker-compose中PostgreSQL服务的名称一致。
2. 确保PostgreSQL服务就绪后再启动API
depends_on仅保证容器启动顺序,不保证PostgreSQL服务完全就绪。可以:
- 在API的启动命令中添加等待脚本,比如使用
pg_isready检查数据库状态:command: bash -c 'until pg_isready -h db -p 5432 -U postgres; do sleep 1; done; yarn migration:run && yarn dev' - 为PostgreSQL服务添加健康检查,让docker-compose等待服务就绪后再启动API:
db: # ...其他配置 healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres"] interval: 5s timeout: 5s retries: 5 api: # ...其他配置 depends_on: db: condition: service_healthy
3. 验证环境变量加载
在API容器启动命令中添加环境变量打印,确认DATABASE_URL是否正确加载:
command: bash -c 'echo $DATABASE_URL; yarn migration:run && yarn dev'
4. 补充PostgreSQL必要环境变量
postgres官方镜像需要POSTGRES_USER、POSTGRES_PASSWORD、POSTGRES_DB这三个环境变量才能正确初始化数据库。可以在.env文件中添加:
POSTGRES_USER=postgres POSTGRES_PASSWORD=1234 POSTGRES_DB=postgres
内容的提问来源于stack exchange,提问作者Luiz Paulo Reis Cardoso
相关产品推荐
相关产品推荐

