django-cloud-sql-postgres

Django on Google Cloud SQL PostgreSQL

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "django-cloud-sql-postgres" with this command: npx skills add jezweb/claude-skills/jezweb-claude-skills-django-cloud-sql-postgres

Django on Google Cloud SQL PostgreSQL

Status: Production Ready Last Updated: 2026-01-24 Dependencies: None Latest Versions: Django@5.1 , psycopg2-binary@2.9.9 , gunicorn@23.0.0 , google-cloud-sql-connector@1.12.0

Quick Start (10 Minutes)

  1. Install Dependencies

pip install Django psycopg2-binary gunicorn

For Cloud SQL Python Connector (recommended for local dev):

pip install "cloud-sql-python-connector[pg8000]"

Why this matters:

  • psycopg2-binary is the PostgreSQL adapter for Django

  • gunicorn is required for App Engine Standard (Python 3.10+)

  • Cloud SQL Python Connector provides secure connections without SSH tunneling

  1. Configure Django Settings

settings.py (production with Unix socket):

import os

Detect App Engine environment

IS_APP_ENGINE = os.getenv('GAE_APPLICATION', None)

if IS_APP_ENGINE: # Production: Connect via Unix socket DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': os.environ['DB_NAME'], 'USER': os.environ['DB_USER'], 'PASSWORD': os.environ['DB_PASSWORD'], 'HOST': f"/cloudsql/{os.environ['CLOUD_SQL_CONNECTION_NAME']}", 'PORT': '', # Empty for Unix socket } } else: # Local development: Connect via Cloud SQL Proxy DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': os.environ.get('DB_NAME', 'mydb'), 'USER': os.environ.get('DB_USER', 'postgres'), 'PASSWORD': os.environ.get('DB_PASSWORD', ''), 'HOST': '127.0.0.1', 'PORT': '5432', } }

CRITICAL:

  • App Engine connects via Unix socket at /cloudsql/PROJECT:REGION:INSTANCE

  • Local development requires Cloud SQL Auth Proxy on 127.0.0.1:5432

  • Never hardcode connection strings - use environment variables

  1. Create app.yaml

runtime: python310 entrypoint: gunicorn -b :$PORT myproject.wsgi:application

env_variables: DB_NAME: "mydb" DB_USER: "postgres" CLOUD_SQL_CONNECTION_NAME: "project-id:region:instance-name"

Cloud SQL connection

beta_settings: cloud_sql_instances: "project-id:region:instance-name"

handlers:

  • url: /static static_dir: static/
  • url: /.* script: auto secure: always

CRITICAL:

  • beta_settings.cloud_sql_instances enables the Unix socket at /cloudsql/...

  • DB_PASSWORD should be set via gcloud app deploy or Secret Manager, not in app.yaml

The 6-Step Setup Process

Step 1: Create Cloud SQL Instance

Create PostgreSQL instance

gcloud sql instances create myinstance
--database-version=POSTGRES_15
--tier=db-f1-micro
--region=us-central1

Create database

gcloud sql databases create mydb --instance=myinstance

Create user

gcloud sql users create postgres
--instance=myinstance
--password=YOUR_SECURE_PASSWORD

Key Points:

  • Use POSTGRES_15 or later for best compatibility

  • db-f1-micro is cheapest for dev ($7-10/month), use db-g1-small or higher for production

  • Note the connection name: PROJECT_ID:REGION:INSTANCE_NAME

Step 2: Configure Django Project

requirements.txt:

Django>=5.1,<6.0 psycopg2-binary>=2.9.9 gunicorn>=23.0.0 whitenoise>=6.7.0

settings.py additions:

import os

Security settings for production

DEBUG = os.environ.get('DEBUG', 'False') == 'True' ALLOWED_HOSTS = [ '.appspot.com', '.run.app', 'localhost', '127.0.0.1', ]

Static files with WhiteNoise

STATIC_URL = '/static/' STATIC_ROOT = os.path.join(BASE_DIR, 'static') MIDDLEWARE.insert(1, 'whitenoise.middleware.WhiteNoiseMiddleware') STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'

Database connection pooling

DATABASES['default']['CONN_MAX_AGE'] = 60 # Keep connections open for 60 seconds

