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

GCE实例中Docker-Compose部署的Django无法连接Cloud SQL PostgreSQL

问题:GCE上Docker Compose部署的Django无法连接Cloud SQL

环境配置

docker-compose.yml

version: "3"
services:

  app:
    restart: always
    command: ./startup.sh
    image: region-docker.pkg.dev/project_id/repo/image:tag
    container_name: backend
    expose:
      - "8000"
    volumes:
      - static_volume:/code/static
    hostname: app

  nginx:
    restart: always
    image: region-docker.pkg.dev/project_id/repo/image:tag
    volumes:
      - static_volume:/code/static
    ports:
      - "80:80" 
    depends_on:
      - app

volumes:
  static_volume:

Django settings.py 数据库配置

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'Instance': 'project_id:region:instance_name',
        'NAME': 'database_name', 
        'USER': 'username', 
        'PASSWORD': 'password',
        'HOST': 'database_internal_IP', 
        'PORT': '5432',
    }
}

报错信息

django.db.utils.OperationalError: could not connect to server: Connection timed out
backend  |      Is the server running on host "instance-private-IP" and accepting
backend  |      TCP/IP connections on port 5432?

已知条件

  • GCE实例本地执行psql -h instance-private-IP -U username可成功连接数据库
  • 本地电脑使用相同容器配置(替换私有IP为公有IP)运行正常
  • GCE实例绑定的服务账号已启用Cloud SQL访问权限

解决方案

方案1:使用Cloud SQL Auth Proxy(推荐,符合GCP安全最佳实践)

通过Cloud SQL Auth Proxy处理数据库连接,无需让Django容器直接访问Cloud SQL私有IP,依赖GCE服务账号权限即可工作。

修改docker-compose.yml,添加cloudsql-proxy服务:

version: "3"
services:
  cloudsql-proxy:
    image: gcr.io/cloudsql-docker/gce-proxy:1.33.1
    command: /cloud_sql_proxy -instances=project_id:region:instance_name=tcp:5432
    restart: always
    volumes:
      - /var/run/cloudsql:/var/run/cloudsql

  app:
    restart: always
    command: ./startup.sh
    image: region-docker.pkg.dev/project_id/repo/image:tag
    container_name: backend
    expose:
      - "8000"
    volumes:
      - static_volume:/code/static
    hostname: app
    depends_on:
      - cloudsql-proxy
    environment:
      - DB_HOST=cloudsql-proxy

  nginx:
    restart: always
    image: region-docker.pkg.dev/project_id/repo/image:tag
    volumes:
      - static_volume:/code/static
    ports:
      - "80:80" 
    depends_on:
      - app

volumes:
  static_volume:

修改Django settings.py 的数据库配置,通过环境变量读取代理地址:

import os

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'database_name', 
        'USER': 'username', 
        'PASSWORD': 'password',
        'HOST': os.getenv('DB_HOST', 'cloudsql-proxy'), 
        'PORT': '5432',
    }
}

方案2:让Django容器使用主机网络模式

让容器共享GCE实例的网络栈,这样容器就能像实例本身一样访问Cloud SQL私有IP。

修改docker-compose.yml中app服务的配置:

app:
    restart: always
    command: ./startup.sh
    image: region-docker.pkg.dev/project_id/repo/image:tag
    container_name: backend
    expose:
      - "8000"
    volumes:
      - static_volume:/code/static
    hostname: app
    network_mode: host  # 添加此行

注意:该方式会降低容器网络隔离性,可能引发端口冲突问题,仅作为临时解决方案。

方案3:授权Docker网段访问Cloud SQL

在Cloud SQL实例的「连接」设置中,添加Docker默认网段(通常为172.17.0.0/16)到授权网络列表,允许该网段访问5432端口。

注意:此方式安全性较低,不推荐生产环境使用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 23:15:50