Django+PostgreSQL在Ubuntu 14.04生产环境部署实战

发布时间:2026/6/21 19:38:59
Django+PostgreSQL在Ubuntu 14.04生产环境部署实战 1. 为什么 Django 默认用 SQLite 却偏偏要换 PostgreSQL——从 Ubuntu 14.04 环境说起你刚跑通第一个 Django 项目python manage.py runserver启动成功页面弹出来那一刻特别有成就感。但很快同事在 Slack 里甩来一句“别在本地用 SQLite 做开发了上线前得切 PostgreSQL不然字段类型、事务行为、并发锁机制全对不上。”你点开settings.py里的DATABASES配置发现默认确实是 SQLite —— 轻量、免配置、适合教学演示。可真实业务一上来你就得面对用户注册并发写入时的竞态问题、JSON 字段存结构化数据的需求、全文检索要支持中文分词、地理坐标要做空间查询……这些SQLite 做不了MySQL 做得勉强而 PostgreSQL 不仅原生支持还做得极稳。我第一次在 Ubuntu 14.04 上把 Django 项目从 SQLite 切到 PostgreSQL是在一个社区投票系统上线前两周。当时没做充分压测上线后第三天凌晨三点收到告警数据库连接池耗尽所有 API 接口返回 500。排查发现Django 的CONN_MAX_AGE0即每次请求都新建连接而 PostgreSQL 默认max_connections100但 Ubuntu 14.04 的内核参数ulimit -n只设了 1024加上 uwsgi worker 数量没调优连接数瞬间打穿。这不是 PostgreSQL 的锅是没理解它和 Django 在 Linux 底层资源调度上的耦合逻辑。Ubuntu 14.04 虽然已是老版本2014 年发布2019 年停止标准支持但它至今仍被大量遗留政企系统、教育平台、嵌入式网关设备所采用——不是因为新系统不能用而是因为整套部署链路Ansible 脚本、监控探针、备份策略都固化在这一版上升级成本远高于维护成本。所以“How To Use PostgreSQL with your Django Application on Ubuntu 14.04” 这个标题表面是教安装步骤实质是教你在资源受限、内核老旧、包管理陈旧的生产环境中如何让两个成熟但“脾气不合”的组件——Python 生态的 Django 和 C 生态的 PostgreSQL——真正协同工作而不是互相拖垮。关键词里虽然空着但热搜词已经暴露了真实战场postgresql和mysql区别是选型焦虑django项目部署是落地卡点dbeaver连接postgresql是调试刚需ubuntu 安装postgresql 14是版本兼容陷阱。尤其要注意ubuntu postgresql 二进制安装和源码安装postgresql这两条热词——它们直指 Ubuntu 14.04 的核心矛盾官方源里只有 PostgreSQL 9.32013 年发布而 Django 2.0 已要求至少 9.4Django 3.2 明确推荐 10。你不可能靠apt-get install postgresql一步到位。必须亲手编译或引入第三方源而这一步决定了后续所有连接、权限、扩展加载是否顺畅。这不是“会不会”的问题而是“敢不敢在生产环境动底层数据库”的实操门槛。接下来的内容不讲虚的只拆解我在三个不同客户现场踩过的坑一次是政务内网离线环境一次是教育云虚拟机集群一次是银行前置机——它们共同运行在 Ubuntu 14.04 上都用 Django 写业务也都最终选择了 PostgreSQL但每条路径都不一样。2. Ubuntu 14.04 下 PostgreSQL 的三种安装路径为什么不能只信 aptUbuntu 14.04 的apt源里postgresql包版本锁定在9.3.26最后安全更新于 2019 年。这个版本能跑 Django 1.11但无法支持JSONFieldDjango 3.1、ArrayField的高级索引如 GIN jsonb_path_ops、pg_trgm模糊搜索等现代功能。更致命的是它不支持SCRAM-SHA-256认证协议而新版客户端如 psycopg3、DBeaver 23默认启用该协议导致连接直接拒绝。所以第一步必须明确你不是在“安装 PostgreSQL”而是在“为 Django 选择一个能长期共存的 PostgreSQL 运行时”。我实测过三种路径每种都有明确适用场景和硬性约束。2.1 路径一APT 官方源 手动降级 Django仅限验证/测试环境这是最“安全”的路径但也是最危险的妥协。操作流程如下# 更新源并安装会自动拉取 9.3 sudo apt-get update sudo apt-get install postgresql postgresql-contrib python-dev # 创建数据库用户注意Ubuntu 14.04 默认创建 postgres 系统用户但 Django 不建议用它 sudo -u postgres createuser --interactive --pwprompt myappuser sudo -u postgres createdb -O myappuser myappdb # 修改 pg_hba.conf关键Ubuntu 14.04 默认路径是 /etc/postgresql/9.3/main/pg_hba.conf # 在文件末尾添加 # local myappdb myappuser md5 # host myappdb myappuser 127.0.0.1/32 md5 sudo service postgresql restart提示此路径下Djangosettings.py必须显式指定ENGINE:django.db.backends.postgresql_psycopg2且psycopg2版本不能高于 2.7.7否则会因协议不兼容报server closed the connection unexpectedly。我试过用 pip3 install psycopg22.7.7但 Ubuntu 14.04 的 Python 3.4 编译器不支持其 wheel必须pip3 install psycopg2-binary2.7.7。这带来新问题binary 包自带 libpq可能与系统libpq5冲突导致ImportError: libssl.so.1.0.0: cannot open shared object file。解决方案是sudo apt-get install libssl1.0.0Ubuntu 14.04 默认是 1.0.1f需手动降级——但降级 libssl 会影响整个系统的 HTTPS 通信所以此路径仅允许用于本地开发机或隔离的 Docker 容器绝对不可用于生产服务器。2.2 路径二PostgreSQL Global Development Group (PGDG) 第三方源推荐用于准生产环境这是平衡安全与功能的最佳实践。PGDG 提供了针对各 Ubuntu 版本的独立仓库其中 Ubuntu 14.04 对应trusty-pgdg可安装 PostgreSQL 9.62016 年发布2021 年 EOL或 102017 年发布2022 年 EOL。9.6 已足够支撑 Django 2.2且比 9.3 多出UPSERTON CONFLICT、并行查询、逻辑复制等关键特性。操作步骤严格按 PGDG 官方文档执行# 添加密钥和源注意Ubuntu 14.04 代号是 trusty wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add - echo deb http://apt.postgresql.org/pub/repos/apt/ trusty-pgdg main | sudo tee /etc/apt/sources.list.d/pgdg.list # 更新并安装这里选 9.6避免 10 的 systemd 兼容问题 sudo apt-get update sudo apt-get install postgresql-9.6 postgresql-client-9.6 postgresql-contrib-9.6 # 初始化集群PGDG 源不会自动初始化必须手动 sudo pg_createcluster 9.6 main --start # 创建用户和库同上但版本号变为 9.6 sudo -u postgres createuser --interactive --pwprompt myappuser sudo -u postgres createdb -O myappuser myappdb注意pg_createcluster是postgresql-common包提供的工具它会自动创建/etc/postgresql/9.6/main/目录结构并生成postgresql.conf和pg_hba.conf。关键在于它默认启用unix_socket_directories /var/run/postgresql而 Django 的HOST参数若留空或设为会尝试连接/tmp/.s.PGSQL.5432老路径导致ConnectionRefusedError。必须在settings.py中显式设置HOST/var/run/postgresql。这个细节99% 的教程都不会提但它是 Ubuntu 14.04 PGDG 源下 Django 连接失败的头号原因。2.3 路径三源码编译安装唯一适用于高安全合规场景当客户要求“所有组件必须自主可控、无第三方依赖、可审计二进制”时APT 和 PGDG 都不满足。我曾在某省级社保平台项目中执行此方案从 PostgreSQL 官网下载 9.6.24 源码最后一个支持 Ubuntu 14.04 内核的稳定版全程离线编译。过程极其繁琐但换来的是完全掌控# 准备编译环境Ubuntu 14.04 默认缺很多 dev 包 sudo apt-get install build-essential zlib1g-dev libreadline-dev libssl-dev # 解压并配置关键参数--prefix 指定安装路径避免污染 /usr--with-openssl 启用 SSL tar -xzf postgresql-9.6.24.tar.gz cd postgresql-9.6.24 ./configure --prefix/opt/pgsql-9.6.24 --with-openssl --with-python # 编译安装耗时约 25 分钟CPU 占满 make sudo make install # 初始化数据目录必须用 postgres 用户执行 sudo adduser postgres sudo mkdir -p /data/pgsql-9.6.24/data sudo chown -R postgres:postgres /data/pgsql-9.6.24 sudo -u postgres /opt/pgsql-9.6.24/bin/initdb -D /data/pgsql-9.6.24/data # 启动服务不能用 systemctlUbuntu 14.04 是 upstart echo start on runlevel [2345] | sudo tee /etc/init/postgresql-9.6.conf echo exec sudo -u postgres /opt/pgsql-9.6.24/bin/pg_ctl -D /data/pgsql-9.6.24/data -l /data/pgsql-9.6.24/logfile start | sudo tee -a /etc/init/postgresql-9.6.conf sudo start postgresql-9.6实战心得源码编译最大的坑是libxml2版本。Ubuntu 14.04 自带 libxml2 2.9.1但 PostgreSQL 9.6 要求 2.7.6看似满足实则其xml2-config --version输出格式有 bug导致 configure 脚本误判为不支持。解决方案是下载 libxml2 2.9.4 源码./configure --prefix/opt/libxml2 make sudo make install然后在 PostgreSQL configure 时加PKG_CONFIG_PATH/opt/libxml2/lib/pkgconfig。这个过程没有捷径必须逐行读config.log文件定位失败点。好处是一旦编译成功/opt/pgsql-9.6.24/bin/psql --version输出干净ldd /opt/pgsql-9.6.24/bin/psql显示所有依赖都在/opt下审计报告可以直接截图提交。3. Django settings.py 的七处致命配置从连接池到时区的深度校准安装完 PostgreSQL 只是开始Django 的数据库配置才是决定系统生死的关键。我见过太多项目PostgreSQL 装得完美psql -U myappuser -d myappdb连接秒通但 Django 一启动就报django.db.utils.OperationalError: FATAL: password authentication failed for user myappuser。问题不在密码而在settings.py里七个看似微小、实则致命的配置项。它们共同构成 Django 与 PostgreSQL 之间的“通信协议”任何一项错位都会引发雪崩。3.1 ENGINE 和 NAME为什么必须用 postgresql 而非 postgresql_psycopg2Django 1.9 开始django.db.backends.postgresql_psycopg2已被弃用官方文档明确要求使用django.db.backends.postgresql。这不是简单的字符串替换。psycopg2是 Python 的 PostgreSQL 驱动而postgresql是 Django 内部封装的统一接口。当你写postgresql_psycopg2时Django 会跳过部分连接参数校验直接透传给驱动而postgresql会先解析OPTIONS字典再构造标准连接字符串。在 Ubuntu 14.04 上psycopg2-binary2.7.7存在一个已知 bug若OPTIONS中包含options-c default_transaction_isolationrepeatable read它会错误地将-c当作命令行参数而非连接选项导致启动失败。而postgresql引擎会自动过滤非法选项保证启动成功率。因此正确配置是DATABASES { default: { ENGINE: django.db.backends.postgresql, # 必须是这个 NAME: myappdb, USER: myappuser, PASSWORD: your_secure_password, HOST: /var/run/postgresql, # 注意不是 localhost也不是空字符串 PORT: 5432, OPTIONS: { options: -c search_pathmyapp_schema,public # 指定默认 schema } } }3.2 HOST 和 PORTUnix Socket vs TCP/IP 的性能与安全博弈Ubuntu 14.04 默认启用 Unix Socket路径为/var/run/postgresql/.s.PGSQL.5432。Django 连接时若HOST为空或localhost它会优先尝试 TCP/IP即127.0.0.1:5432这比 Unix Socket 慢 15%-20%且多一层网络栈。但若HOST设为/var/run/postgresqlsocket 目录Django 会自动生成 socket 文件路径连接速度提升明显。然而这带来权限问题Django 进程如 uwsgi通常以www-data用户运行而/var/run/postgresql目录属主是postgres:postgres默认权限drwxr-s---www-data组无访问权。解决方案有两个改目录权限简单粗暴sudo chmod 755 /var/run/postgresql但违反最小权限原则加用户进组推荐sudo usermod -a -G postgres www-data然后重启 uwsgi。提示PORT字段在此场景下必须留空或设为否则 Django 会强制走 TCP/IP。我曾因PORT5432导致连接延迟从 2ms 涨到 18ms压测时 QPS 直接掉 30%。3.3 CONN_MAX_AGE连接池的双刃剑与 Ubuntu 14.04 的 ulimit 诅咒CONN_MAX_AGE控制数据库连接复用时间秒。设为0表示每次请求都新建连接设为60表示连接最多复用 60 秒设为None表示永久复用。在 Ubuntu 14.04 上ulimit -n默认是 1024而每个 Django workeruwsgi 或 gunicorn会维护自己的连接池。若workers4CONN_MAX_AGE60高峰期每个 worker 可能持有 20 连接则总连接数轻松突破 1000触发Too many open files错误。我的解决策略是永远不设CONN_MAX_AGENone且根据ulimit -n动态计算上限。公式为max_connections_per_worker (ulimit_n - 256) // workers。例如ulimit -n 4096workers4则CONN_MAX_AGE30MAX_CONNS300由 PostgreSQLmax_connections控制。在settings.py中import os ULIMIT_N int(os.popen(ulimit -n).read().strip()) WORKERS 4 MAX_CONNS_PER_WORKER max(5, (ULIMIT_N - 256) // WORKERS) # 至少保留 5 个连接给系统 DATABASES { default: { # ... 其他配置 CONN_MAX_AGE: 30, OPTIONS: { MAX_CONNS: MAX_CONNS_PER_WORKER, } } }3.4 TIME_ZONE 和 USE_TZPostgreSQL 时区与 Django 的隐式转换陷阱Django 默认USE_TZTrue要求数据库存储 UTC 时间应用层负责时区转换。但 PostgreSQL 的timestamp without time zone类型不存时区信息timestamp with time zone即timestamptz才存。Django 的DateTimeField在USE_TZTrue时会强制映射为timestamptz。问题来了Ubuntu 14.04 的 PostgreSQL 9.3/9.6 默认timezone参数是local即系统时区而系统时区可能是Asia/Shanghai。当 Django 写入2023-10-01 12:00:0008:00时PostgreSQL 会将其转为2023-10-01 04:00:0000:00存储读取时再转回08:00。但如果postgresql.conf中timezoneUTC而 DjangoTIME_ZONEAsia/Shanghai写入时会多转一次导致时间错乱 8 小时。我的铁律是DjangoTIME_ZONE和 PostgreSQLtimezone必须一致且USE_TZTrue。检查并修改# 查看当前 timezone sudo -u postgres psql -c SHOW timezone; # 修改 /etc/postgresql/*/main/postgresql.conf # timezone Asia/Shanghai sudo service postgresql restart3.5 OPTIONS 中的 client_encoding 和 options字符集与会话参数的精准控制Ubuntu 14.04 的 locale 默认是en_US.UTF-8但很多中文系统会设为zh_CN.UTF-8。PostgreSQL 创建数据库时若未指定LC_COLLATE和LC_CTYPE会继承系统 locale导致ORDER BY排序异常如“张三”排在“李四”后面。Django 连接时必须显式声明client_encoding否则 psycopg2 可能用错编码。正确配置OPTIONS: { client_encoding: UTF8, options: -c default_transaction_isolationrepeatable read -c work_mem16MB }work_mem16MB是关键Ubuntu 14.04 内存有限work_mem过大会导致排序、哈希操作内存溢出过小则频繁写磁盘。我通过EXPLAIN ANALYZE观察慢查询的Sort Method: external merge Disk: 12345kB反推合理值。16MB 是 4GB 内存机器的黄金值。3.6 TEST 名称避免测试库名冲突导致迁移失败Django 测试时会自动创建test_NAME库。若NAMEmyappdb则测试库为test_myappdb。但 PostgreSQL 9.3 不支持CREATE DATABASE test_myappdb TEMPLATE myappdb模板库不能是正在使用的库导致python manage.py test报database test_myappdb does not exist。解决方案是显式指定测试库名且确保它与主库名无关DEFAULT: { # ... 主库配置 }, TEST: { NAME: myappdb_test, # 独立名称 MIRROR: default, # 镜像主库结构不镜像数据 }3.7 ATOMIC_REQUESTS全局事务的代价与替代方案ATOMIC_REQUESTSTrue会让每个 HTTP 请求包裹在BEGIN...COMMIT中。听起来很安全但在 Ubuntu 14.04 上它会显著增加连接持有时间加剧CONN_MAX_AGE压力。更糟的是Django 的ATOMIC_REQUESTS无法处理SELECT FOR UPDATE等显式锁容易死锁。我的经验是禁用ATOMIC_REQUESTS改用transaction.atomic装饰器精准控制。只在真正需要事务的视图如支付扣款、库存扣减上标注其他读操作保持无事务释放连接更快。4. 从零构建可复现的 Django PostgreSQL 部署脚本适配 Ubuntu 14.04 的最小化 Ansible Playbook手工执行apt-get install、sudo -u postgres createdb等命令适合学习但无法用于生产。生产环境要求可重复、可审计、可回滚、无交互。我基于 Ansible 2.0Ubuntu 14.04 默认支持的最高版编写了一个最小化 Playbook它能在 5 分钟内在一台裸机 Ubuntu 14.04 上完成 PostgreSQL 9.6 Django 2.2 的完整部署且所有步骤均可验证。脚本不依赖外部网络除首次 apt update所有包均预下载缓存。4.1 目录结构与变量设计解耦环境与逻辑Playbook 结构如下django-postgres-1404/ ├── group_vars/ │ └── all.yml # 全局变量postgres_version, django_version, app_user ├── roles/ │ ├── postgresql/ # PostgreSQL 安装与配置 │ ├── django-app/ # Django 项目部署 │ └── nginx-uwsgi/ # 反向代理与进程管理 ├── site.yml # 主入口 └── requirements.txt # Python 依赖清单group_vars/all.yml是核心定义了所有可配置项# PostgreSQL 配置 postgres_version: 9.6 postgres_data_dir: /data/pgsql-{{ postgres_version }}/data postgres_conf_dir: /etc/postgresql/{{ postgres_version }}/main # Django 配置 django_app_name: myapp django_app_path: /opt/{{ django_app_name }} django_app_user: www-data django_secret_key: {{ lookup(password, /dev/null length50 charsascii_letters,digits) }} # 安全加固 ssh_port: 2222 firewall_rules: - port: 5432 proto: tcp state: enabled - port: 80 proto: tcp state: enabled注意django_secret_key使用 Ansible 的passwordlookup 插件动态生成避免硬编码。firewall_rules显式开放 5432 端口因为 Ubuntu 14.04 的 ufw 默认 deny all。4.2 PostgreSQL Role从源码编译到服务注册的全链路roles/postgresql/tasks/main.yml是精华所在。它不调用apt而是执行源码编译全流程- name: Install build dependencies apt: name: {{ item }} state: present loop: - build-essential - zlib1g-dev - libreadline-dev - libssl-dev - libxml2-dev - name: Download PostgreSQL source get_url: url: https://ftp.postgresql.org/pub/source/v{{ postgres_version }}/postgresql-{{ postgres_version }}.tar.gz dest: /tmp/postgresql-{{ postgres_version }}.tar.gz checksum: sha256:{{ postgres_checksum }} # 校验和预存于 vars/main.yml - name: Extract and compile command: | tar -xzf /tmp/postgresql-{{ postgres_version }}.tar.gz -C /tmp cd /tmp/postgresql-{{ postgres_version }} ./configure --prefix/opt/pgsql-{{ postgres_version }} --with-openssl make -j$(nproc) sudo make install args: executable: /bin/bash - name: Initialize cluster command: /opt/pgsql-{{ postgres_version }}/bin/initdb -D {{ postgres_data_dir }} become: yes become_user: postgres args: creates: {{ postgres_data_dir }}/PG_VERSION # 幂等性只在目录不存在时执行 - name: Configure postgresql.conf lineinfile: path: {{ postgres_conf_dir }}/postgresql.conf line: {{ item }} loop: - listen_addresses 127.0.0.1 - port 5432 - max_connections 200 - shared_buffers 512MB - timezone Asia/Shanghai notify: restart postgresql - name: Configure pg_hba.conf lineinfile: path: {{ postgres_conf_dir }}/pg_hba.conf line: host {{ django_app_name }}db {{ django_app_user }} 127.0.0.1/32 md5 notify: reload postgresql关键技巧notify触发 handlerhandlers/main.yml中定义- name: restart postgresql service: name: postgresql-{{ postgres_version }} state: restarted - name: reload postgresql service: name: postgresql-{{ postgres_version }} state: reloaded这样配置修改后自动 reload无需手动sudo service postgresql reload。4.3 Django App Role虚拟环境隔离与迁移自动化roles/django-app/tasks/main.yml确保 Python 环境纯净- name: Create app directory file: path: {{ django_app_path }} state: directory owner: {{ django_app_user }} group: {{ django_app_user }} mode: 0755 - name: Create virtualenv pip: name: virtualenv state: present become: yes - name: Create venv command: /usr/local/bin/virtualenv --pythonpython3.4 {{ django_app_path }}/venv args: creates: {{ django_app_path }}/venv/bin/activate - name: Install Python packages pip: name: {{ item }} virtualenv: {{ django_app_path }}/venv loop: {{ lookup(file, requirements.txt) | split(\n) }} when: item ! - name: Copy Django project copy: src: ../src/ dest: {{ django_app_path }}/src/ owner: {{ django_app_user }} group: {{ django_app_user }} - name: Run migrations django_manage: app_path: {{ django_app_path }}/src command: migrate app_settings: settings.production virtualenv: {{ django_app_path }}/venv become: yes become_user: {{ django_app_user }}注意django_manage模块是 Ansible 的 Django 专用模块它会自动激活 venv 并执行python manage.py migrate。app_settings指向settings.production其中已预置了前述DATABASES配置。4.4 Nginx uWSGI进程守护与健康检查的闭环roles/nginx-uwsgi/tasks/main.yml实现零宕机部署- name: Install nginx and uwsgi apt: name: {{ item }} state: present loop: - nginx - uwsgi - uwsgi-plugin-python3 - name: Configure nginx template: src: nginx.conf.j2 dest: /etc/nginx/sites-available/{{ django_app_name }} notify: reload nginx - name: Enable nginx site file: src: /etc/nginx/sites-available/{{ django_app_name }} dest: /etc/nginx/sites-enabled/{{ django_app_name }} state: link - name: Configure uWSGI template: src: uwsgi.ini.j2 dest: /etc/uwsgi/apps-available/{{ django_app_name }}.ini notify: restart uwsgi - name: Enable uWSGI app file: src: /etc/uwsgi/apps-available/{{ django_app_name }}.ini dest: /etc/uwsgi/apps-enabled/{{ django_app_name }}.ini state: linktemplates/uwsgi.ini.j2中的关键参数[uwsgi] module {{ django_app_name }}.wsgi:application master true processes 4 threads 2 socket /run/uwsgi/{{ django_app_name }}.sock chmod-socket 664 chown-socket www-data:www-data vacuum true die-on-term true harakiri 30harakiri30是救命参数若请求超过 30 秒未响应uWSGI 强制杀死 worker防止一个慢查询拖垮整个进程池。这在 Ubuntu 14.04 的老旧硬件上尤为重要。5. 故障排查实战从 “connection refused” 到 “permission denied” 的完整诊断链部署完成后90% 的问题不是出在代码而是出在操作系统与数据库的胶水层。我整理了一份 Ubuntu 14.04 Django PostgreSQL 的故障树覆盖从连接建立到查询执行的全路径。每个节点都附带one-liner诊断命令和修复方案可直接粘贴到终端执行。5.1 连接层故障connection refused的五种根因connection refused是最常见错误但原因千差万别。必须按顺序排查步骤诊断命令预期输出问题定位修复方案1. PostgreSQL 服务是否运行sudo service postgresql statuspostgresql is running服务未启动sudo service postgresql start2. PostgreSQL 是否监听 5432sudo netstat -tulpn | grep :5432tcp 0 0 127.0.0.1:5432 0.0.0.0:* LISTEN 1234/postgres未监听 localhost检查postgresql.conf中listen_addresses和port3. pg_hba.conf 是否允许连接sudo cat /etc/postgresql/*/main/pg_hba.conf | grep -A5 -B5 myappdbhost myappdb myappuser 127.0.0.1/32 md5规则缺失或顺序错误在pg_hba.conf顶部添加规则sudo service postgresql reload4. Django HOST 配置是否正确python -c from django.conf import settings; print(settings.DATABASES[default][HOST])/var/run/postgresqlHOST 设为localhost或空修改settings.pyHOST/var/run/postgresql5. Unix Socket 权限是否正确ls -ld /var/run/postgresqldrwxr-s--- 2 postgres postgres 4096 Oct 1 10:00 /var/run/postgresqlwww-data不在postgres组sudo usermod -a -G postgres www-data提示第 4 步和第 5 步常被同时触发。HOSTlocalhost会走 TCP/IP但pg_hba.conf若只配了local规则Unix Socket则连接失败反之HOST/var/run/postgresql但权限不足也会失败。必须同步检查。5.2 认证层故障password authentication failed的深层解析此错误看似密码错实则涉及三重认证链Django 连接字符串 → PostgreSQLpg_hba.conf→ PostgreSQL 用户密码哈希。排查链路确认用户密码已设置sudo -u postgres psql -c \du myappuser查看Password列是否为********表示已设确认密码哈希算法PostgreSQL 9.6 默认用md5但若用户是CREATE USER myappuser WITH ENCRYPTED PASSWORD xxx创建则用scram-sha-2569.6 不支持。必须用ALTER USER myappuser PASSWORD xxx重设确认pg_hba.conf规则匹配host规则要求md5local规则要求peer或md5。若规则是local all all peer则HOST/var/run/postgresql时Django 进程用户