agentsclimarketplace

Resonate server deployment cloud run

Skill resonatehq/resonate-skills/resonate-server-deployment-cloud-run

Agent skills for building with Resonate — durable execution for long-running, crash-safe workflows.

Install
npx -y skills add resonatehq/resonate-skills --skill resonate-server-deployment-cloud-run

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 5 stars5 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Deploy the Resonate server to Google Cloud Run with Cloud SQL Postgres storage. Covers Dockerfile reuse, the Cloud SQL Auth Proxy Unix socket, mandatory server URL, JWT authentication via Secret Manager, and configuration through `RESONATE_` environment variables.

The file declares its own license as Apache-2.0. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.

SKILL.md

9.9 KB, as published. Nobody here has run it

Resonate Server Deployment on Cloud Run

Overview

Deploy the Resonate server (resonatehq/resonate, Rust) as a Google Cloud Run service backed by Cloud SQL Postgres. Distinct deployment target from Linux + systemd — see resonate-server-deployment for the VM pattern.

Companion skill: workers that talk to this server deploy via resonate-gcp-deployments-typescript.

When to use this skill

  • You want the Resonate server on GCP without managing a VM.
  • You want durable storage in Cloud SQL Postgres instead of on-disk SQLite.
  • Your workers run on Cloud Functions, Cloud Run, or any other environment that can reach a Cloud Run service over HTTPS.

When NOT to use this skill

Assumptions & Inputs

You (the agent) should obtain or be given:

  • GCP_PROJECT_ID – GCP project
  • GCP_REGION – region (e.g. us-central1)
  • CLOUD_SQL_INSTANCE – Cloud SQL Postgres instance name (e.g. resonate-db)
  • PG_USER, PG_PASSWORD, PG_DATABASE – Postgres credentials
  • SERVICE_NAME – Cloud Run service name (e.g. resonate-server)

Prerequisites:

  • gcloud authenticated to GCP_PROJECT_ID
  • Cloud Run, Cloud SQL Admin, and Secret Manager APIs enabled
  • A Cloud SQL Postgres 16+ instance, with PG_DATABASE created
  • Local clone of resonatehq/resonate (used as build source — the repo ships its own Dockerfile)

Configuration model

The Resonate server reads all settings from RESONATE_-prefixed environment variables (figment, __ for nesting). There is no need for --args overrides or a custom Dockerfile wrapper — pass config through gcloud run deploy --set-env-vars and mount secrets with --set-secrets.

Env varEquivalent flagPurpose
RESONATE_SERVER__URL--server-urlMandatory public URL; the default http://localhost:8001 silently breaks workers
RESONATE_STORAGE__TYPE--storage-typesqlite (default) or postgres
RESONATE_STORAGE__POSTGRES__URL--storage-postgres-urlPostgres connection string
RESONATE_AUTH__PUBLICKEY--auth-publickeyPath (inside the container) to the mounted JWT public key

High-level flow

  1. Clone the server repo – the upstream Dockerfile builds the Rust server binary.
  2. Smoke-test deploy (SQLite) – confirm the service starts and is reachable before wiring storage.
  3. Attach Cloud SQL and switch to Postgres – connection URL lives in Secret Manager.
  4. Wire up JWT auth – public key mounted from Secret Manager.
  5. Verify.

Step 1 – Clone the server repo

The upstream repo ships a Dockerfile that builds the resonate-server binary. Reuse it as-is.

git clone --depth 1 https://github.com/resonatehq/resonate.git /tmp/resonate-deploy

Step 2 – Smoke-test deploy (SQLite)

Deploy first with in-memory SQLite to confirm the service starts and is reachable, then come back and switch storage. A shorter feedback loop when the pipe breaks.

gcloud run deploy "$SERVICE_NAME" \
  --source=/tmp/resonate-deploy \
  --region="$GCP_REGION" \
  --project="$GCP_PROJECT_ID" \
  --allow-unauthenticated \
  --port=8001 \
  --min-instances=1 \
  --memory=512Mi \
  --set-env-vars=RESONATE_SERVER__URL=https://PLACEHOLDER

Capture the service URL from the deploy output, then redeploy with RESONATE_SERVER__URL pointing at that URL. Cloud Run URLs are deterministic per service/project/region, so the second deploy is a one-time fix-up.

Why --min-instances=1: with cold starts, the first worker poll after a quiet period races the server coming up and surfaces as a connection failure. One warm instance avoids this.

Step 3 – Attach Cloud SQL and switch to Postgres

Postgres connections run through the Cloud SQL Auth Proxy, which exposes a Unix socket at /cloudsql/<connection-name> inside the container.

Connection string format. sqlx (the driver used by the Resonate server) accepts Unix sockets via the ?host=... query parameter in general, but when the connection string has an empty authority — postgres://user:pw@/db?host=/cloudsql/... — it surfaces a misleading "empty host" error. URL-encoding the socket path into the authority avoids that failure mode and is the form to use here:

postgres://PG_USER:PG_PASSWORD@%2Fcloudsql%2FPROJECT%3AREGION%3AINSTANCE/PG_DATABASE

Store the URL in Secret Manager so the password never lands in the Cloud Run revision config:

CONNECTION_NAME="$GCP_PROJECT_ID:$GCP_REGION:$CLOUD_SQL_INSTANCE"
PG_URL="postgres://$PG_USER:$PG_PASSWORD@$(python3 -c "import urllib.parse; print(urllib.parse.quote('/cloudsql/$CONNECTION_NAME', safe=''))")/$PG_DATABASE"
echo -n "$PG_URL" | gcloud secrets create resonate-pg-url --data-file=-

