修复 Gitea PostgreSQL Docker 连接问题 | AI生成和翻译

Home 2026.03

🔧 我如何修复 Gitea ↔ PostgreSQL 连接

错误

The database settings are invalid: dial tcp 172.17.0.1:5433: connect: connection timed out

Gitea(在 Docker 中运行)无法连接到 PostgreSQL(在主机上运行)。有三个独立问题阻塞了它。


问题 1:PostgreSQL 仅监听 localhost

发生的情况: PostgreSQL 的默认配置仅绑定到 127.0.0.1。这意味着它只接受来自主机本身的连接 — 而不是来自 Docker 容器的连接。

如何发现:

sudo ss -tlnp | grep 5433
# 输出显示:127.0.0.1:5433 — 仅 localhost!

修复方法:

# 在 /etc/postgresql/16/main/postgresql.conf 中更改:
# listen_addresses = 'localhost'        ← 旧的(注释掉的默认值)
listen_addresses = '*'                  ← 新(监听所有接口)

现在 PostgreSQL 在 0.0.0.0:5433(所有 IP)接受连接,而不是仅 127.0.0.1

为什么重要: Docker 容器有自己的网络命名空间。从容器内部看,127.0.0.1 是容器本身 — 而不是主机。所以 Docker 内的 localhost ≠ 主机的 localhost


问题 2:Docker 网络不匹配

发生的情况: Gitea 运行在自定义 Docker 网络(gitea_default)上,网关为 172.22.0.1,但 host.docker.internal 解析为 172.17.0.1(默认 docker0 桥接)。

如何发现:

docker inspect gitea --format ': \n'
# 输出:gitea_default: 172.22.0.1

docker exec gitea sh -c "getent hosts host.docker.internal"
# 输出:172.17.0.1  host.docker.internal

Docker Compose 为每个项目创建自己的网络。host.docker.internal 映射使用默认桥接 IP,但来自自定义网络的流量并不总是能干净地路由到默认桥接。

修复方法: 通过将 listen_addresses = '*',PostgreSQL 现在监听所有接口 — 包括自定义 Docker 网络可达的接口。无论哪个 Docker 网络连接,只要流量到达主机的 5433 端口,PostgreSQL 就会接受。


问题 3:iptables 阻塞连接

发生的情况: 即使修复了上述两个问题,连接仍然超时。真正的阻塞者是 iptables — Linux 防火墙悄无声息地丢弃了来自 Docker 到主机 5433 端口的数据包。

如何发现:

# 修复 listen_addresses 后,再试一次:
docker exec gitea sh -c "timeout 3 bash -c 'echo > /dev/tcp/host.docker.internal/5433'"
# 仍然失败

# 然后手动打开端口:
sudo iptables -I INPUT -p tcp --dport 5433 -j ACCEPT
# 再试 → 成功!

Docker 有自己的 iptables 链。当容器尝试连接主机时,数据包会通过主机的 INPUT 链。如果没有规则允许,它就会被丢弃。

永久修复:

sudo ufw allow from 172.16.0.0/12 to any port 5433 proto tcp comment 'postgresql-docker'
部分 含义
from 172.16.0.0/12 仅 Docker 网络(172.16.0.0 – 172.31.255.255)
to any port 5433 PostgreSQL 的端口
proto tcp PostgreSQL 使用 TCP

这比向整个互联网开放 5433 端口更安全 — 只有 Docker 容器才能访问。


修复后的流程

1. 浏览器 → http://192.168.1.36:3000
              ↓
2. Gitea 容器(172.22.0.x)
   将 host.docker.internal 解析为 → 172.17.0.1
              ↓
3. 数据包击中主机的 iptables INPUT 链
   ufw 规则:"allow from 172.16.0.0/12 to port 5433" → ACCEPT ✅
              ↓
4. PostgreSQL 在 0.0.0.0:5433 接收连接
   pg_hba.conf:"allow gitea user from 172.16.0.0/12" → AUTHENTICATE ✅
              ↓
5. Gitea 连接到 DB,安装页面正常工作 🎉

总结

问题 症状 修复
PostgreSQL 仅在 localhost 容器无法访问主机的 loopback listen_addresses = '*'
自定义 Docker 网络 ≠ 桥接 host.docker.internal 解析到错误的网关 已由 listen_addresses = '*' 处理
iptables 丢弃 Docker → 主机流量 连接超时 ufw allow from 172.16.0.0/12 to port 5433

Back Donate