본문으로 건너뛰기
cccskills
무료GitHub에 공개

cloud-run-job-cloudsql-setup

Set up Cloud Run Jobs with CloudSQL connection. Use when: (1) Deploying long-running batch jobs that need database access, (2) Errors like "Cloud SQL Proxy not found" in container, (3) "password authentication failed" despite correct credentials, (4) Job creation fails with permission errors. Covers socket path configuration, IAM permissions, and common gotchas.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

설치 방법 보기

포함된 파일(1)

  • SKILL.md5.3 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

Cloud Run Job with CloudSQL Setup

Problem

Setting up Cloud Run Jobs to connect to CloudSQL involves multiple non-obvious steps and gotchas that cause confusing errors. The main issues are:

  1. Wrong gcloud flags for CloudSQL connection
  2. Incorrect socket path configuration
  3. Missing IAM permissions
  4. App code trying to start proxy when Cloud Run already provides it

Context / Trigger Conditions

  • Error: "unrecognized arguments: --add-cloudsql-instances" (wrong flag name)
  • Error: "Cloud SQL Proxy not found" (app trying to start proxy in container)
  • Error: "password authentication failed" (socket path misconfigured or newline in secret)
  • Error: "Permission denied on secret" (missing secretAccessor role)
  • Error: "does not have permission to access namespaces" (missing cloudsql.client role)

Solution

1. Create the Job with Correct Flags

gcloud run jobs create my-job \
  --region=us-central1 \
  --image=gcr.io/PROJECT/IMAGE:latest \
  --set-cloudsql-instances=PROJECT:REGION:INSTANCE \  # NOT --add-cloudsql-instances
  --set-env-vars="POSTGRES_SOCKET_PATH=/cloudsql/PROJECT:REGION:INSTANCE,POSTGRES_DATABASE=mydb,POSTGRES_USER=myuser" \
  --set-secrets="POSTGRES_PASSWORD=my-secret:latest"

Key: Use --set-cloudsql-instances NOT --add-cloudsql-instances

2. Configure Socket Path in App

For Node.js with pg library:

// Use socketPath for unix socket, not host
if (config.socketPath) {
  pool = new Pool({
    host: config.socketPath,  // e.g., "/cloudsql/project:region:instance"
    database: config.database,
    user: config.user,
    password: config.password,
  });
}

Environment variable: POSTGRES_SOCKET_PATH=/cloudsql/PROJECT:REGION:INSTANCE

3. Grant Required IAM Permissions

# Secret access
gcloud secrets add-iam-policy-binding my-secret \
  --member="serviceAccount:PROJECT_NUMBER-compute@developer.gserviceaccount.com" \
  --role="roles/secretmanager.secretAccessor"

# CloudSQL connection
gcloud projects add-iam-policy-binding PROJECT_ID \
  --member="serviceAccount:PROJECT_NUMBER-compute@developer.gserviceaccount.com" \
  --role="roles/cloudsql.client"

4. Don't Auto-Start Proxy in Container

Cloud Run automatically provides the CloudSQL proxy socket. If your app has logic to start the proxy, skip it when a socket path is configured:

// Skip proxy start if socketPath provided (Cloud Run handles it)
if (!config.socketPath && config.host === "localhost") {
  await ensureCloudSqlProxy();  // Only for local development
}

5. Create Secrets Without Newlines

# WRONG - adds trailing newline
gcloud secrets create my-secret --data-file=- <<< "password"

# CORRECT - no trailing newline
echo -n "password" | gcloud secrets create my-secret --data-file=-

Verification

# Check job config
gcloud run jobs describe my-job --region=us-central1

# Execute and check logs
gcloud run jobs execute my-job --region=us-central1
gcloud run jobs logs read my-job --region=us-central1 --limit=50

Example: Complete Setup

# 1. Create secrets (no newlines!)
echo -n "dbpassword123" | gcloud secrets create db-password --data-file=-

# 2. Grant permissions
gcloud secrets add-iam-policy-binding db-password \
  --member="serviceAccount:123456789-compute@developer.gserviceaccount.com" \
  --role="roles/secretmanager.secretAccessor"