Why these settings:

  • CONN_MAX_AGE=60 reduces connection overhead (Cloud SQL has connection limits)

  • WhiteNoise serves static files without Cloud Storage

  • ALLOWED_HOSTS must include .appspot.com for App Engine

Step 3: Set Up Local Development with Cloud SQL Proxy

Install Cloud SQL Auth Proxy:

macOS

brew install cloud-sql-proxy

Linux

curl -o cloud-sql-proxy https://storage.googleapis.com/cloud-sql-connectors/cloud-sql-proxy/v2.14.1/cloud-sql-proxy.linux.amd64 chmod +x cloud-sql-proxy

Run the proxy:

Authenticate first

gcloud auth application-default login

Start proxy (runs on 127.0.0.1:5432)

./cloud-sql-proxy PROJECT_ID:REGION:INSTANCE_NAME

Or with specific port

./cloud-sql-proxy PROJECT_ID:REGION:INSTANCE_NAME --port=5432

Set environment variables for local dev:

export DB_NAME=mydb export DB_USER=postgres export DB_PASSWORD=your_password export DEBUG=True

Key Points:

  • Proxy creates a secure tunnel to Cloud SQL

  • No need to whitelist your IP address

  • Works with both password and IAM authentication

Step 4: Run Migrations

Local (with proxy running)

python manage.py migrate

Verify connection

python manage.py dbshell

For production migrations (via Cloud Build or local with proxy):

Option 1: Run locally with proxy

./cloud-sql-proxy PROJECT:REGION:INSTANCE & python manage.py migrate

Option 2: Use Cloud Build (recommended)

See references/cloud-build-migrations.md

Step 5: Configure Gunicorn

gunicorn.conf.py (optional, for fine-tuning):

import multiprocessing

Workers

workers = 2 # App Engine Standard limits this threads = 4 worker_class = 'gthread'

Timeout (App Engine has 60s limit for standard, 3600s for flexible)

timeout = 55

Logging

accesslog = '-' errorlog = '-' loglevel = 'info'

Bind (App Engine sets $PORT)

bind = f"0.0.0.0:{os.environ.get('PORT', '8080')}"

app.yaml entrypoint options:

Simple (recommended for most cases)

entrypoint: gunicorn -b :$PORT myproject.wsgi:application

With config file

entrypoint: gunicorn -c gunicorn.conf.py myproject.wsgi:application

With workers and timeout

entrypoint: gunicorn -b :$PORT -w 2 -t 55 myproject.wsgi:application

Key Points:

  • App Engine Standard limits workers (F1: 1 worker, F2: 2 workers)

  • Use gthread worker class for I/O-bound Django apps

  • Set timeout < 60s to avoid App Engine killing requests

Step 6: Deploy to App Engine

Collect static files

python manage.py collectstatic --noinput

Deploy

gcloud app deploy app.yaml

Set DB password via environment

gcloud app deploy --set-env-vars="DB_PASSWORD=your_secure_password"

View logs

gcloud app logs tail -s default

Verify deployment:

Open in browser

gcloud app browse

Check database connection

gcloud app logs read --service=default | grep -i database

Critical Rules (Django + Cloud SQL)

ALWAYS DO:

  • Use Unix socket path /cloudsql/PROJECT:REGION:INSTANCE on App Engine

  • Set PORT='' (empty string) for Unix socket connections

  • Use Cloud SQL Auth Proxy for local development

  • Set CONN_MAX_AGE for connection pooling (30-60 seconds)

  • Use environment variables for database credentials

  • Use Secret Manager for production passwords

