使用Docker Compose部署FastAPI+PostgreSQL容器遇退出码1错误排查
解决Docker Compose中FastAPI连接PostgreSQL失败(exit code 1)的问题
问题诊断
从错误日志看,核心问题集中在三点:
- FastAPI容器启动后立即尝试连接PostgreSQL,但
depends_on仅保证容器启动顺序,不等待数据库服务完全就绪 .env文件中变量带引号,导致PostgreSQL错误解析数据库名、用户名等配置- 代码存在SQL列名不匹配、注入风险,且硬编码数据库配置未读取环境变量
修复步骤
1. 修正.env文件格式
去掉变量值的引号,否则PostgreSQL会将引号作为名称的一部分,导致连接失败:
POSTGRES_PORT=5432 POSTGRES_DB=testdb POSTGRES_USER=testuser POSTGRES_PASSWORD=testpassword
2. 给FastAPI添加数据库连接重试机制
修改app/database.py,增加重试逻辑等待PostgreSQL服务就绪,同时改用环境变量读取配置:
import os import sys import time import psycopg2 class Database: def __init__(self): self.conn = self.connect() def connect(self): """ 连接数据库,带重试机制 """ print("Connecting to PostgreSQL Database...") retries = 5 delay = 2 while retries > 0: try: conn = psycopg2.connect( host="db", dbname=os.getenv("POSTGRES_DB"), user=os.getenv("POSTGRES_USER"), password=os.getenv("POSTGRES_PASSWORD"), port=os.getenv("POSTGRES_PORT", 5432), ) print("Connected successfully!") return conn except psycopg2.OperationalError as e: retries -= 1 print(f"Connection failed, {retries} retries left. Error: {e}") time.sleep(delay) delay *= 2 print("Failed to connect after retries, exiting.") sys.exit(1) def add_user(self, id, firstname): cur = self.conn.cursor() # 使用参数化查询避免SQL注入,同时匹配表列名 SQL = "INSERT INTO users (uid, firstname) VALUES (%s, %s);" data = (id, firstname) print(data) cur.execute(SQL, data) self.conn.commit() return {"status": "success", "user": {"id": id, "name": firstname}}
3. 修正数据库表与代码的列名匹配
如果要保留代码中的id参数,修改dump-postgres-test.sql的users表结构:
CREATE TABLE users ( id int NULL, firstname varchar NULL ); CREATE TABLE sites ( sid varchar NULL, "location" point NULL );
或者保持SQL表结构不变,修改add_user方法中的SQL语句为uid列(如上面代码所示)。
4. 让FastAPI容器读取环境变量
在compose.yaml的app服务中添加env_file配置,确保应用能读取.env中的变量:
version: '3.8' services: app: build: context: . dockerfile: Dockerfile ports: - "5000:5000" volumes: - .:/app/ depends_on: - db restart: always networks: - testNet env_file: # 添加此行 - .env db: image: "postgres:latest" restart: always expose: - 5432 env_file: - .env volumes: - ./dump-postgres-test.sql:/docker-entrypoint-initdb.d/dummy_dump.sql networks: - testNet networks: testNet:
验证PostgreSQL服务是否正常运行
方法1:进入数据库容器执行查询
- 查看PostgreSQL容器名称:
docker ps - 进入容器并连接数据库:
docker exec -it <你的db容器名称> psql -U testuser -d testdb
- 执行以下命令验证:
- 查看所有表:
\dt - 插入测试数据:
INSERT INTO users (id, firstname) VALUES (1, 'TestUser'); - 查询数据:
SELECT * FROM users;
- 查看所有表:
方法2:通过FastAPI接口测试
启动容器后,访问http://0.0.0.0:5000/users/add?id=99&name=Juan,返回{"status": "success", "user": {"id": 99, "name": "Juan"}}则说明连接正常。
内容的提问来源于stack exchange,提问作者jboat
相关产品推荐
相关产品推荐

