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

Ubuntu环境变量下Express.js连接PostgreSQL认证失败问题排查

问题描述

搭建PERN Stack时出现报错:error: password authentication failed for user "postgres",浏览器显示504网关超时。

环境信息:

  • 系统:Ubuntu 22.04.2
  • PostgreSQL版本:14.8
  • 本地可通过Ubuntu用户ubuntu或postgres,利用环境变量和peer认证登录PostgreSQL,执行psql -d testdb能以ubuntu用户成功登录。当前ubuntu用户的环境变量:
    PGPORT=5432
    PGPASSWORD=password
    PGUSER=ubuntu
    PGDATABASE=testdb
    PGHOST=localhost
    
  • /etc/postgresql/14/main/pg_hba.conf配置:
    # Database administrative login by Unix domain socket
    local   all             postgres                                peer
    
    # TYPE  DATABASE        USER            ADDRESS                 METHOD
    
    # "local" is for Unix domain socket connections only
    local   all             all                                     peer
    # IPv4 local connections:
    host    all             all             127.0.0.1/32            scram-sha-256
    # IPv6 local connections:
    host    all             all             ::1/128                 scram-sha-256
    # Allow replication connections from localhost, by a user with the
    # replication privilege.
    local   replication     all                                     peer
    host    replication     all             127.0.0.1/32            scram-sha-256
    host    replication     all             ::1/128                 scram-sha-256
    

疑问:是否需要配置Ubuntu用户www-data的环境变量以访问PostgreSQL?问题出在哪里?


问题分析与解决

核心问题

  1. 连接身份不匹配:错误提示是postgres用户认证失败,但你的环境变量指定的是PGUSER=ubuntu,说明Express应用要么没读取到你的环境变量,要么连接代码里硬编码了postgres用户。
  2. 环境变量隔离:Express默认以www-data用户运行(Web服务进程用户),而你配置的PG环境变量属于ubuntu用户,www-data无法读取这些变量。
  3. 连接方式与认证规则不匹配:你的pg_hba.conf里,TCP连接(localhost)需要密码认证,Unix套接字连接需要peer认证(系统用户与DB用户同名),Express的连接方式可能和当前认证规则不兼容。

解决步骤

1. 检查Express连接代码

确认代码中是否正确使用环境变量,而非硬编码用户:

// 正确示例:使用环境变量
const { Pool } = require('pg');
const pool = new Pool({
  user: process.env.PGUSER,
  host: process.env.PGHOST,
  database: process.env.PGDATABASE,
  password: process.env.PGPASSWORD,
  port: process.env.PGPORT,
});

如果代码里写死了user: 'postgres',改成对应正确的用户或使用环境变量。

2. 让www-data获取PG环境变量

方法一:全局环境变量配置

编辑/etc/environment文件,添加PG相关变量:

PGPORT=5432
PGPASSWORD=password
PGUSER=ubuntu
PGDATABASE=testdb
PGHOST=localhost

重启系统或Express服务,让环境变量生效。

方法二:在启动脚本中指定

如果用PM2管理服务,在ecosystem.config.js中配置环境变量:

module.exports = {
  apps: [{
    name: 'your-pern-app',
    script: 'app.js',
    env: {
      PGPORT: 5432,
      PGPASSWORD: 'password',
      PGUSER: 'ubuntu',
      PGDATABASE: 'testdb',
      PGHOST: 'localhost'
    }
  }]
};

3. 匹配连接方式与认证规则(二选一)

选项A:保持TCP连接(PGHOST=localhost)

需要确保ubuntu用户有符合scram-sha-256的密码:

# 切换到postgres用户执行
sudo -u postgres psql -c "ALTER USER ubuntu WITH PASSWORD 'password';"
# 重启PostgreSQL生效
sudo systemctl restart postgresql

选项B:使用Unix套接字连接(无需密码)

  • 修改PGHOST为Unix套接字路径:PGHOST=/var/run/postgresql
  • 在PostgreSQL中创建www-data同名用户并授权:
    sudo -u postgres psql -c "CREATE USER \"www-data\";"
    sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE testdb TO \"www-data\";"
    
    这样Express以www-data用户运行时,通过Unix套接字可直接通过peer认证登录。

4. 解决504超时问题

504网关超时是因为Express连接数据库失败导致请求挂起,解决数据库认证问题后,超时问题会自动消失。


内容的提问来源于stack exchange,提问作者STEVE J

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 01:37:03