Redeploy with Cloud SQL attached and the secret mounted as an env var:

gcloud run deploy "$SERVICE_NAME" \
  --source=/tmp/resonate-deploy \
  --region="$GCP_REGION" \
  --project="$GCP_PROJECT_ID" \
  --allow-unauthenticated \
  --port=8001 \
  --min-instances=1 \
  --memory=512Mi \
  --add-cloudsql-instances="$CONNECTION_NAME" \
  --set-env-vars=RESONATE_SERVER__URL=https://<service-url>,RESONATE_STORAGE__TYPE=postgres \
  --set-secrets=RESONATE_STORAGE__POSTGRES__URL=resonate-pg-url:latest

Step 4 – JWT authentication

Cloud Run URLs are reachable from the public internet; enable JWT auth before production traffic. The mechanics match the systemd variant — only the key delivery changes.

Generate the key pair locally (commands in resonate-server-deployment#jwt-authentication-setup), then upload the public key to Secret Manager:

gcloud secrets create resonate-public-key --data-file=public_key.pem

Mount the public key as a file in the revision and point the server at it via env var:

gcloud run deploy "$SERVICE_NAME" \
  --source=/tmp/resonate-deploy \
  --region="$GCP_REGION" \
  --project="$GCP_PROJECT_ID" \
  --port=8001 \
  --min-instances=1 \
  --memory=512Mi \
  --add-cloudsql-instances="$CONNECTION_NAME" \
  --set-env-vars=RESONATE_SERVER__URL=https://<service-url>,RESONATE_STORAGE__TYPE=postgres,RESONATE_AUTH__PUBLICKEY=/etc/resonate/public_key.pem \
  --set-secrets=RESONATE_STORAGE__POSTGRES__URL=resonate-pg-url:latest,/etc/resonate/public_key.pem=resonate-public-key:latest

Drop --allow-unauthenticated once JWT is the gatekeeper. The auth check happens at the Resonate API layer, so workers still reach the service over HTTPS.

Token generation and prefix claim semantics are covered in resonate-server-deployment#jwt-authentication-setup.

Step 5 – Verify

SERVER_URL=$(gcloud run services describe "$SERVICE_NAME" --region="$GCP_REGION" --project="$GCP_PROJECT_ID" --format="value(status.url)")
curl -s "$SERVER_URL/promises" | head -c 200

With auth enabled, expect a 401 without a token.

Common pitfalls

  • RESONATE_SERVER__URL missing. Server returns http://localhost:8001 in task URLs. Worker logs show fetch failed / connection_error. Always set it.
  • Empty-authority Postgres URL. postgres://user:pw@/db?host=/cloudsql/... surfaces as "empty host" in sqlx. Encode the socket path into the authority instead (Step 3).
  • First request after deploy 5xx. --min-instances=1 keeps one warm instance so worker polls don't race cold start.
  • Cloud SQL Admin API not enabled. One-time per project: gcloud services enable sqladmin.googleapis.com.
  • Secret not mounted. If RESONATE_STORAGE__POSTGRES__URL is blank at boot, the server falls back to SQLite silently. Confirm --set-secrets is present and the revision actually received the env var.

Architecture

                    Internet
                       │
                       ▼
              ┌────────────────┐
              │   Cloud Run    │  (--min-instances=1, JWT-gated)
              │ resonate-server│
              │    :8001       │
              └────────┬───────┘
                       │ Cloud SQL Auth Proxy
                       │ (Unix socket)
                       ▼
              ┌────────────────┐
              │  Cloud SQL     │
              │  Postgres      │
              └────────────────┘
                       ▲
              Workers  │
              ┌────────┴───────┐
              │ Cloud Function │  (RESONATE_URL = server URL)
              └────────────────┘

Outputs

  • A Cloud Run service serving the Resonate HTTP API, backed by Cloud SQL Postgres.
  • A public HTTPS URL suitable as RESONATE_URL for workers and --server for the Resonate CLI.
  • (If Step 4) JWT-authenticated API surface.

Reference example

example-chess-hero-gcp-ts – end-to-end: worker on Cloud Functions Gen 2, server on Cloud Run, output streamed to the browser via the state bus pattern (resonate-state-bus-pattern-typescript).

Gives 0 of the 12 instructions most ship operate skills give

Counted across 779 of the 1,178 authors here whose files we hold, read 2026-08-06

  • document a rollback plan before deploymentin 40 of 779, across 21 files
  • create an annotated git tagin 21 of 779, across 20 files
  • Run the test suitein 20 of 779
  • update the changelogin 20 of 779, across 18 files
  • verify deployment health after launchin 19 of 779, across 10 files
  • clean up feature flags after full rolloutin 18 of 779, across 10 files
  • verify the working tree is cleanin 18 of 779
  • test both feature flag statesin 17 of 779, across 9 files
  • Make database migrations backward-compatiblein 16 of 779, across 8 files
  • set up error monitoring before launchin 15 of 779, across 7 files
  • monitor metrics at each rollout stagein 14 of 779, across 5 files
  • create a github releasein 14 of 779

Said here and by no other author read

  • reuse the upstream Dockerfile unmodified
  • smoke-test the service using SQLite first
  • set the server URL environment variable explicitly
  • keep a minimum of one warm instance
  • store the Postgres connection string in Secret Manager
  • URL-encode the Cloud SQL socket path into the authority

Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.