You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker Compose部署Python+PostgreSQL应用时遭遇psycopg2.OperationalError: fe_sendauth: no password supplied错误

Docker Compose部署Python+PostgreSQL应用时遭遇psycopg2.OperationalError: fe_sendauth: no password supplied错误

看起来你遇到的核心问题是Python应用容器没有正确读取到.env里的数据库密码,或者PostgreSQL容器初始化时没有使用正确的密码创建用户,导致连接时报密码未提供的错误。我来一步步帮你排查解决:

1. 确保Python应用容器能获取到.env中的环境变量

你当前的docker-compose.yml里,app服务没有配置env_file,导致容器内无法读取到.env文件的变量——虽然代码里用了load_dotenv,但本地路径和容器内路径不匹配,大概率找不到文件。

修改docker-compose.yml的app服务,添加env_file配置:

app :
  build: ./app/
  container_name: todo-app
  ports:
    - 8002:8000
  links:
    - db
  depends_on:
    - db
  env_file:
    - ./TODO-App/.env  # 这里要和你的.env实际位置匹配,确保路径正确

这样容器启动时会自动加载.env里的所有变量到环境中,代码里直接用os.environ.get()就能读到。

2. 修复PostgreSQL初始化脚本的变量替换问题

你的init.sql里用了${POSTGRES_PASSWORD},但PostgreSQL官方镜像不会自动替换.sql文件中的环境变量——只有.sh脚本才会被shell解析变量。这会导致创建的用户密码是字符串${POSTGRES_PASSWORD},而不是你.env里的Aa123456。

解决方法是把init.sql改成shell脚本:

  1. 创建init.sh文件,内容如下:
#!/bin/bash
set -e

# 使用环境变量执行SQL
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
    CREATE USER IF NOT EXISTS todo_user WITH PASSWORD '$POSTGRES_PASSWORD';
    CREATE DATABASE todo_db WITH OWNER todo_user;
    GRANT ALL PRIVILEGES ON DATABASE todo_db TO todo_user;
    \c todo_db todo_user;
    CREATE TABLE tasks(
        id SERIAL PRIMARY KEY,
        task VARCHAR NOT NULL,
        status VARCHAR NOT NULL  # 注意你原来写的是ststus,这里修正了拼写错误
    );
EOSQL
  1. 修改PostgreSQL的Dockerfile,复制并赋予脚本执行权限:
FROM postgres:latest
WORKDIR /app
COPY init.sh /docker-entrypoint-initdb.d/init.sh
RUN chmod +x /docker-entrypoint-initdb.d/init.sh
EXPOSE 5432
CMD [ "postgres" ]

3. 确保PostgreSQL容器正确读取.env变量

同样,给db服务也加上env_file配置,确保它能读取到同一个.env文件的变量:

db:
  build: ./database/
  container_name: todo-db
  env_file:
    - ./TODO-App/.env
  restart: always
  ports:
    - 5432:5432
  volumes:
    - ./database/data:/var/lib/postgresql/data

4. 调试变量读取情况(可选但有用)

在Python代码里添加打印语句,确认变量是否正确读取:

import os

# 打印读取到的变量,方便调试
print(f"POSTGRES_USER: {os.environ.get('POSTGRES_USER')}")
print(f"POSTGRES_PASSWORD: {os.environ.get('POSTGRES_PASSWORD')}")
print(f"POSTGRES_DB: {os.environ.get('POSTGRES_DB')}")

启动容器后看日志,如果这些变量是空的,说明.env路径配置有问题。

5. 清理旧数据卷,重新初始化

因为你之前可能已经创建了PostgreSQL的数据卷,旧的用户和数据库配置还在,所以需要彻底清理后重新构建:

docker-compose down -v
docker-compose up --build

-v参数会删除所有关联的数据卷,确保PostgreSQL重新执行初始化脚本。

备注:内容来源于stack exchange,提问作者Dvir Horev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.23 10:59:12