Docker Compose中PostgreSQL健康检查无法保障.NET服务初始化问题
PostgreSQL容器与.NET微服务初始化连接问题排查
问题背景
我是Docker新手,正在搭建基于.NET的微服务应用,用Docker容器运行,其中包含PostgreSQL数据库容器。配置了docker-compose.yml和docker-compose.override.yml,本以为discountdb的健康检查能确保PostgreSQL连接正常,让.NET服务完成数据库初始化(seed),但执行启动命令后,查看discountdb日志发现数据库启动后又重启了,服务无法正常连接数据库。
配置文件
docker-compose.yml
version: '3.4' services: catalogdb: image: mongo basketdb: image: redis:alpine discountdb: image: postgres portainer: image: portainer/portainer-ce catalog.api: image: ${DOCKER_REGISTRY-}catalogapi build: context: . dockerfile: Services/Catalog/Catalog.API/Dockerfile basket.api: image: ${DOCKER_REGISTRY-}basketapi build: context: . dockerfile: Services/Basket/Basket.API/Dockerfile discount.api: image: ${DOCKER_REGISTRY-}discountapi build: context: . dockerfile: Services/Discount/Discount.API/Dockerfile volumes: mongo_data: portainer_data: postgres_data:
docker-compose.override.yml
version: '3.4' services: catalogdb: container_name: catalogdb restart: always ports: - "27018:27017" volumes: - mongo_data:/data/db basketdb: container_name: basketdb restart: always ports: - "6379:6379" discountdb: container_name: discountdb restart: always ports: - "5430:5432" command: postgres environment: - POSTGRES_USER=admin - POSTGRES_PASSWORD=admin1234 - POSTGRES_DB=DiscountDb healthcheck: test: [ "CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}" ] interval: 10s timeout: 5s retries: 5 volumes: - postgres_data:/var/lib/postgesql/data/ portainer: container_name: portainer restart: always ports: - "8080:8000" - "9000:9000" volumes: - /var/run/docker.sock:/var/run/docker.sock - portainer_data:/data catalog.api: container_name: catalog.api environment: - ASPNETCORE_ENVIRONMENT=Development - "DatabaseSettings:ConnectionString=mongodb://catalogdb:27017" depends_on: - catalogdb ports: - "8000:80" basket.api: container_name: basket.api environment: - ASPNETCORE_ENVIRONMENT=Development - "CacheSettings:ConnectionString=basketdb:6379" depends_on: - basketdb ports: - "8001:80" discount.api: container_name: discount.api environment: - ASPNETCORE_ENVIRONMENT=Development - "DatabaseSettings:ConnectionString=Server=discountdb;Port=5430;Database=DiscountDb;User Id=admin;Password=admin1234;" depends_on: - discountdb ports: - "8002:80"
启动命令
docker-compose -f docker-compose.yml -f .\docker-compose.override.yml up -d
discountdb日志
This user must also own the server process. The database cluster will be initialized with locale "en_US.utf8". The default database encoding has accordingly been set to "UTF8". The default text search configuration will be set to "english". Data page checksums are disabled. fixing permissions on existing directory /var/lib/postgresql/data ... ok creating subdirectories ... ok selecting dynamic shared memory implementation ... posix selecting default max_connections ... 100 selecting default shared_buffers ... 128MB selecting default time zone ... Etc/UTC creating configuration files ... ok running bootstrap script ... ok performing post-bootstrap initialization ... ok initdb: warning: enabling "trust" authentication for local connections initdb: hint: You can change this by editing pg_hba.conf or using the option -A, or --auth-local and --auth-host, the next time you run initdb. syncing data to disk ... ok Success. You can now start the database server using: pg_ctl -D /var/lib/postgresql/data -l logfile start waiting for server to start....2023-05-18 01:47:02.074 UTC [48] LOG: starting PostgreSQL 15.3 (Debian 15.3-1.pgdg110+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit 2023-05-18 01:47:02.076 UTC [48] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432" 2023-05-18 01:47:02.083 UTC [51] LOG: database system was shut down at 2023-05-18 01:47:01 UTC 2023-05-18 01:47:02.090 UTC [48] LOG: database system is ready to accept connections done server started CREATE DATABASE /usr/local/bin/docker-entrypoint.sh: ignoring /docker-entrypoint-initdb.d/* waiting for server to shut down....2023-05-18 01:47:02.289 UTC [48] LOG: received fast shutdown request 2023-05-18 01:47:02.291 UTC [48] LOG: aborting any active transactions 2023-05-18 01:47:02.293 UTC [48] LOG: background worker "logical replication launcher" (PID 54) exited with exit code 1 2023-05-18 01:47:02.293 UTC [49] LOG: shutting down 2023-05-18 01:47:02.295 UTC [49] LOG: checkpoint starting: shutdown immediate 2023-05-18 01:47:02.370 UTC [49] LOG: checkpoint complete: wrote 918 buffers (5.6%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.015 s, sync=0.054 s, total=0.077 s; sync files=250, longest=0.003 s, average=0.001 s; distance=4217 kB, estimate=4217 kB 2023-05-18 01:47:02.377 UTC [48] LOG: database system is shut down done server stopped PostgreSQL init process complete; ready for start up. 2023-05-18 01:47:02.414 UTC [1] LOG: starting PostgreSQL 15.3 (Debian 15.3-1.pgdg110+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit 2023-05-18 01:47:02.414 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432 2023-05-18 01:47:02.414 UTC [1] LOG: listening on IPv6 address "::", port 5432 2023-05-18 01:47:02.418 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432" 2023-05-18 01:47:02.424 UTC [64] LOG: database system was shut down at 2023-05-18 01:47:02 UTC 2023-05-18 01:47:02.429 UTC [1] LOG: database system is ready to accept connections
问题排查与解决
1. 数据卷路径拼写错误
在docker-compose.override.yml的discountdb配置中,数据卷挂载路径写错了:
# 错误路径 - postgres_data:/var/lib/postgesql/data/ # 正确路径(补全缺失的r) - postgres_data:/var/lib/postgresql/data/
路径错误会导致容器无法正确初始化数据目录,触发数据库重启。
2. 服务依赖未关联健康检查
当前discount.api的depends_on仅等待discountdb容器启动,不等待数据库健康检查通过。需要修改为:
discount.api: # ...其他配置 depends_on: discountdb: condition: service_healthy
这样服务会等待数据库完全就绪后再启动,避免初始化时连接失败。
3. 容器间连接端口错误
discount.api的连接字符串中使用了宿主映射的端口5430,但容器内部PostgreSQL运行在5432端口,容器间通信应使用内部端口:
discount.api: environment: # ...其他配置 - "DatabaseSettings:ConnectionString=Server=discountdb;Port=5432;Database=DiscountDb;User Id=admin;Password=admin1234;"
修复后重启
修改完成后,重新执行启动命令:
docker-compose -f docker-compose.yml -f .\docker-compose.override.yml up -d --force-recreate
添加--force-recreate确保容器使用新配置重建。
内容的提问来源于stack exchange,提问作者Jamie
相关产品推荐
相关产品推荐

