Skip to content

504 Gateway Timeout 错误

当 Coolify 代理无法在配置的超时期限内从您的应用程序获得响应时,就会发生 Gateway Timeout 错误。这与 Bad Gateway (502) 错误不同,后者表示代理根本无法连接到您的应用程序。

常见原因

在 Coolify 中,导致 504 Gateway Timeout 错误的主要有两种场景:

  1. 自定义 Docker 网络隔离 - 代理无法访问使用自定义网络的应用程序
  2. 大型上传/下载超时 - 默认超时设置对于大文件传输来说太短

问题 1:自定义 Docker 网络隔离

症状

  • 应用程序在部署后最初可以正常工作
  • 几小时或几天后出现 504 Gateway Timeout 错误
  • 应用程序可以通过直接 IP 和端口访问(需要手动端口映射)
  • 重新启动应用程序可以暂时解决问题
  • 配置中使用了自定义 Docker 网络

根本原因

当您在 Docker Compose 文件中定义自定义 Docker 网络时,coolify-proxy 容器在 Coolify 自己的网络中运行,而您的应用程序在自定义网络中运行。这种网络隔离会阻止代理访问您的应用程序,特别是当 Docker 的内部 DNS 基于时间和网络加入返回不同的 IP 时。

诊断

  1. 检查您的应用程序是否使用自定义网络:

    bash
    docker inspect <your-container-name> --format='{{range $k,$v := .NetworkSettings.Networks}}Network: {{$k}}, IP: {{$v.IPAddress}}, Gateway: {{$v.Gateway}}{{println}}{{end}}'
  2. 验证代理网络连接:

    bash
    docker inspect coolify-proxy --format='{{range $k,$v := .NetworkSettings.Networks}}Network: {{$k}}, IP: {{$v.IPAddress}}, Gateway: {{$v.Gateway}}{{println}}{{end}}'

解决方案

解决方案 1:使用 Coolify 目标(推荐)

让 Coolify 通过使用 目标 而不是自定义网络自动管理网络:

  1. 从 Docker Compose 文件中移除自定义网络定义
  2. 在 Coolify UI 的目标配置网络目标
  3. 将您的应用程序/服务移动到所需的目标
  4. 重新部署

修改前(有问题):

yaml
services:
  app:
    image: myapp:latest
    networks:
      - custom-network

networks:
  custom-network:
    driver: bridge

修改后(推荐):

yaml
services:
  app:
    image: myapp:latest
    # 让 Coolify 处理网络

解决方案 2:手动网络连接(临时)

如果您必须使用自定义网络,请手动连接代理:

bash
docker network connect <your-network-name> coolify-proxy

注意: 这是一个临时解决方案,可能需要在代理重启后重新应用。

问题 2:大型上传/下载超时

症状

  • 上传大文件(>100MB)时出现 504 错误
  • 向注册表推送大型 Docker 镜像时出现 504 错误
  • 长时间运行的请求(Traefik/Nginx 超过 60 秒)期间出现 504 错误
  • 小文件和快速请求可以正常工作

根本原因

默认超时行为取决于您使用的代理:

  • Traefik:默认读取超时为 60 秒
  • Caddy:无默认超时(请求可以无限期运行)
  • Nginx(一键式数据库):默认超时为 60 秒

任何超过配置超时的请求都会导致 504 Gateway Timeout 错误,即使后端应用程序仍在处理该请求。

诊断

  1. 检查您使用的是哪种代理:

    • 在 Coolify UI 中导航至 服务器 > [您的服务器] > 代理
    • 将显示代理类型(Traefik、Caddy 等)
  2. 检查当前代理配置:

    • 导航至 服务器 > [您的服务器] > 代理 并查找任何超时设置
    • 检查您的应用程序/服务中可能覆盖默认值的自定义标签
  3. 监控应用程序日志中的请求持续时间:

    • 在 Coolify 中导航至您的应用程序/服务日志
    • 查找超过 60 秒的长时间运行的请求
  4. 使用较小的文件测试以确认与大小相关