NEVER DO:

  • Put database password in app.yaml (use Secret Manager or env vars at deploy time)

  • Use HOST='localhost' on App Engine (must use Unix socket path)

  • Forget beta_settings.cloud_sql_instances in app.yaml

  • Set CONN_MAX_AGE=None (unlimited) - can exhaust connection pool

  • Skip SSL on Cloud SQL (it's enforced by default)

Known Issues Prevention

This skill prevents 12 documented issues:

Issue #1: OperationalError - No such file or directory

Error: django.db.utils.OperationalError: could not connect to server: No such file or directory

Source: https://cloud.google.com/sql/docs/postgres/connect-app-engine-standard Why It Happens: App Engine can't find the Unix socket because beta_settings.cloud_sql_instances is missing in app.yaml Prevention: Always include beta_settings.cloud_sql_instances: "PROJECT:REGION:INSTANCE" in app.yaml

Issue #2: Connection Refused on Local Development

Error: django.db.utils.OperationalError: connection refused or could not connect to server: Connection refused

Source: https://cloud.google.com/sql/docs/postgres/connect-auth-proxy Why It Happens: Cloud SQL Auth Proxy is not running or bound to wrong port Prevention: Start cloud-sql-proxy PROJECT:REGION:INSTANCE before running Django locally. Verify it's running on port 5432.

Issue #3: FATAL: password authentication failed

Error: FATAL: password authentication failed for user "postgres"

Source: https://cloud.google.com/sql/docs/postgres/create-manage-users Why It Happens: Wrong password in environment variable, or user doesn't exist in Cloud SQL instance Prevention: Verify password with gcloud sql users list --instance=INSTANCE . Reset if needed: gcloud sql users set-password postgres --instance=INSTANCE --password=NEW_PASSWORD

Issue #4: Too Many Connections

Error: FATAL: too many connections for role "postgres" or remaining connection slots are reserved

Source: https://cloud.google.com/sql/docs/postgres/quotas#connection_limits Why It Happens: Each request opens a new connection without pooling, exhausting the 25-100 connection limit Prevention: Set CONN_MAX_AGE = 60 in Django settings. For high traffic, use PgBouncer or django-db-connection-pool .

Issue #5: App Engine Request Timeout

Error: DeadlineExceededError or request terminated after 60 seconds Source: https://cloud.google.com/appengine/docs/standard/python3/how-requests-are-handled Why It Happens: Database query or migration takes longer than App Engine's 60-second limit Prevention: Set Gunicorn timeout to 55 seconds. For long-running tasks, use Cloud Tasks or Cloud Run Jobs.

Issue #6: Static Files 404 in Production

Error: Static files return 404, CSS/JS not loading Source: https://cloud.google.com/appengine/docs/standard/serving-static-files Why It Happens: Missing static/ handler in app.yaml or collectstatic not run before deploy Prevention: Run python manage.py collectstatic --noinput before deploy. Include static handler in app.yaml.

Issue #7: CSRF Verification Failed

Error: Forbidden (403) CSRF verification failed

Source: Django documentation on CSRF Why It Happens: CSRF_TRUSTED_ORIGINS not set for appspot.com domain Prevention: Add CSRF_TRUSTED_ORIGINS = ['https://*.appspot.com'] to settings.py

Issue #8: Database Not Found After Deployment

Error: django.db.utils.OperationalError: FATAL: database "mydb" does not exist

Source: https://cloud.google.com/sql/docs/postgres/create-manage-databases Why It Happens: Database exists in Cloud SQL but DB_NAME environment variable is wrong Prevention: Verify database name: gcloud sql databases list --instance=INSTANCE . Ensure DB_NAME matches exactly.

Issue #9: IAM Authentication Failure

Error: FATAL: Cloud SQL IAM user authentication failed

Source: https://cloud.google.com/sql/docs/postgres/iam-logins Why It Happens: App Engine service account doesn't have roles/cloudsql.instanceUser role Prevention: Grant role: gcloud projects add-iam-policy-binding PROJECT --member="serviceAccount:PROJECT@appspot.gserviceaccount.com" --role="roles/cloudsql.instanceUser"

Issue #10: Migrations Fail in Production

Error: Migrations timeout or can't run during deployment Source: https://cloud.google.com/sql/docs/postgres/connect-build Why It Happens: App Engine deploy doesn't provide a migration step; running in entrypoint times out Prevention: Run migrations separately via Cloud Build, or locally with Cloud SQL Proxy before deploying.

Issue #11: SECRET_KEY Exposed

Error: Security warning about hardcoded SECRET_KEY Source: Django deployment checklist Why It Happens: SECRET_KEY is in settings.py instead of environment variable or Secret Manager Prevention: Use SECRET_KEY = os.environ.get('SECRET_KEY') and set via gcloud app deploy --set-env-vars or Secret Manager.

Issue #12: Cold Start Database Timeout

Error: First request after idle period times out Source: https://cloud.google.com/appengine/docs/standard/how-instances-are-managed Why It Happens: App Engine instance cold start + Cloud SQL activation delay (if using "on demand" activation) Prevention: Use App Engine warmup requests, or keep Cloud SQL instance "always on" (increases cost). Set app_engine_apis: true and add /_ah/warmup handler.

Configuration Files Reference

settings.py (Complete Production Example)

import os from pathlib import Path

BASE_DIR = Path(file).resolve().parent.parent

Security

SECRET_KEY = os.environ.get('SECRET_KEY', 'dev-key-change-in-production') DEBUG = os.environ.get('DEBUG', 'False') == 'True' ALLOWED_HOSTS = [ '.appspot.com', '.run.app', 'localhost', '127.0.0.1', ]

CSRF for App Engine

CSRF_TRUSTED_ORIGINS = [ 'https://.appspot.com', 'https://.run.app', ]

Application definition

INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', # Your apps here ]

MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'whitenoise.middleware.WhiteNoiseMiddleware', # Static files 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ]

ROOT_URLCONF = 'myproject.urls'

TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [BASE_DIR / 'templates'], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ]

