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

在DigitalOcean Droplet部署双应用失败,跨应用连接遇EOF错误求助

跨Docker Compose服务通信异常排查(DigitalOcean Droplet环境)

问题背景

我有两个独立Docker Compose管理的应用,本地部署正常,但放到DigitalOcean Droplet后出现通信故障:

  • Python Flask应用(Gunicorn运行):负责拉取互联网数据存入PostgreSQL,仅接受本地连接,当前运行正常
  • Golang应用:拉取互联网数据后,需请求Flask接口获取数据并存入自身PostgreSQL
  • 异常表现:Golang应用向http://jobs-web:5000或http://jobs:5000发起GET请求时,返回EOF错误

现有Compose文件

Flask应用Compose

web:
    container_name: jobs-web
    build: .
    command:
      [
        "gunicorn",
        "-b",
        "0.0.0.0:5000",
        "app:create_app()",
        "--log-level",
        "debug",
        "--access-logfile",
        "-",
        "--error-logfile",
        "-",
        "--timeout",
        "0",
        "--preload",
      ]
    environment:
      ENABLE_SCHEDULER: ${ENABLE_SCHEDULER}
      FLASK_ENV: production
      SQLALCHEMY_DATABASE_URI: ${SQLALCHEMY_DATABASE_URI}
    volumes:
      - .:/app
    depends_on:
      - db
    networks:
      - fullstack

  db:
    container_name: jobs-db
    image: postgres:16.4-alpine3.20
    restart: always
    environment:
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: ${POSTGRES_DB}
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./init-db.sh:/docker-entrypoint-initdb.d/init-db.sh
      - ./.env:/app/.env
    networks:
      - fullstack

networks:
  fullstack:
    external: true

volumes:
  postgres_data:
  test_postgres_data:

Golang应用Compose

services:
  remoti-db:
    image: postgres:16.4-alpine3.20
    container_name: remoti-db
    ports:
      - 5432:5432
    restart: always
    environment:
      - POSTGRES_DB=${DB_NAME}
      - POSTGRES_USER=${DB_USERNAME}
      - POSTGRES_PASSWORD=${DB_PASSWORD}
    networks:
      - remoti-network
    volumes:
      - database_postgres:/var/lib/postgresql/data
    healthcheck:
      test: [CMD-SHELL, "pg_isready -U ${DB_USERNAME}"]
      interval: 3s
      timeout: 3s
      retries: 5
    expose:
      - "5432"

  app:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: remoti-app
    ports:
      - 4000:4000
    depends_on:
      remoti-db:
        condition: service_healthy
    networks:
      - fullstack
      - remoti-network

  prometheus:
    image: prom/prometheus
    ports:
      - 9090:9090
    volumes:
      - prometheus:/prometheus
      - ./prometheus/development.yml:/etc/prometheus/prometheus.yml
    networks:
      - remoti-network

  grafana:
    image: grafana/grafana
    ports:
      - 3000:3000
    depends_on:
      - prometheus
    networks:
      - remoti-network
    volumes:
      - grafana:/var/lib/grafana
      - ./grafana/provisioning/datasources:/etc/grafana/provisioning/datasources
      - ./grafana/provisioning/dashboards:/etc/grafana/provisioning/dashboards
      - ./grafana/dashboards:/etc/dashboards
      - ./grafana/grafana.ini:/etc/grafana/grafana.ini

  migrations:
    image: migrate/migrate:latest
    env_file:
      - .env
    command: -path /migrations -database ${DSN} up
    volumes:
      - ./migrations:/migrations
    networks:
      - remoti-network
    depends_on:
      remoti-db:
        condition: service_healthy

volumes:
  database_postgres:
  migrations:
  prometheus:
  grafana:

networks:
  fullstack:
    external: true

  remoti-network:
    driver: bridge

排查步骤与解决方案

1. 确认外部网络一致性

两个Compose都声明了external: true的fullstack网络,需确保Droplet上该网络为同一个:

  • 执行docker network ls查看网络ID,确认两个服务连接的fullstack网络ID一致
  • 若不一致,先删除旧网络:docker network rm fullstack,重启Flask应用Compose(会创建外部网络),再启动Golang应用Compose

2. 验证Flask端口可达性

进入Golang应用容器,直接测试Flask服务:

  • 进入容器:docker exec -it remoti-app sh
  • 用curl调试:curl -v http://jobs-web:5000
    • 连接被拒绝:检查Flask容器是否正常启动,确认Gunicorn绑定0.0.0.0:5000(配置已正确),查看容器日志docker logs jobs-web排查启动错误
    • 返回EOF:检查Flask应用日志,看请求处理时是否提前断开连接

3. 检查Droplet防火墙/安全组

DigitalOcean Droplet的防火墙规则可能拦截容器间通信:

  • 放行容器内部网段流量(默认Docker网段为172.17.x.x或自定义网段)
  • 无需对外暴露Flask的5000端口,只需保证内部网络互通

4. 优化服务启动顺序

Flask可能在DB未完全就绪时启动,导致后续请求异常:

  • 给Flask的web服务添加健康检查(需Flask提供健康接口):
    web:
      # ... 其他配置
      healthcheck:
        test: ["CMD", "curl", "-f", "http://localhost:5000/health"]
        interval: 5s
        timeout: 3s
        retries: 3
    
  • Golang应用可添加对Flask服务的依赖:
    app:
      # ... 其他配置
      depends_on:
        remoti-db:
          condition: service_healthy
        jobs-web:
          condition: service_healthy
    

5. 验证容器DNS解析

在Golang容器内测试DNS解析:

  • 执行nslookup jobs-web,确认能解析到Flask容器IP
  • 若解析失败,检查Docker DNS配置,或直接用Flask容器IP测试:curl http://<容器IP>:5000

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 06:50:17