解决方案

解决方案 1:增加代理超时

配置方法取决于您的代理类型:

对于 Traefik(默认代理)

添加自定义 Traefik 配置以增加超时。根据您的需求,您有多种选择来实现这一点:

  1. 在 Coolify 中导航至您的应用程序设置
  2. 容器标签中添加以下内容:
yaml
# 5分钟超时
traefik.http.services.<service-name>.loadbalancer.timeout.read=300s
traefik.http.services.<service-name>.loadbalancer.timeout.write=300s
traefik.http.services.<service-name>.loadbalancer.timeout.idle=300s

或者导航至服务器的代理设置,并在命令部分下添加全局超时:

yaml
command:
  - "--entrypoints.https.transport.respondingTimeouts.readTimeout=5m"
  - "--entrypoints.https.transport.respondingTimeouts.writeTimeout=5m"
  - "--entrypoints.https.transport.respondingTimeouts.idleTimeout=5m"

官方文档 ↗ 中了解有关 Traefik 超时的更多信息。

对于 Caddy

由于 Caddy 没有默认超时,您通常不会遇到超时问题。但是,如果您需要设置超时(出于安全或资源管理目的):

  1. 在 Coolify 的容器标签中添加以下内容:
yaml
# 设置5分钟超时(300秒)
caddy.servers.timeouts.read_body=300s
caddy.servers.timeouts.read_header=300s
caddy.servers.timeouts.write=300s
caddy.servers.timeouts.idle=5m

官方文档 ↗ 中了解有关 Caddy 超时的更多信息。

对于 Nginx(一键式数据库)

无法直接修改 Coolify 中一键式数据库的 Nginx 配置。相反,请完全绕过 Nginx 以避免超时问题:

  1. 在 Coolify 中导航至您的数据库设置
  2. 禁用"使其公开可用?"选项
  3. 改为使用端口映射直接公开数据库端口并重新启动数据库
  4. 这会直接从容器映射端口,绕过 Nginx 及其超时限制

示例: 对于 PostgreSQL 数据库,映射端口 5432:5432 以直接访问它,而没有任何代理超时。

在此处了解有关公共数据库访问的更多信息:一键式数据库

解决方案 2:实现分块上传

对于非常大的文件,请考虑在您的应用程序中实现分块上传:

  1. 在客户端将大文件分成较小的块
  2. 单独上传块(每个都在超时限制内)
  3. 在服务器端重新组装

解决方案 3:使用后台处理

对于长时间运行的操作:

  1. 接受请求并立即返回作业 ID
  2. 在后台处理请求
  3. 提供检查作业状态的端点

快速诊断清单

运行以下步骤来识别您的具体问题:

  1. 检查错误代码:

  2. 检查时间:

    • 立即 = 可能是网络/配置问题
    • 大约 60 秒后 = 可能是超时问题
    • 几小时/天后随机出现 = 可能是网络隔离问题
  3. 检查网络配置:

    bash
    # 列出所有 Docker 网络
    docker network ls
    
    # 检查容器使用的网络
    docker ps --format "table {{.Names}}\t{{.Networks}}"

预防提示

  1. 避免自定义 Docker 网络,除非绝对必要
  2. 在初始设置期间为应用程序的需求设置适当的超时
  3. 实施健康检查以维持连接
  4. 定期监控代理日志以查找超时模式
  5. 为长时间运行的操作使用进度指示器以防止客户端超时

支持

如果这些解决方案不能解决您的网关超时问题:

  1. 收集诊断信息:

    bash
    # 保存此输出
    docker ps --format "table {{.Names}}\t{{.Networks}}\t{{.Status}}"
    docker logs coolify-proxy --tail 200 > proxy-logs.txt
    docker logs <your-container-name> --tail 200 > app-logs.txt
  2. 加入我们的Discord 社区 ↗

  3. 分享您的配置、日志和您已经尝试过的具体步骤