WSGI_APPLICATION = 'myproject.wsgi.application'

Database

IS_APP_ENGINE = os.getenv('GAE_APPLICATION', None)

if IS_APP_ENGINE: DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': os.environ['DB_NAME'], 'USER': os.environ['DB_USER'], 'PASSWORD': os.environ['DB_PASSWORD'], 'HOST': f"/cloudsql/{os.environ['CLOUD_SQL_CONNECTION_NAME']}", 'PORT': '', 'CONN_MAX_AGE': 60, 'OPTIONS': { 'connect_timeout': 10, }, } } else: DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': os.environ.get('DB_NAME', 'mydb'), 'USER': os.environ.get('DB_USER', 'postgres'), 'PASSWORD': os.environ.get('DB_PASSWORD', ''), 'HOST': os.environ.get('DB_HOST', '127.0.0.1'), 'PORT': os.environ.get('DB_PORT', '5432'), 'CONN_MAX_AGE': 60, } }

Static files

STATIC_URL = '/static/' STATIC_ROOT = BASE_DIR / 'static' STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'

Default primary key field type

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

Logging

LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { 'console': { 'class': 'logging.StreamHandler', }, }, 'root': { 'handlers': ['console'], 'level': 'INFO', }, 'loggers': { 'django': { 'handlers': ['console'], 'level': os.getenv('DJANGO_LOG_LEVEL', 'INFO'), 'propagate': False, }, }, }

app.yaml (Complete Example)

runtime: python310 entrypoint: gunicorn -b :$PORT -w 2 -t 55 --threads 4 myproject.wsgi:application

instance_class: F2

env_variables: DB_NAME: "mydb" DB_USER: "postgres" CLOUD_SQL_CONNECTION_NAME: "project-id:us-central1:instance-name" DEBUG: "False"

beta_settings: cloud_sql_instances: "project-id:us-central1:instance-name"

handlers:

  • url: /static static_dir: static/ secure: always

  • url: /.* script: auto secure: always

automatic_scaling: min_instances: 0 max_instances: 2 target_cpu_utilization: 0.65

Why these settings:

  • F2 instance class allows 2 Gunicorn workers

  • min_instances: 0 saves costs when idle

  • target_cpu_utilization: 0.65 scales before overload

requirements.txt

Django>=5.1,<6.0 psycopg2-binary>=2.9.9 gunicorn>=23.0.0 whitenoise>=6.7.0

Common Patterns

Pattern 1: Environment-Aware Database Configuration

import os

def get_database_config(): """Return database config based on environment.""" is_production = os.getenv('GAE_APPLICATION', None)

if is_production:
    return {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': os.environ['DB_NAME'],
        'USER': os.environ['DB_USER'],
        'PASSWORD': os.environ['DB_PASSWORD'],
        'HOST': f"/cloudsql/{os.environ['CLOUD_SQL_CONNECTION_NAME']}",
        'PORT': '',
        'CONN_MAX_AGE': 60,
    }
else:
    return {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': os.environ.get('DB_NAME', 'mydb'),
        'USER': os.environ.get('DB_USER', 'postgres'),
        'PASSWORD': os.environ.get('DB_PASSWORD', ''),
        'HOST': '127.0.0.1',
        'PORT': '5432',
        'CONN_MAX_AGE': 60,
    }