# 3. Create job
gcloud run jobs create my-processor \
  --region=us-central1 \
  --image=gcr.io/my-project/processor:latest \
  --memory=4Gi \
  --cpu=2 \
  --task-timeout=86400s \
  --max-retries=3 \
  --set-cloudsql-instances=my-project:us-central1:my-instance \
  --set-env-vars="POSTGRES_SOCKET_PATH=/cloudsql/my-project:us-central1:my-instance,POSTGRES_DATABASE=mydb,POSTGRES_USER=myuser" \
  --set-secrets="POSTGRES_PASSWORD=db-password:latest"

# 4. Execute
gcloud run jobs execute my-processor --region=us-central1

Notes

  • Cloud Run Job timeout max is 86400s (24 hours)
  • The socket path format is /cloudsql/PROJECT:REGION:INSTANCE
  • Socket appears as a Unix socket at that path when container starts
  • No need for Cloud SQL Proxy binary in your container
  • Cloud Build service account needs different permissions than the compute service account
  • PostgreSQL password reset gotcha: When resetting Cloud SQL PostgreSQL passwords, do NOT use --host='%'. That flag is MySQL-specific and creates a separate user entry in PostgreSQL, causing intermittent password auth failures (some jobs connect, others don't, despite identical DATABASE_URL). Use: gcloud sql users set-password USERNAME --instance=INSTANCE --password=PASSWORD (no --host flag)
  • Password changes may take a minute to propagate through Cloud SQL Auth Proxy sidecars. If auth fails immediately after a reset, redeploy the job to force a fresh proxy connection

References

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Fix ArgoCD ExternalSecret deployment failing with "namespace X is not permitted in project Y". Use when: (1) ExternalSecret shows OutOfSync in ArgoCD but won't sync, (2) ArgoCD application status shows "namespace X is not permitted in project 'infrastructure'", (3) ExternalSecret targets a namespace managed by a different ArgoCD project, (4) Using apps-of-apps pattern with separate infrastructure and application projects.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

divinevideo/divine-mobile2662026년 10월 19일 업데이트

Art direction for any content — reads text, PDF, Word, HTML, PPT, then proposes 2-3 creative directions with photography style, mood, and visual language. After selection, generates AI image prompts and visual briefs section-by-section. Use when the user shares content and needs visual direction, image sourcing, or creative direction for any material.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

divinevideo/divine-mobile2662026년 10월 19일 업데이트

Fix "Null check operator used on a null value" errors when an object is set to null during an async await. Use when: (1) Object reference is nullified while awaiting, (2) Code accesses object with ! after await returns, (3) Cancel/dispose operations run concurrently with async operations on same object. Solution: capture local reference before await.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

divinevideo/divine-mobile2662026년 10월 19일 업데이트

Add custom metadata headers (x-amz-meta-*) to AWS v4 signed requests for GCS S3-compatible API. Use when: (1) Adding custom metadata to GCS uploads via S3 API, (2) Getting signature mismatch errors after adding new headers, (3) x-amz-meta-* headers being ignored or causing 403 errors. Custom headers MUST be included in canonical headers and signed headers list.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

divinevideo/divine-mobile2662026년 10월 19일 업데이트

Fix password/secret authentication failures caused by trailing newlines when creating Google Cloud secrets (or similar) with bash here-strings. Use when: (1) Password authentication fails with correct password, (2) Secret created with `<<< "value"` syntax, (3) Error like "password authentication failed" or "invalid token" despite correct value. Bash here-strings (`<<<`) add a trailing newline that corrupts secrets.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

divinevideo/divine-mobile2662026년 10월 19일 업데이트

Fix silent video/media processing failures caused by URL extraction code that filters on file extensions (.mp4, .webm, .webp). Use when: (1) Media moderation, transcoding, or analysis silently skips files from Blossom or content-addressed storage servers, (2) URL extraction from Nostr event tags (imeta, r tags) drops URLs without recognized extensions, (3) CDN fallback URLs append .mp4 but the actual server uses extensionless content-addressed paths like /{sha256}. Common in Nostr video events (kind 34236) where different clients use different URL formats.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

divinevideo/divine-mobile2662026년 10월 19일 업데이트

divinevideo의 스킬 모두 보기

이 스킬의 문제 신고