DATABASES = {'default': get_database_config()}

When to use: Standard Django project needing local/production parity

Pattern 2: Secret Manager Integration

from google.cloud import secretmanager

def get_secret(secret_id, version_id='latest'): """Retrieve secret from Google Secret Manager.""" client = secretmanager.SecretManagerServiceClient() project_id = os.environ.get('GOOGLE_CLOUD_PROJECT') name = f"projects/{project_id}/secrets/{secret_id}/versions/{version_id}" response = client.access_secret_version(request={"name": name}) return response.payload.data.decode('UTF-8')

Usage in settings.py

if os.getenv('GAE_APPLICATION'): SECRET_KEY = get_secret('django-secret-key') DB_PASSWORD = get_secret('db-password')

When to use: Production deployments requiring proper secret management

Pattern 3: Cloud SQL Python Connector (Alternative to Proxy)

For local development without Cloud SQL Auth Proxy

from google.cloud.sql.connector import Connector

def get_db_connection(): connector = Connector() return connector.connect( "project:region:instance", "pg8000", user="postgres", password=os.environ["DB_PASSWORD"], db="mydb", )

In settings.py for local dev (requires pg8000 driver)

DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'mydb', 'USER': 'postgres', 'OPTIONS': { 'get_conn': get_db_connection, }, } }

When to use: Local development when you can't install Cloud SQL Auth Proxy

Pattern 4: Health Check Endpoint with Database Verification

views.py

from django.http import JsonResponse from django.db import connection

def health_check(request): """Health check endpoint for App Engine.""" try: with connection.cursor() as cursor: cursor.execute("SELECT 1") return JsonResponse({ 'status': 'healthy', 'database': 'connected', }) except Exception as e: return JsonResponse({ 'status': 'unhealthy', 'database': str(e), }, status=503)

urls.py

urlpatterns = [ path('_ah/health', health_check, name='health_check'), ]

When to use: Load balancer health checks, monitoring database connectivity

Using Bundled Resources

Templates (templates/)

  • templates/settings_snippet.py

  • Copy-paste database configuration

  • templates/app.yaml

  • Complete App Engine configuration

  • templates/requirements.txt

  • Production dependencies

References (references/)

  • references/cloud-sql-proxy-setup.md

  • Detailed proxy installation and usage

  • references/iam-authentication.md

  • IAM-based authentication (no passwords)

  • references/secret-manager.md

  • Storing secrets properly

  • references/migrations-in-production.md

  • Running migrations safely

When Claude should load these:

  • Load cloud-sql-proxy-setup.md when user has local connection issues

  • Load iam-authentication.md when setting up passwordless auth

  • Load migrations-in-production.md before first production deployment

Advanced Topics

IAM Database Authentication

Instead of password authentication, use IAM for service-to-service auth:

Enable IAM authentication on instance

gcloud sql instances patch INSTANCE --database-flags cloudsql.iam_authentication=on

Create IAM user

gcloud sql users create SERVICE_ACCOUNT@PROJECT.iam
--instance=INSTANCE
--type=CLOUD_IAM_SERVICE_ACCOUNT

Grant connect permission

gcloud projects add-iam-policy-binding PROJECT
--member="serviceAccount:PROJECT@appspot.gserviceaccount.com"
--role="roles/cloudsql.instanceUser"

Django settings for IAM auth:

DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': os.environ['DB_NAME'], 'USER': f"{os.environ['SERVICE_ACCOUNT']}@{os.environ['PROJECT_ID']}.iam", 'HOST': f"/cloudsql/{os.environ['CLOUD_SQL_CONNECTION_NAME']}", 'PORT': '', # No PASSWORD needed with IAM auth } }

Connection Pooling with PgBouncer

For high-traffic applications, deploy PgBouncer on Cloud Run:

Cloud Run service for PgBouncer

See references/pgbouncer-setup.md for full configuration

Why PgBouncer:

  • Cloud SQL limits connections (25-4000 depending on tier)

  • Django's CONN_MAX_AGE helps but doesn't pool across processes

  • PgBouncer provides true connection pooling

Running Migrations Safely

Option 1: Cloud Build (Recommended)

cloudbuild.yaml

steps:

  • name: 'gcr.io/cloud-builders/gcloud' args: ['sql', 'connect', 'INSTANCE', '--quiet']

  • name: 'python:3.10' entrypoint: 'bash' args:

    • '-c'
    • | pip install -r requirements.txt python manage.py migrate --noinput env:
    • 'DB_NAME=mydb'
    • 'DB_USER=postgres'
    • 'DB_HOST=/cloudsql/PROJECT:REGION:INSTANCE' secretEnv: ['DB_PASSWORD']

availableSecrets: secretManager: - versionName: projects/PROJECT/secrets/db-password/versions/latest env: 'DB_PASSWORD'

Option 2: Local with Proxy (Simple)

./cloud-sql-proxy PROJECT:REGION:INSTANCE & python manage.py migrate

Dependencies

Required:

  • Django>=5.1

  • Web framework

  • psycopg2-binary>=2.9.9

  • PostgreSQL adapter

  • gunicorn>=23.0.0

  • WSGI server for App Engine

Recommended:

  • whitenoise>=6.7.0

  • Static file serving

  • python-dotenv>=1.0.0

  • Local environment variables

Optional:

  • google-cloud-secret-manager>=2.20.0

  • Secret Manager integration

  • cloud-sql-python-connector[pg8000]>=1.12.0

  • Python-native Cloud SQL connector

  • django-db-connection-pool>=1.2.5

  • Connection pooling (alternative to CONN_MAX_AGE)

Official Documentation

Package Versions (Verified 2026-01-24)

{ "dependencies": { "Django": ">=5.1,<6.0", "psycopg2-binary": ">=2.9.9", "gunicorn": ">=23.0.0", "whitenoise": ">=6.7.0" }, "optional": { "google-cloud-secret-manager": ">=2.20.0", "cloud-sql-python-connector": ">=1.12.0" } }

Production Example

This skill is based on production Django deployments on App Engine:

  • Use Case: Multi-tenant SaaS application

  • Traffic: 10K+ daily requests

  • Database: Cloud SQL PostgreSQL (db-g1-small, 25 connections)

  • Errors: 0 (all 12 known issues prevented)

  • Validation: Unix socket connection, connection pooling, static files, CSRF

Troubleshooting

Problem: No such file or directory for socket

Solution:

  • Verify beta_settings.cloud_sql_instances in app.yaml

  • Check connection name format: PROJECT:REGION:INSTANCE

  • Ensure Cloud SQL instance exists: gcloud sql instances list

Problem: Connection works locally but fails on App Engine

Solution:

  • Verify HOST uses Unix socket path, not 127.0.0.1

  • Check environment variables are set in app.yaml

  • Verify App Engine service account has Cloud SQL Client role

Problem: Migrations timeout during deployment

Solution:

  • Don't run migrations in app.yaml entrypoint

  • Use Cloud Build or run locally with proxy before deploying

  • For large migrations, increase Cloud SQL tier temporarily

Problem: Static files 404 after deploy

Solution:

  • Run python manage.py collectstatic --noinput before deploy

  • Verify static/ handler in app.yaml points to correct directory

  • Check WhiteNoise is in MIDDLEWARE list

Complete Setup Checklist

  • Cloud SQL PostgreSQL instance created

  • Database and user created in Cloud SQL

  • Cloud SQL Auth Proxy installed locally

  • Django settings configured for Unix socket (production) and localhost (dev)

  • beta_settings.cloud_sql_instances in app.yaml

  • CONN_MAX_AGE set for connection pooling

  • Environment variables configured (DB_NAME, DB_USER, etc.)

  • DB_PASSWORD stored securely (not in app.yaml)

  • Static files collected and handler configured

  • CSRF_TRUSTED_ORIGINS includes *.appspot.com

  • Migrations run (locally with proxy) before first deploy

  • Deployed with gcloud app deploy

  • Verified database connection in production logs

Questions? Issues?

Last verified: 2026-01-24 | Skill version: 1.0.0

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

tailwind-v4-shadcn

No summary provided by upstream source.

Repository SourceNeeds Review
-2.7K
jezweb
General

tanstack-query

No summary provided by upstream source.

Repository SourceNeeds Review
-2.5K
jezweb
General

fastapi

No summary provided by upstream source.

Repository SourceNeeds Review