diff --git a/CHANGELOG.md b/CHANGELOG.md index 284ee2c..ab54b10 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +## 0.2.0 - 2026-10-08 + +### Changed + +- Vendored all 21 Render skills from `render-oss/skills` release `skills-v1.0.0` instead of `main`: shared, single-sourced reference content across skills, doc retrieval that does not require `curl`, and the Render Workflows skill updated for SDK 1.x. + +### Removed + +- Reference files replaced by shared references: `render-deploy/references/blueprint-spec.md`, `render-disks/references/sizing-and-snapshots.md`, `render-networking/references/troubleshooting.md`, `render-scaling/references/instance-types.md`, and `render-web-services/references/deploy-lifecycle.md`. + ## 0.1.0 - 2026-08-03 Initial GitHub release of the Render integration for the Pi coding agent. diff --git a/README.md b/README.md index 1431533..59addaf 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ MCP package or MCP support prerequisite to install. For a reproducible install pinned to this release: ```bash -pi install https://github.com/render-oss/render-pi-plugin@v0.1.0 +pi install https://github.com/render-oss/render-pi-plugin@v0.2.0 ``` ## What you get (v1) diff --git a/package-lock.json b/package-lock.json index 2b0368b..51712e2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@render/pi-render", - "version": "0.1.0", + "version": "0.2.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@render/pi-render", - "version": "0.1.0", + "version": "0.2.0", "license": "MIT", "dependencies": { "pi-mcp-adapter": "2.19.0" diff --git a/package.json b/package.json index a6e0350..801c925 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@render/pi-render", - "version": "0.1.0", + "version": "0.2.0", "description": "Render integration for the Pi coding agent — deployment skills and lazy hosted MCP access.", "keywords": [ "pi-package" diff --git a/skills/.sync-source b/skills/.sync-source index 88edf1d..b7f95ee 100644 --- a/skills/.sync-source +++ b/skills/.sync-source @@ -1,4 +1,4 @@ source: https://github.com/render-oss/skills -ref: main -commit: 1b36c1643c1e6105c73ca19cb387fc916d1da4fc +ref: skills-v1.0.0 +commit: 3a3a422f6074469327708a8c447ada9b6a739747 note: generated by scripts/sync-skills.sh; do not edit vendored skills by hand. diff --git a/skills/render-background-workers/SKILL.md b/skills/render-background-workers/SKILL.md index aab99f8..71b1cf2 100644 --- a/skills/render-background-workers/SKILL.md +++ b/skills/render-background-workers/SKILL.md @@ -4,7 +4,7 @@ description: >- Sets up and configures background workers on Render for queue-based job processing. Use when the user needs to process async jobs, consume from a queue, run Celery/Sidekiq/BullMQ/Asynq/Oban workers, handle graceful - shutdown with SIGTERM, wire a worker to Key Value (Redis), or choose between + shutdown with SIGTERM, wire a worker to Key Value, or choose between workers and cron jobs for background work. Trigger terms: background worker, async jobs, queue consumer, Celery, Sidekiq, BullMQ, Asynq, Oban, job processing, SIGTERM, graceful shutdown. @@ -29,6 +29,10 @@ This skill explains **worker** services on Render: processes that **consume jobs Per-framework setup and signal-handling detail: `references/queue-framework-setup.md`, `references/graceful-shutdown.md`. +Before deploying, restarting, or changing shutdown behavior, read `references/deployments.md`. +Before configuring or troubleshooting a worker's outbound private-network connection, read `references/private-networking.md`. +When choosing between a worker, cron job, and Workflow, read `references/service-types.md`. + ## How Workers Work - **Long-running services** with **no inbound (HTTP) traffic**. Render does not expose a public URL or internal hostname for workers the way it does for web or private services—**workers cannot receive private network traffic directed at them**. @@ -39,11 +43,11 @@ Per-framework setup and signal-handling detail: `references/queue-framework-setu | Framework | Language | Queue backend | Notes | |-----------|----------|---------------|--------| -| Celery | Python | Redis / Key Value | Most common Python task queue | -| Sidekiq | Ruby | Redis / Key Value | Standard for Rails | -| BullMQ | Node.js | Redis / Key Value | Modern Node queue (Redis-based) | -| Asynq | Go | Redis / Key Value | Go async task processing | -| Oban | Elixir | **Postgres** (not Redis) | Queue stored in the database | +| Celery | Python | Key Value | Most common Python task queue | +| Sidekiq | Ruby | Key Value | Standard for Rails | +| BullMQ | Node.js | Key Value | Modern Node queue | +| Asynq | Go | Key Value | Go async task processing | +| Oban | Elixir | **Postgres** (not a Key Value queue) | Queue stored in the database | ## Pairing with Key Value @@ -61,13 +65,12 @@ See `references/queue-framework-setup.md` for minimal app + YAML examples. | Always-on queue consumer | **Background Worker** | Polls continuously; long-lived process | | Periodic scheduled task | **Cron Job** | Runs on a schedule, **exits**; **12h max** per run | | Distributed parallel compute | **Workflow** | Each run gets its own instance; fan-out patterns | -| High-volume or bursty jobs | **Workflow** | Scales per run; **no idle instance cost** between runs | +| High-volume or bursty jobs | **Workflow** | Scales per run without a continuously running worker instance | ## Graceful Shutdown -- Before stopping an instance, Render sends **`SIGTERM`**, then waits up to **`maxShutdownDelaySeconds`** (**1–300**, **default 30**) before **`SIGKILL`**. - Workers should: **(1)** stop accepting new jobs, **(2)** finish the current job or **checkpoint** progress, **(3)** close connections, **(4)** exit **0**. -- Set **`maxShutdownDelaySeconds`** to at least your **longest safe job duration** (see Dashboard or Blueprint). +- Follow `references/deployments.md` for Render's current drain, signal, and shutdown-delay behavior. Language- and framework-specific handlers: `references/graceful-shutdown.md`. @@ -81,6 +84,7 @@ services: name: jobs plan: starter region: oregon + maxmemoryPolicy: noeviction ipAllowList: [] - type: worker @@ -106,6 +110,9 @@ Optional: **`maxShutdownDelaySeconds`** on the worker service for longer drainin |--------|------| | Celery, Sidekiq, BullMQ, Asynq, Oban setup + YAML | `references/queue-framework-setup.md` | | SIGTERM, `maxShutdownDelaySeconds`, per-language patterns | `references/graceful-shutdown.md` | +| Deploy lifecycle, shutdown, restart, and verification | `references/deployments.md` | +| Private-network scope, internal addresses, and troubleshooting | `references/private-networking.md` | +| Service-type selection and execution models | `references/service-types.md` | ## Related Skills @@ -113,3 +120,16 @@ Optional: **`maxShutdownDelaySeconds`** on the worker service for longer drainin - **render-blueprints** — Full `render.yaml` schema, `fromService`, projects - **render-networking** — Private URLs, what can call what - **render-scaling** — Worker plans, instance counts, limits + + +## Current documentation retrieval + +Whenever this skill directs you to consult current Render documentation: + +1. Retrieve the linked Markdown document directly with an available URL-fetching tool or HTTP client, such as `curl`. Do not substitute web-search summaries for the document. +2. Confirm that retrieval succeeded and returned the expected document, then read its contents. Saving a file or printing its path is not sufficient. +3. If the request fails or your tool cannot read the Markdown response, open and read the linked HTML version instead. +4. If neither version can be retrieved, disclose that the current reference is unavailable and follow any topic-specific fallback in the skill. Use bundled guidance only for stable constraints, and do not guess at changeable platform details. + +When a task requires multiple references, apply this workflow to each one and distinguish the documents you verified from those that remain unavailable. + diff --git a/skills/render-background-workers/references/deployments.md b/skills/render-background-workers/references/deployments.md new file mode 100644 index 0000000..5ca9905 --- /dev/null +++ b/skills/render-background-workers/references/deployments.md @@ -0,0 +1,50 @@ + +## Deployments and health checks + +A Render deploy is asynchronous. A successful trigger means only that Render accepted or queued the deploy; it does not mean the new version is live. Before triggering a deploy, confirm the workspace, service, intended source commit or image, and current live deploy. Capture the new deploy ID, monitor it to a terminal state, and do not report success until its status is `live` and the deployed workload has been verified. + +Before configuring or troubleshooting deployments and health checks, fetch the current Render references: + +- [deploys.md](https://render.com/docs/deploys.md) (HTML: ) +- [health-checks.md](https://render.com/docs/health-checks.md) (HTML: ) + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read both references. + +Read the relevant sections of both documents. Confirm current service-type support, command timeouts, health-check thresholds, rollout behavior, and configuration syntax rather than relying on remembered values. + +Automatic deployment behavior depends on the service's source and settings. A service linked to a branch through a connected Git provider can deploy on each commit, wait for supported CI checks, or require manual triggers. Services that pull a prebuilt image and services linked by a public Git repository URL require manual deploys; moving a mutable image tag does not itself trigger one. When manually deploying a historical commit, verify whether that trigger method changes automatic-deploy settings. If automatic deploys remain enabled, a later branch update can replace the selected commit. + +The normal lifecycle is build command, optional pre-deploy command, then start command and readiness checks. If a command fails or times out, the deploy fails and later steps do not run. A pre-deploy command runs after the build on a separate instance before the new version is deployed. Neither the build nor pre-deploy instance can access an attached persistent disk, and pre-deploy filesystem changes do not carry into the running service. Use pre-deploy for release tasks such as database migrations, not for producing runtime artifacts. Pre-deploy commands are supported for paid web services, private services, and background workers. + +Render normally deploys services without downtime by starting the new version before retiring the current one. Web and private services continue routing traffic to the current instances until the new instances are ready. Multi-instance services roll out one instance at a time; if a replacement does not become healthy, Render cancels the rollout and retains or restores the previous version. Attaching a persistent disk disables zero-downtime deploys, so plan explicitly for an interruption. + +A workflow deployment has a different completion model. It builds and caches the image used by future task runs and includes a task-registration step, but it does not execute those tasks. After a workflow deploy succeeds, verify that the expected task definitions are registered. Trigger and monitor a task run separately only when execution is intended. For workflow-specific deployment behavior, fetch the current workflow overview: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/workflows.md) or its [HTML version](https://render.com/docs/workflows). + +Health checks apply to web services and private services. Both use TCP socket checks by default. Only web services support a configured HTTP health-check path. Render sends an HTTP `GET`; any `2xx` or `3xx` response received within five seconds succeeds, while other status codes, timeouts, and connection failures fail. Private services support TCP checks only. + +For a new deploy, all new instances must pass their checks at the same time within the current readiness window, documented as 15 minutes, before Render routes traffic to them. For a running service, consecutive failures currently remove an instance from routing after 15 seconds and restart it after 60 seconds. Treat these thresholds as platform behavior, not user-tunable health-check interval settings, and verify them in the fetched reference before relying on exact timing. + +Design an HTTP health endpoint to represent readiness for production traffic. Keep it fast and side-effect free. Check critical dependencies only when losing that dependency should make the entire instance unavailable; otherwise a transient dependency failure can unnecessarily remove healthy application capacity. Verify the configured path, response status, response time, listening port, and `0.0.0.0` binding when checks fail. + +After traffic moves, Render gives the previous instance a drain period, then sends `SIGTERM`. The application should stop accepting new work, finish or safely abandon in-flight work, close connections, and exit within its shutdown delay. Ensure the actual application process receives the signal: container entrypoints and shell wrappers should use `exec` or explicitly forward signals. Render sends `SIGKILL` if the process remains running after the delay. The documented default shutdown delay is 30 seconds and the usual maximum is 300 seconds, but support varies by service configuration; confirm the current reference and Blueprint or API validation before setting `maxShutdownDelaySeconds`. + +A service restart is a special deploy of the same commit and user-defined environment-variable values as the current running instance. It does not incorporate configuration changes saved after that deploy. Use a standard deploy when pending configuration must take effect. + +Only one deploy runs at a time for a service. A workspace's overlapping-deploy policy determines whether a new trigger waits or cancels the in-progress deploy. Do not assume the policy or wait for every intermediate revision: inspect the workspace setting and identify the deploy that actually became live. + +Treat rollback as a new deploy based on a retained previous build artifact, not as restoration of the entire service to an earlier point in time. It does not reverse database migrations, messages, external writes, or other side effects from the release, so confirm that the previous application version remains compatible with current external state. Disks and their data are not rolled back, some settings continue using current configuration, mutable image tags can resolve to a different image, and eligible artifacts are retained only for a limited period. Before rolling back, fetch the current rollback reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/rollbacks.md) or its [HTML version](https://render.com/docs/rollbacks). + +Read which configuration comes from the target deploy and which remains current. After the rollback is created, inspect the service's resulting automatic-deploy setting instead of assuming whether it remains enabled, and deliberately restore the intended setting after the underlying issue is resolved. + +Deploy hooks are secret credentials that authorize deploys. Never print, commit, or expose their full URLs. Before using one, fetch the current deploy-hook reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/deploy-hooks.md) or its [HTML version](https://render.com/docs/deploy-hooks). + +Distinguish an immediately started deploy from a queued one, and continue monitoring the resulting deploy rather than treating the HTTP response as completion. + +After a deploy becomes live, verify the behavior appropriate to the service type: make a request to a web or private service, confirm a worker is processing work, confirm a cron job or workflow invocation completes, and inspect recent runtime logs for new errors. If a deploy fails, diagnose the first failed lifecycle stage before retrying. + diff --git a/skills/render-background-workers/references/graceful-shutdown.md b/skills/render-background-workers/references/graceful-shutdown.md index cc4c2a8..682cb57 100644 --- a/skills/render-background-workers/references/graceful-shutdown.md +++ b/skills/render-background-workers/references/graceful-shutdown.md @@ -4,17 +4,13 @@ Render stops worker instances during **deploys**, **manual restarts**, and **sca ## Platform behavior -1. Render sends **`SIGTERM`** to your process. -2. The platform waits up to **`maxShutdownDelaySeconds`** (**1–300**, **default 30**). -3. If the process is still running, Render sends **`SIGKILL`** (not catchable). - -Configure **`maxShutdownDelaySeconds`** in the **Dashboard** (service settings) or in **`render.yaml`** on the worker service. Set it to cover your **longest job** you are willing to let complete during shutdown (plus buffer for flushing metrics, closing DB pools, etc.). +Follow [deployments.md](deployments.md) for Render's current drain, signal, and shutdown-delay behavior. Set the available shutdown delay to cover the longest job you are willing to let complete, plus time for cleanup. ## General pattern 1. **Stop accepting new jobs** — stop the consumer loop, pause polling, or drain the framework’s internal fetch. 2. **Finish the current job** or **checkpoint** durable progress so another worker can resume safely. -3. **Close connections** — Redis/Postgres pools, HTTP clients. +3. **Close connections** — Key Value/Postgres pools, HTTP clients. 4. **Exit with code 0** when done. ## Python diff --git a/skills/render-background-workers/references/private-networking.md b/skills/render-background-workers/references/private-networking.md new file mode 100644 index 0000000..d68d6be --- /dev/null +++ b/skills/render-background-workers/references/private-networking.md @@ -0,0 +1,25 @@ + +## Private networking + +Render services can communicate over a private network without traversing the public internet. Private-network peers must belong to the same workspace and run in the same region. An isolated project environment can additionally block traffic both to and from resources outside that environment, so workspace and region matching alone do not guarantee connectivity. + +Before designing, configuring, or troubleshooting private-network communication, fetch the current Render private-network reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/private-network.md) or its [HTML version](https://render.com/docs/private-network). + +Read the relevant sections. Confirm current service-type capabilities, port restrictions, environment-isolation behavior, discovery-hostname guidance, and plan requirements instead of relying on a memorized catalog. + +Web services and private services have internal hostnames and can receive private-network traffic. A private service must bind at least one port; use a background worker instead when a workload does not need to accept inbound connections. Render Postgres and Key Value instances provide internal connection URLs. Workflows, background workers, and cron jobs can initiate private-network connections but do not have an internal address for receiving them. Static sites are not on the private network. Free web services can initiate private-network connections but cannot receive them. + +Prefer the internal address or URL shown under **Connect > Internal** in the Render Dashboard. Include the protocol when the client or server requires one; an address such as `service:10000` does not by itself establish whether to use HTTP, HTTPS, or another protocol. A process that receives traffic must listen on the intended port and on an interface reachable outside its own container, such as `0.0.0.0`, rather than only on loopback. + +For Blueprint-managed connections, fetch the current Blueprint specification and use supported service or database references instead of copying a generated hostname, port, credential, or connection string. Web and private services currently expose `host`, `port`, and `hostport` properties. A Blueprint can obtain another service's discovery hostname by referencing that service's `RENDER_DISCOVERY_SERVICE` environment variable with `fromService.envVarKey`; the discovery hostname is not a service property. The fetched specification is authoritative for the syntax and supported references. + +A service can expose at most 75 ports on the private network. Ports `18012`, `18013`, and `19099` are unavailable for private-network communication. Port `10000` is not generally blocked: for a web service, private traffic to port `10000` routes to its primary HTTP server even when that server binds to another port. In that case, both port `10000` and the actual primary HTTP port route to the same server. + +Use a service's normal internal hostname for ordinary service-to-service traffic. For advanced per-instance communication, each web or private service has a discovery hostname, conventionally formed by appending `-discovery` to its internal hostname, that resolves to all active instance IP addresses. A service receives its own discovery hostname in `RENDER_DISCOVERY_SERVICE`. Use DNS APIs that honor the system resolver configuration, and do not persist resolved instance IPs because they can change between deploys. Prefer hostname-based communication unless per-instance addressing or custom load balancing is specifically required. + +When a private-network connection fails, verify the workspace, region, project-environment isolation settings, whether the destination service type accepts inbound traffic, the internal hostname or URL, protocol, port, listening interface, current deploy health, and DNS resolution. Do not substitute a public URL or expose a private service merely to bypass a private-network configuration problem. + +AWS PrivateLink is a separate Pro-or-higher feature for connecting a Render private network to compatible AWS-hosted systems. Fetch its current documentation before proposing or configuring it; do not treat ordinary Render service-to-service networking and PrivateLink as interchangeable. + diff --git a/skills/render-background-workers/references/queue-framework-setup.md b/skills/render-background-workers/references/queue-framework-setup.md index a055117..98d8cda 100644 --- a/skills/render-background-workers/references/queue-framework-setup.md +++ b/skills/render-background-workers/references/queue-framework-setup.md @@ -2,7 +2,7 @@ Minimal patterns for running each stack as a **`type: worker`** service. Replace regions, plans, and commands to match your repo. -**Shared Key Value (Redis-style) wiring** — add once, reference from every consumer that needs the broker: +**Shared Key Value wiring** — add once, reference from every consumer that needs the broker: ```yaml services: @@ -10,6 +10,7 @@ services: name: jobs region: oregon plan: starter + maxmemoryPolicy: noeviction ipAllowList: [] ``` @@ -24,7 +25,7 @@ envVars: property: connectionString ``` -Set Key Value **maxmemory policy** to **`noeviction`** in the Dashboard so queue keys are never evicted like cache entries. +The Blueprint sets Key Value **`maxmemoryPolicy: noeviction`** so queue keys are never evicted like cache entries. --- @@ -230,7 +231,7 @@ func main() { ## Oban (Elixir) -Oban uses **PostgreSQL** as its queue store—**not** Redis. Provision a Render **PostgreSQL** database and wire **`DATABASE_URL`**. +Oban uses **PostgreSQL** as its queue store—**not** a Key Value queue. Provision a Render **PostgreSQL** database and wire **`DATABASE_URL`**. **Config** (`config/runtime.exs` or `config/prod.exs` pattern): diff --git a/skills/render-background-workers/references/service-types.md b/skills/render-background-workers/references/service-types.md new file mode 100644 index 0000000..a0a3786 --- /dev/null +++ b/skills/render-background-workers/references/service-types.md @@ -0,0 +1,37 @@ + +## Render service types + +Use this guidance when selecting or comparing Render service types, or when a task's architecture depends on the distinction between them. A task that is already unambiguously scoped to one service type does not need this entire overview. + +On Render, a service represents code deployed for a particular execution model. Render runs that service on one or more instances, and the service's compute plan determines the CPU and memory available to each instance. + +Before choosing a service type, fetch the current service-types reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/service-types.md) or its [HTML version](https://render.com/docs/service-types). + +If neither version can be retrieved, use the bundled overview below only for basic service-type selection. State that current platform details could not be verified, and do not guess about changeable capabilities such as supported runtimes, plans, scaling, networking, disks, health checks, deployment behavior, availability, or limits. + +Render provides six public service types for running code: + +- **Web service:** A continuously running server that receives public HTTP traffic and also has an internal hostname for private-network traffic. Use it for dynamic websites, APIs, and other internet-facing server applications. +- **Static site:** Built HTML, CSS, JavaScript, and other static assets served publicly from Render's global CDN. Use it only when the deployed application does not require server-side runtime logic. +- **Private service:** A continuously running server that receives traffic only over Render's private network. Use it for internal HTTP, TCP, gRPC, or other server processes that need an internal hostname but no public URL. +- **Background worker:** A continuously running process that does not receive incoming traffic or expose a public or internal hostname. Use it for queue consumers and other processes that pull or poll for work. +- **Cron job:** A command or process that starts on a schedule, performs a bounded unit of work, and exits. Use it for straightforward recurring tasks rather than an always-running process. +- **Workflow:** A collection of on-demand tasks executed across distributed compute, with Render handling task queuing, orchestration, and provisioning. Use it when the workload benefits from independently invoked tasks, retries, composition, or parallel execution instead of a continuously running worker process. + +Choose based on how the code executes and receives work: + +- Public incoming traffic that requires server-side logic belongs on a web service. Public static assets with no runtime server belong on a static site. +- An application that needs both public and private ingress remains a web service; use its internal hostname for traffic from other Render services. +- A process that receives private-network requests belongs on a private service. A process that only initiates connections and pulls work belongs on a background worker. +- A simple scheduled command that exits belongs on a cron job. An always-running queue consumer belongs on a background worker. On-demand or distributed tasks for which Render should manage queuing and per-run compute belong in a workflow. + +Cron jobs and Workflows use invocation-based execution models. The ordinary instance-count and autoscaling model used by continuously running services does not apply to them. + +Render Postgres and Render Key Value are fully managed datastores, not general-purpose compute service types for running application code. Use Render Postgres for relational data and Render Key Value for use cases such as shared caching and job queues. An attached persistent disk is a storage feature of certain compute services, not a service type of its own. + +After selecting a type, fetch the product article linked from the service-types reference before relying on details such as supported runtimes and sources, plans, scaling, networking, disks, health checks, deployment behavior, scheduling semantics, availability, or limits. These capabilities are not uniform across service types and can change independently. + +Human-facing service names do not always map directly to configuration identifiers or structure. When creating or editing a Blueprint, fetch the current Blueprint specification and use its service-type schema instead of inferring fields or values from this overview. In particular, do not assume that every Dashboard service type has a same-named Blueprint `type` or that managed datastores are declared like compute services. + diff --git a/skills/render-blueprints/SKILL.md b/skills/render-blueprints/SKILL.md index f41adb1..ac227f7 100644 --- a/skills/render-blueprints/SKILL.md +++ b/skills/render-blueprints/SKILL.md @@ -23,6 +23,16 @@ metadata: Blueprints define Render infrastructure as YAML (commonly `render.yaml` at the repo root). This skill focuses on **authoring**, **wiring**, **projects/environments**, **previews**, **validation**, and **immutable fields**. Heavy detail lives under `references/`. +Before creating or modifying a Blueprint, read `references/blueprints.md` for the current specification-fetch, validation, repository-sync, and safety workflow. + +For current compute-plan terminology, Plan IDs, and availability, use `references/compute-plans.md` instead of relying on plan catalogs embedded in examples. + +Before adding or changing a service-attached disk, read `references/persistent-disks.md` for current architectural constraints and configuration workflow. + +Before wiring private-network addresses, ports, or discovery hostnames, read `references/private-networking.md`. + +Before choosing a service type or translating its Dashboard name to Blueprint structure, read `references/service-types.md`. + ## When to Use Apply this skill when the user: @@ -48,12 +58,7 @@ For end-to-end deploy flows and MCP/CLI operations, see **render-deploy**. For e | `projects` | Optional grouping; contains `environments` and service lists | | `previews` | Defaults for PR preview environments | -A Blueprint may also use patterns like **ungrouped** resources vs **environment-scoped** lists, depending on whether you adopt the projects model. Avoid duplicating the same logical resource in multiple places (see `references/common-mistakes.md`). - -### Schema and IDE validation - -- **JSON Schema URL:** `https://render.com/schema/render.yaml.json` -- Configure your editor to associate `render.yaml` with that schema for completions and diagnostics. +A Blueprint may also use patterns like **ungrouped** resources vs **environment-scoped** lists, depending on whether you adopt the projects model. See `references/common-mistakes.md` for duplication and naming pitfalls. ### Minimal example: web + PostgreSQL @@ -93,18 +98,20 @@ services: Common `runtime` values: **`node`**, **`python`**, **`go`**, **`ruby`**, **`rust`**, **`elixir`**, **`docker`**, **`image`**, **`static`**. - **`docker`**: Build from `Dockerfile` (see `dockerfilePath`, `dockerContext`, `dockerCommand`). -- **`image`**: Run a prebuilt container image (registry + optional `registryCredential`). +- **`image`**: Run a prebuilt container image with `image.url` and optional `image.creds.fromRegistryCreds`. - **`static`**: Static site; requires `staticPublishPath` and build output paths (see references). ## Cross-Service Wiring -Env vars under `envVars` (and analogous patterns in groups) can pull values from other resources instead of hardcoding secrets. +Before configuring variables, secrets, secret files, or environment groups, read `references/environment-variables.md`. + +Service env vars under `envVars` can pull values from other resources instead of hardcoding secrets. Environment-group variables cannot reference services, databases, or other environment groups. ### `fromDatabase` Reference a database in `databases:` by `name`. Properties include: -- `connectionString`, `host`, `port`, `user`, `password`, `database` +- `connectionString`, `connectionPoolString`, `host`, `port`, `user`, `password`, `database` ### `fromService` @@ -118,12 +125,6 @@ Which properties are valid depends on target service type (e.g. Key Value vs `ps Attach shared vars from `envVarGroups` (by group `name`). -### Other env var keys - -- **`value`**: Literal string. -- **`generateValue`**: Let Render generate a random secret (password/API key). -- **`sync`**: Set `sync: false` for secrets that should not sync from repo on every update (see edge cases in wiring reference). - Full patterns and combinations: `references/wiring-patterns.md`. ## Projects and Environments @@ -176,13 +177,11 @@ projects: name: cache plan: starter maxmemoryPolicy: noeviction - ipAllowList: - - source: 0.0.0.0/0 - description: everywhere + ipAllowList: [] # Internal access only databases: - name: db - plan: starter + plan: basic-256mb ``` Key rules: @@ -190,28 +189,26 @@ Key rules: - Each environment owns its `services` and `databases` lists. - Do not define the same resource at both the root level and inside an environment. - `envVarGroups` can be scoped to a project environment or shared across the workspace. -- Environment isolation (Professional+) can block cross-environment private network traffic. +- With a Pro workspace or higher, environment isolation can block cross-environment private network traffic. For single-service apps, flat top-level `services`/`databases` is fine. Reach for the projects pattern when you have multiple services, need staging/production separation, or want environment-scoped env groups. ## Preview Environments -Top-level `previews` controls PR previews: +When a preview request is underspecified, first establish the desired generation mode, retention period, preview compute plans, and whether the user expects to exclude any resources. + +Top-level `previews` controls Blueprint preview environments: - **`previews.generation`**: `off` (default), `manual`, or `automatic` - **`previews.expireAfterDays`**: Auto-delete preview stacks after N days -Services can override preview behavior (e.g. service-level `previews.generation`). Limitations: autoscaling behavior, `sync: false` vars, `previewPlan` / flexible instance constraints—see `references/preview-environments.md`. - -## Validation - -```bash -render blueprints validate -``` +Do not confuse preview environments with service previews: -Requires **Render CLI v2.7.0+**. Run from the repo root (or pass the appropriate path options your CLI version supports). Fix schema and semantic errors before merging Blueprint changes. +- A top-level `previews.generation: automatic` creates the Blueprint's preview environment, including the resources declared by that Blueprint. +- A service-level `previews.generation` controls that service's independent service previews. It does **not** override the Blueprint preview environment or exclude that service from it. It accepts only `manual` or `automatic`; omit it to disable independent service previews. +- Use `previews.plan` and `previews.numInstances` on compute services to size their preview-environment instances. Key Value and Postgres use `previewPlan` instead. -Official schema: `https://render.com/schema/render.yaml.json` +If a user needs a worker or another resource omitted entirely from Blueprint preview environments, explain that service-level preview generation is not an exclusion mechanism; the Blueprint or application architecture must account for that requirement. Other limitations include autoscaling behavior, `sync: false` variables, and database plan compatibility—see `references/preview-environments.md`. ## Immutable Fields @@ -238,7 +235,7 @@ Plan other fields (disk, HA, replicas) carefully up front; consult Render docs f | Area | Fields | |------|--------| -| Plans | `plan`, `previewPlan` (previews), database `plan` | +| Plans | `plan`; compute-service `previews.plan`; Key Value/Postgres `previewPlan` | | Build/run | `buildCommand`, `startCommand`, `preDeployCommand`, `rootDir` | | Deploy | `autoDeployTrigger`: `commit`, `checksPass`, or `off` | | Lifecycle | `maxShutdownDelaySeconds`: 1–300, default **30** | @@ -246,21 +243,40 @@ Plan other fields (disk, HA, replicas) carefully up front; consult Render docs f | Storage | `disk` (`name`, `mountPath`, `sizeGB`) | | Scale | `scaling` / `numInstances` (see references) | | Monorepo | `buildFilter` (`paths`, `ignoredPaths`) | -| Docker | `dockerfilePath`, `dockerContext`, `dockerCommand`, `registryCredential` | +| Docker | `dockerfilePath`, `dockerContext`, `dockerCommand`, `registryCredential`; prebuilt `image.url` / `image.creds` | -Deprecated names to avoid: `env` (use `runtime`), `redis` (use `keyvalue`), `autoDeploy` (use `autoDeployTrigger`), `pullRequestPreviewsEnabled` (use `previews.generation`). Details: `references/common-mistakes.md`. +Deprecated names to avoid: `env` (use `runtime`), `redis` (use `keyvalue`), `autoDeploy` (use `autoDeployTrigger`), `previewsEnabled`, and `pullRequestPreviewsEnabled`. Use the appropriate top-level or service-level `previews.generation` replacement described in `references/common-mistakes.md`. ## References | Document | Contents | |----------|----------| +| `references/blueprints.md` | Current Blueprint specification, schema, validation, repository-sync, and safety workflow | +| `references/compute-plans.md` | Current compute-plan terminology, Plan ID discovery, availability, and change behavior | +| `references/environment-variables.md` | Current environment-variable documentation, secrets, groups, platform variables, and mutation safety | +| `references/persistent-disks.md` | Service-attached disk constraints, current documentation, sizing, snapshots, and Blueprint workflow | +| `references/private-networking.md` | Private-network scope, addresses, Blueprint references, discovery, ports, and isolation | +| `references/service-types.md` | Service-type selection, execution models, and Blueprint naming | | `references/field-reference.md` | YAML fields by service type, database, groups, projects, previews, scaling, disk, static, Key Value | -| `references/wiring-patterns.md` | `fromDatabase` / `fromService` / `fromGroup` examples, `sync: false`, `generateValue`, combinations | +| `references/wiring-patterns.md` | `fromDatabase` / `fromService` / `fromGroup` examples and combined wiring patterns | | `references/common-mistakes.md` | Branch + previews, `buildFilter`, replicas, duplicates, preview plans, wiring mistakes | -| `references/preview-environments.md` | `previews.generation`, expiry, overrides, `previewPlan`, disks, PR workflow | +| `references/preview-environments.md` | `previews.generation`, expiry, `previews.plan`, `previewPlan`, disks, PR workflow | ## Related Skills - **render-deploy** — Deploy flows, Blueprint vs direct create, MCP/deeplinks - **render-env-vars** — Env var strategy, secrets, Dashboard vs Blueprint - **render-docker** — Dockerfile-backed services and image runtime nuances + + +## Current documentation retrieval + +Whenever this skill directs you to consult current Render documentation: + +1. Retrieve the linked Markdown document directly with an available URL-fetching tool or HTTP client, such as `curl`. Do not substitute web-search summaries for the document. +2. Confirm that retrieval succeeded and returned the expected document, then read its contents. Saving a file or printing its path is not sufficient. +3. If the request fails or your tool cannot read the Markdown response, open and read the linked HTML version instead. +4. If neither version can be retrieved, disclose that the current reference is unavailable and follow any topic-specific fallback in the skill. Use bundled guidance only for stable constraints, and do not guess at changeable platform details. + +When a task requires multiple references, apply this workflow to each one and distinguish the documents you verified from those that remain unavailable. + diff --git a/skills/render-blueprints/references/blueprints.md b/skills/render-blueprints/references/blueprints.md new file mode 100644 index 0000000..35a7b23 --- /dev/null +++ b/skills/render-blueprints/references/blueprints.md @@ -0,0 +1,31 @@ + +## Render Blueprints + +A Render Blueprint is a declarative YAML definition of interconnected Render services, databases, and environment groups. The file is usually named `render.yaml` and stored at the root of a Git repository, although its path can be customized when the Blueprint is created. + +Blueprint creation and sync read the file from the linked remote Git repository. Local edits are not available to Render until they are committed and pushed to that repository. + +Do not rely on remembered Blueprint fields, allowed values, defaults, or update behavior. Before creating or modifying a Blueprint, use the documentation-retrieval workflow in the root `SKILL.md` to retrieve and read the [Markdown reference](https://render.com/docs/blueprint-spec.md) or its [HTML version](https://render.com/docs/blueprint-spec). + +If neither version can be retrieved, use the current JSON Schema and Render validation where possible. Use the bundled guidance only for stable workflow and safety constraints, and do not guess at unfamiliar or potentially changed syntax. + +Read the sections relevant to every resource and field being changed. In particular, confirm required fields, service-type support, immutable fields, defaults for new resources, behavior for existing resources, and whether omitting or emptying a field preserves or removes existing configuration. Do not treat an example Blueprint as a complete specification. + +Use the public JSON Schema for editor or programmatic validation: + +```text +https://render.com/schema/render.yaml.json +``` + +When Render CLI v2.7.0 or later is available, validate the finished file: + +```bash +render blueprints validate render.yaml +``` + +Fix validation errors before presenting the Blueprint as ready to deploy. Validation does not apply, sync, or deploy the Blueprint. Schema validation checks structure; Render CLI or API validation can also catch platform-aware errors. If copied examples, the schema, and Render validation disagree, prefer the configuration accepted by current Render validation and call out the discrepancy. + +Blueprint resource names are used to associate definitions with existing resources. Before reusing or changing a name, verify that the Blueprint will manage the intended resource. Do not define the same resource in more than one location, such as both a root-level list and a project environment or `ungrouped`. + +Treat edits to an existing Blueprint as infrastructure changes, not ordinary text edits. Review the proposed diff for replacements, removals, immutable-field changes, and destructive declarative behavior before applying or recommending a sync. Never hardcode secret values in a Blueprint; consult the current environment-variable sections of the specification for supported secret mechanisms and their limitations. + diff --git a/skills/render-blueprints/references/common-mistakes.md b/skills/render-blueprints/references/common-mistakes.md index 236efcf..fa4d398 100644 --- a/skills/render-blueprints/references/common-mistakes.md +++ b/skills/render-blueprints/references/common-mistakes.md @@ -43,7 +43,8 @@ Symptoms, causes, and fixes for frequent `render.yaml` errors. | `env` | `runtime` | | `redis` (service type) | `keyvalue` (alias `redis` if still accepted—prefer `keyvalue` in new files) | | `autoDeploy` | `autoDeployTrigger` | -| `pullRequestPreviewsEnabled` | `previews.generation` (`off` / `manual` / `automatic`) | +| Top-level `previewsEnabled: true` | Top-level `previews.generation: automatic` | +| Service-level `pullRequestPreviewsEnabled: true` | Service-level `previews.generation: automatic`; omit `generation` to disable service previews | **Fix:** Migrate to current keys; run schema validation against `https://render.com/schema/render.yaml.json`. @@ -59,13 +60,13 @@ Symptoms, causes, and fixes for frequent `render.yaml` errors. --- -## 6. Mixing flexible and non-flexible instance types in `previewPlan` +## 6. Using the wrong preview-plan field -**Mistake:** `plan` uses one instance family and `previewPlan` uses an incompatible (flex vs non-flex) type. +**Mistake:** Setting `previewPlan` on a compute service, setting `previews.plan` on Key Value or Postgres, or mixing flexible and legacy Postgres compute plans between `plan` and `previewPlan`. **Effect:** Preview deploy failures or plan validation errors. -**Fix:** Match preview plan family to primary plan constraints per Render’s current plan catalog; when unsure, set `previewPlan` to a conservative plan in the same family or validate via CLI. +**Fix:** Use `previews.plan` for web, private, worker, and cron services. Use `previewPlan` for Key Value and Postgres, and keep Postgres plans in compatible instance families. --- diff --git a/skills/render-blueprints/references/compute-plans.md b/skills/render-blueprints/references/compute-plans.md new file mode 100644 index 0000000..5d0ccc1 --- /dev/null +++ b/skills/render-blueprints/references/compute-plans.md @@ -0,0 +1,23 @@ + +## Compute plans + +A compute plan determines the CPU and RAM available to each instance of a Render service. Use **compute plan**, not the former term **instance type**. Do not confuse a service's compute plan with its workspace plan, which controls account-level features and limits. + +Compute plans differ by service type: + +- Web services, private services, background workers, and cron jobs use CPU-and-memory plan IDs such as `0.5c-512mb` and `1c-2g`. +- Render Postgres has its own plan catalog and connection limits. +- Render Key Value uses memory-based plan IDs such as `256mb` and `1g`. +- Workflow tasks select a compute plan in application code; a Workflow service does not set a Blueprint `plan`. +- Static sites do not have compute plans. + +Legacy plan names such as `starter`, `standard`, and `pro` remain valid in Render tooling, including Blueprints and API requests. For new configuration, prefer the current plan ID when the selected configuration surface accepts it. Before passing a plan to an API, MCP tool, or CLI command, inspect that operation's current schema or help and use one of its accepted values; the compute-plan reference describes the product catalog, not every tool version's input contract. Do not rename an existing legacy plan merely for consistency unless the user asks for that change. + +Do not rely on a memorized plan catalog. When a task depends on current plan IDs, specifications, defaults, availability, or pricing, fetch the canonical compute-plan reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/compute-plans.md) or its [HTML version](https://render.com/docs/compute-plans). + +Read the section for the relevant service type. If the document cannot be fetched, do not guess at current plan details. Preserve an existing valid plan where possible, or explain that the plan must be confirmed in the Render Dashboard or current documentation. + +When estimating capacity or cost, remember that every instance of a scaled service uses the selected compute plan and is billed accordingly. Changing the compute plan for Render Postgres, Render Key Value, or a service with an attached persistent disk requires brief downtime; other services normally apply the change with a zero-downtime deploy. + diff --git a/skills/render-blueprints/references/environment-variables.md b/skills/render-blueprints/references/environment-variables.md new file mode 100644 index 0000000..e9de03c --- /dev/null +++ b/skills/render-blueprints/references/environment-variables.md @@ -0,0 +1,38 @@ + +## Environment variables and secrets + +Render environment-variable values are strings. Applications must explicitly parse values that represent booleans, numbers, lists, or structured data; for example, the string `"false"` is truthy in many languages. + +Environment variables can be managed through the Render Dashboard, Blueprints, environment groups, and supported API, MCP, or CLI operations. Before changing a service, determine which mechanism is intended to be the source of truth. Do not make parallel Dashboard and infrastructure-as-code edits without explaining how future syncs or deploys will reconcile them. + +Never commit secret values to application source, `render.yaml`, checked-in `.env` files, fixtures, examples, or logs. Keep local secret-bearing `.env` files out of version control. Do not print or repeat secret values returned by the user, Render, or another provider. Use Render's supported secret mechanisms or an external secret manager appropriate to the user's workflow. + +Before configuring environment variables, secret files, or environment groups, fetch the current Render configuration reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/configure-environment-variables.md) or its [HTML version](https://render.com/docs/configure-environment-variables). + +Read the sections relevant to the configuration surface being used. Dashboard save options can rebuild and deploy, deploy the existing build, or save without deploying; do not assume a changed value is active until the applicable deploy occurs. + +For Blueprint-managed variables, also consult the current Blueprint YAML reference before writing syntax or predicting update behavior. In particular: + +- Use literal `value` entries only for non-sensitive configuration. +- `generateValue: true` creates a platform-generated secret when the variable does not already exist. +- `sync: false` prompts for a value only during initial Blueprint creation. It is ignored for existing services during later Blueprint updates, is not included in preview environments, and is not valid in environment groups. +- Use current `fromDatabase`, `fromService`, and `fromGroup` syntax instead of hardcoding connection strings or copying shared values. + +Blueprint syncs preserve existing service environment variables that are omitted from the Blueprint; omission does not delete them. Values defined with `fromDatabase` or `fromService` refresh on each Blueprint sync, not immediately when the referenced property or variable changes. + +Environment groups provide shared variables and secret files to linked services. A variable defined directly on a service takes precedence over the same key from a linked group. Precedence between multiple linked groups with the same key is not guaranteed; avoid collisions instead of depending on group creation order. Respect project-environment scoping when linking groups to services. + +Use secret files for credentials or configuration that must be read from the filesystem rather than an environment variable. Confirm current size and runtime-path rules in the fetched reference. Treat secret-file contents with the same precautions as other credentials. + +Render also injects documented default environment variables. Do not maintain a memorized catalog. Fetch the current default-variable reference when a task depends on a variable's name, availability, build/runtime scope, or semantics: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/environment-variables.md) or its [HTML version](https://render.com/docs/environment-variables). + +Depend only on documented platform variables. Other `RENDER_*` variables are internal and can change without notice. + +Treat environment-variable changes as service configuration mutations. Confirm the target workspace and service, inspect the existing keys without exposing their values, and preserve variables outside the user's requested scope. Before using an API, MCP, or CLI operation, check whether it patches individual keys or replaces the complete collection. After the applicable deploy, verify that required keys are present and that the service starts successfully without logging secret values. + +If the current references or live configuration cannot be inspected, do not guess at secret behavior, precedence, or replacement semantics. Preserve existing configuration where possible and explain what must be confirmed before making the change. + diff --git a/skills/render-blueprints/references/field-reference.md b/skills/render-blueprints/references/field-reference.md index a584721..f40eb99 100644 --- a/skills/render-blueprints/references/field-reference.md +++ b/skills/render-blueprints/references/field-reference.md @@ -20,7 +20,6 @@ Applies broadly to `web`, `pserv`, `worker`, `cron`, and often `keyvalue` where | `runtime` | `node`, `python`, `go`, `ruby`, `rust`, `elixir`, `docker`, `image`, `static`. **Immutable after create.** | | `region` | Deploy region. | | `plan` | Instance/plan slug. | -| `previewPlan` | Plan used for preview instances; constraints vs primary `plan` (see preview doc). | | `branch` | Git branch to deploy. | | `rootDir` | Subdirectory for repo context. | | `buildCommand` | Build step(s). | @@ -28,18 +27,19 @@ Applies broadly to `web`, `pserv`, `worker`, `cron`, and often `keyvalue` where | `preDeployCommand` | Command before deploy rollout. | | `autoDeployTrigger` | `commit`, `checksPass`, or `off`. | | `maxShutdownDelaySeconds` | 1–300; default **30**. | -| `healthCheckPath` | HTTP path for health checks (`web` / some others as applicable). | +| `healthCheckPath` | HTTP path for health checks (web services only). | | `domains` | Custom domains list. | | `envVars` | List of env var objects (see [Env vars patterns](#env-vars-patterns)). | | `buildFilter` | Limit builds to path changes (see [buildFilter](#buildfilter)). | | `disk` | Persistent disk attachment (see [disk](#disk)). | | `scaling` | Autoscaling settings (see [scaling](#scaling)). | | `numInstances` | Manual instance count; interacts with `scaling`. | -| `registryCredential` | For private registry pulls (`image` runtime / images). | +| `registryCredential` | For private base images in a `runtime: docker` build. | +| `image` | For `runtime: image`: `url` plus optional `creds.fromRegistryCreds`. | | `dockerfilePath` | Path to Dockerfile (`docker` runtime). | | `dockerContext` | Docker build context path. | | `dockerCommand` | Override container command. | -| `previews` | Service-level preview overrides (e.g. `generation`). | +| `previews` | Mixed preview settings: `generation` configures independent service previews; `plan` and `numInstances` configure the service in preview environments. | **Cron-specific** @@ -96,9 +96,9 @@ Applies broadly to `web`, `pserv`, `worker`, `cron`, and often `keyvalue` where | Field | Notes | |-------|--------| | `name` | Group identifier for `fromGroup`. | -| `envVars` | Same patterns as service `envVars` (`value`, `generateValue`, `fromDatabase`, `fromService`, etc.). | +| `envVars` | Variables may use `value` or `generateValue`; they cannot reference services, databases, or other groups. | -**Constraint:** `sync: false` is **not valid** in env var groups (see wiring / mistakes docs). +**Constraints:** `sync: false`, `fromDatabase`, `fromService`, and `fromGroup` are **not valid** in env var groups. --- @@ -112,7 +112,6 @@ Projects group one or more **environments** (e.g. production, staging) under a s |-------|--------| | `name` | Project name (appears in Dashboard). | | `environments` | List of environment blocks. | -| `envVarGroups` | Env var groups scoped to the project (shared across its environments). | ### Environment fields @@ -129,7 +128,7 @@ Each environment is a self-contained set of resources: - **No duplication:** Define each resource in **one** place: either at the root level **or** inside a single environment. Never both. - **Cross-environment wiring:** `fromDatabase` and `fromService` resolve within the same environment. Referencing resources across environments is not supported in Blueprint YAML. -- **Environment isolation:** On Professional and higher plans, environments can be isolated so services in different environments cannot reach each other over the private network. +- **Environment isolation:** With a Pro workspace or higher, environments can be isolated so services in different environments cannot reach each other over the private network. - **When to use projects:** Multiple services that belong together, staging/production parity, environment-scoped env groups. Single-service apps can use flat top-level lists instead. --- @@ -141,7 +140,7 @@ Each environment is a self-contained set of resources: | `generation` | `off` (default), `manual`, or `automatic`. | | `expireAfterDays` | Delete preview environments after N days. | -Services may override selected preview behavior. +Top-level `previews.generation` controls preview environments. Service-level `previews.generation` instead controls independent service previews, accepts only `manual` or `automatic`, and does not override the top-level setting. Omit it to disable service previews. --- @@ -154,7 +153,7 @@ Each entry is typically keyed by `key` plus **one** of: | `value` | Inline literal. | | `generateValue` | Render generates a random secret. | | `sync` | `false` = do not sync from Blueprint after initial setup (secrets); see limitations in preview/group docs. | -| `fromDatabase` | Pull DB host, port, user, password, database, or `connectionString`. | +| `fromDatabase` | Pull DB host, port, user, password, database, `connectionString`, or `connectionPoolString`. | | `fromService` | Pull host/port/connection info from another service. | | `fromGroup` | Import vars from an `envVarGroup` by name. | @@ -176,13 +175,13 @@ Each entry is typically keyed by `key` plus **one** of: ## disk -Attached disk object on a service: +Before configuring an attached service disk, read [persistent-disks.md](persistent-disks.md) for its architectural constraints and confirm the current schema in the Blueprint specification. | Field | Notes | -|-------|--------| +|-------|-------| | `name` | Disk identifier. | -| `mountPath` | Mount path in the instance filesystem. | -| `sizeGB` | Size in GB. | +| `mountPath` | Absolute mount path in the instance filesystem. | +| `sizeGB` | Provisioned disk capacity in GB. | --- @@ -216,6 +215,7 @@ Limit which Git changes trigger builds: | Field | Notes | |-------|--------| | `name`, `region`, `plan` | Standard resource fields. | +| `previewPlan` | Plan for preview Key Value instances. | | `maxmemoryPolicy` | Eviction policy string. | | `ipAllowList` | **Required** for proper network restriction in typical setups—do not omit unless you explicitly accept open access per product rules. | diff --git a/skills/render-blueprints/references/persistent-disks.md b/skills/render-blueprints/references/persistent-disks.md new file mode 100644 index 0000000..3ba9242 --- /dev/null +++ b/skills/render-blueprints/references/persistent-disks.md @@ -0,0 +1,29 @@ + +## Persistent disks + +Use this guidance only for service-attached persistent disks and for architecture or configuration decisions directly affected by them. Do not apply it to Render Postgres or Key Value storage, object storage, build caches, or ordinary ephemeral filesystem tasks. + +By default, a Render service's filesystem is ephemeral. Files created or changed at runtime are lost when the service is redeployed or restarted. Use a persistent disk only when a supported service must retain local filesystem data across those events. + +Before designing, configuring, or troubleshooting a persistent disk, fetch the current documentation: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/disks.md) or its [HTML version](https://render.com/docs/disks). + +Read the relevant sections before relying on details that can change, including supported service types, size limits and pricing, mount-path restrictions, snapshot cadence and retention, transfer methods, and current scaling or deployment limitations. If the document cannot be fetched, do not guess those details from memory. + +A persistent disk belongs to one service and is mounted at one absolute path. Only files written under that mount path persist; the rest of the service filesystem remains ephemeral. Make sure the application writes every intended durable file beneath the configured mount path. A disk is not shared storage, and another service cannot access it. + +Under the documented generally available behavior, a disk-backed service runs as a single instance and cannot use autoscaling or zero-downtime deploys. During a deploy, Render stops the existing instance before starting its replacement, so expect a short interruption. If the workload needs horizontal scaling, shared state, or stronger availability, use an external or managed datastore instead of a service-attached disk. + +The disk is available only to the running service. Builds, pre-deploy commands, and one-off jobs run on separate compute and cannot access it. Do not design a build step, pre-deploy command, or one-off job that depends on files stored on the mounted disk. + +The documented supported service types are paid web services, private services, and background workers. For other workload types, use an appropriate external datastore or reconsider the service architecture rather than assuming a disk can be attached. + +Disk capacity can be increased but not decreased. Confirm current limits and pricing in the fetched documentation, and choose capacity using observed usage plus reasonable headroom. + +Treat attaching, resizing, or restoring a disk as a stateful mutation. After attaching, verify that the service deploys successfully and that reads and writes use the mounted path. + +Snapshots are a disaster-recovery mechanism, not a substitute for application-consistent database backups. A snapshot restore replaces the entire disk; it cannot restore individual files, and it discards changes made after that snapshot. Do not use a disk snapshot to recover a custom database, because a filesystem-level snapshot can restore the database into an inconsistent or corrupted state. Use the database engine's native backup and restore tools instead. Check the current documentation before promising a particular snapshot schedule, retention period, or restore procedure. + +Mount paths must be absolute and must satisfy Render's current restrictions. Fetch the documentation instead of reproducing its forbidden-path list or runtime-specific path suggestions from memory. When declaring a disk in a Blueprint, also fetch the current Blueprint specification and follow its disk schema rather than relying on remembered syntax. + diff --git a/skills/render-blueprints/references/preview-environments.md b/skills/render-blueprints/references/preview-environments.md index 2d40d21..6b11d0c 100644 --- a/skills/render-blueprints/references/preview-environments.md +++ b/skills/render-blueprints/references/preview-environments.md @@ -25,9 +25,9 @@ previews: --- -## Service-level override +## Service previews vs. preview environments -Individual services may override preview generation: +Service-level `previews.generation` configures a service's independent pull request previews. It does **not** override the Blueprint's top-level preview-environment generation mode. ```yaml services: @@ -36,18 +36,40 @@ services: runtime: node # ... previews: - generation: off + generation: manual ``` -Use this when a heavy or sensitive service should not run in every preview (e.g. workers that touch billing). +The only supported service-level generation values are `manual` and `automatic`. Omit `previews.generation` to disable service previews. Do not set it to `off`, and do not use it to try to exclude a resource from preview environments. --- -## `previewPlan` constraints +## Preview compute plans -- **`previewPlan`** selects the instance type for preview **service** instances. -- **Cannot mix** flexible and non-flexible instance types between **`plan`** and **`previewPlan`** in ways Render rejects (same family constraints as production). -- If previews fail validation, align `previewPlan` with the primary `plan` category or choose a supported preview size. +- For web services, private services, background workers, and cron jobs, set **`previews.plan`**. Despite sharing an object with the service-preview generation field, this field controls the compute plan used in preview environments. +- Set **`previews.numInstances`** to control the service's instance count in preview environments. +- For Key Value and Postgres instances, set **`previewPlan`**. +- For Postgres, `plan` and `previewPlan` must both use flexible compute plans or both use legacy compute plans. +- If no preview compute plan is specified, Render uses the base resource's compute plan. + +Use `compute-plans.md` for current Plan IDs and availability rather than copying plan catalogs into this preview-specific reference. + +```yaml +services: + - type: web + name: api + plan: standard + previews: + plan: starter + - type: keyvalue + name: cache + plan: standard + previewPlan: starter + ipAllowList: [] +databases: + - name: db + plan: pro-4gb + previewPlan: basic-1gb +``` --- @@ -78,7 +100,7 @@ Use this when a heavy or sensitive service should not run in every preview (e.g. ## PR workflow — how previews map to Git 1. A **pull request** is opened against the tracked branch (e.g. `main`). -2. Render uses the **PR head commit** (and Blueprint at that revision) to propose or create a preview stack, depending on `previews.generation` and service overrides. +2. Render uses the **PR head commit** (and Blueprint at that revision) to propose or create a preview environment according to the top-level `previews.generation` setting. 3. **Build filters** and **branch** settings on services still matter: misconfigured `branch` can break the expectation that previews track the PR (see `common-mistakes.md`). 4. When the PR closes or merges, previews are typically torn down per product rules; **`expireAfterDays`** enforces a maximum lifetime regardless. @@ -88,9 +110,10 @@ Use this when a heavy or sensitive service should not run in every preview (e.g. - [ ] `previews.generation` matches team workflow (`off` / `manual` / `automatic`). - [ ] `expireAfterDays` set if org needs automatic cleanup. -- [ ] `previewPlan` compatible with primary `plan`. +- [ ] Compute services use `previews.plan`; Key Value and Postgres use `previewPlan`. +- [ ] Postgres `previewPlan` is compatible with the primary `plan` family. - [ ] `previewDiskSizeGB` (if used) sufficient for migrations. - [ ] No reliance on `sync: false` secrets without a preview secret strategy. -- [ ] Service-level `previews` overrides reviewed for workers/cron/private services. +- [ ] Any service-level `previews.generation` setting is intentional and treated separately from preview-environment generation. Validate with `render blueprints validate` and `https://render.com/schema/render.yaml.json`. diff --git a/skills/render-blueprints/references/private-networking.md b/skills/render-blueprints/references/private-networking.md new file mode 100644 index 0000000..d68d6be --- /dev/null +++ b/skills/render-blueprints/references/private-networking.md @@ -0,0 +1,25 @@ + +## Private networking + +Render services can communicate over a private network without traversing the public internet. Private-network peers must belong to the same workspace and run in the same region. An isolated project environment can additionally block traffic both to and from resources outside that environment, so workspace and region matching alone do not guarantee connectivity. + +Before designing, configuring, or troubleshooting private-network communication, fetch the current Render private-network reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/private-network.md) or its [HTML version](https://render.com/docs/private-network). + +Read the relevant sections. Confirm current service-type capabilities, port restrictions, environment-isolation behavior, discovery-hostname guidance, and plan requirements instead of relying on a memorized catalog. + +Web services and private services have internal hostnames and can receive private-network traffic. A private service must bind at least one port; use a background worker instead when a workload does not need to accept inbound connections. Render Postgres and Key Value instances provide internal connection URLs. Workflows, background workers, and cron jobs can initiate private-network connections but do not have an internal address for receiving them. Static sites are not on the private network. Free web services can initiate private-network connections but cannot receive them. + +Prefer the internal address or URL shown under **Connect > Internal** in the Render Dashboard. Include the protocol when the client or server requires one; an address such as `service:10000` does not by itself establish whether to use HTTP, HTTPS, or another protocol. A process that receives traffic must listen on the intended port and on an interface reachable outside its own container, such as `0.0.0.0`, rather than only on loopback. + +For Blueprint-managed connections, fetch the current Blueprint specification and use supported service or database references instead of copying a generated hostname, port, credential, or connection string. Web and private services currently expose `host`, `port`, and `hostport` properties. A Blueprint can obtain another service's discovery hostname by referencing that service's `RENDER_DISCOVERY_SERVICE` environment variable with `fromService.envVarKey`; the discovery hostname is not a service property. The fetched specification is authoritative for the syntax and supported references. + +A service can expose at most 75 ports on the private network. Ports `18012`, `18013`, and `19099` are unavailable for private-network communication. Port `10000` is not generally blocked: for a web service, private traffic to port `10000` routes to its primary HTTP server even when that server binds to another port. In that case, both port `10000` and the actual primary HTTP port route to the same server. + +Use a service's normal internal hostname for ordinary service-to-service traffic. For advanced per-instance communication, each web or private service has a discovery hostname, conventionally formed by appending `-discovery` to its internal hostname, that resolves to all active instance IP addresses. A service receives its own discovery hostname in `RENDER_DISCOVERY_SERVICE`. Use DNS APIs that honor the system resolver configuration, and do not persist resolved instance IPs because they can change between deploys. Prefer hostname-based communication unless per-instance addressing or custom load balancing is specifically required. + +When a private-network connection fails, verify the workspace, region, project-environment isolation settings, whether the destination service type accepts inbound traffic, the internal hostname or URL, protocol, port, listening interface, current deploy health, and DNS resolution. Do not substitute a public URL or expose a private service merely to bypass a private-network configuration problem. + +AWS PrivateLink is a separate Pro-or-higher feature for connecting a Render private network to compatible AWS-hosted systems. Fetch its current documentation before proposing or configuring it; do not treat ordinary Render service-to-service networking and PrivateLink as interchangeable. + diff --git a/skills/render-blueprints/references/service-types.md b/skills/render-blueprints/references/service-types.md new file mode 100644 index 0000000..a0a3786 --- /dev/null +++ b/skills/render-blueprints/references/service-types.md @@ -0,0 +1,37 @@ + +## Render service types + +Use this guidance when selecting or comparing Render service types, or when a task's architecture depends on the distinction between them. A task that is already unambiguously scoped to one service type does not need this entire overview. + +On Render, a service represents code deployed for a particular execution model. Render runs that service on one or more instances, and the service's compute plan determines the CPU and memory available to each instance. + +Before choosing a service type, fetch the current service-types reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/service-types.md) or its [HTML version](https://render.com/docs/service-types). + +If neither version can be retrieved, use the bundled overview below only for basic service-type selection. State that current platform details could not be verified, and do not guess about changeable capabilities such as supported runtimes, plans, scaling, networking, disks, health checks, deployment behavior, availability, or limits. + +Render provides six public service types for running code: + +- **Web service:** A continuously running server that receives public HTTP traffic and also has an internal hostname for private-network traffic. Use it for dynamic websites, APIs, and other internet-facing server applications. +- **Static site:** Built HTML, CSS, JavaScript, and other static assets served publicly from Render's global CDN. Use it only when the deployed application does not require server-side runtime logic. +- **Private service:** A continuously running server that receives traffic only over Render's private network. Use it for internal HTTP, TCP, gRPC, or other server processes that need an internal hostname but no public URL. +- **Background worker:** A continuously running process that does not receive incoming traffic or expose a public or internal hostname. Use it for queue consumers and other processes that pull or poll for work. +- **Cron job:** A command or process that starts on a schedule, performs a bounded unit of work, and exits. Use it for straightforward recurring tasks rather than an always-running process. +- **Workflow:** A collection of on-demand tasks executed across distributed compute, with Render handling task queuing, orchestration, and provisioning. Use it when the workload benefits from independently invoked tasks, retries, composition, or parallel execution instead of a continuously running worker process. + +Choose based on how the code executes and receives work: + +- Public incoming traffic that requires server-side logic belongs on a web service. Public static assets with no runtime server belong on a static site. +- An application that needs both public and private ingress remains a web service; use its internal hostname for traffic from other Render services. +- A process that receives private-network requests belongs on a private service. A process that only initiates connections and pulls work belongs on a background worker. +- A simple scheduled command that exits belongs on a cron job. An always-running queue consumer belongs on a background worker. On-demand or distributed tasks for which Render should manage queuing and per-run compute belong in a workflow. + +Cron jobs and Workflows use invocation-based execution models. The ordinary instance-count and autoscaling model used by continuously running services does not apply to them. + +Render Postgres and Render Key Value are fully managed datastores, not general-purpose compute service types for running application code. Use Render Postgres for relational data and Render Key Value for use cases such as shared caching and job queues. An attached persistent disk is a storage feature of certain compute services, not a service type of its own. + +After selecting a type, fetch the product article linked from the service-types reference before relying on details such as supported runtimes and sources, plans, scaling, networking, disks, health checks, deployment behavior, scheduling semantics, availability, or limits. These capabilities are not uniform across service types and can change independently. + +Human-facing service names do not always map directly to configuration identifiers or structure. When creating or editing a Blueprint, fetch the current Blueprint specification and use its service-type schema instead of inferring fields or values from this overview. In particular, do not assume that every Dashboard service type has a same-named Blueprint `type` or that managed datastores are declared like compute services. + diff --git a/skills/render-blueprints/references/wiring-patterns.md b/skills/render-blueprints/references/wiring-patterns.md index 7beb550..92ba56b 100644 --- a/skills/render-blueprints/references/wiring-patterns.md +++ b/skills/render-blueprints/references/wiring-patterns.md @@ -1,6 +1,6 @@ # Cross-Service Wiring Patterns -Complete examples for wiring services together in `render.yaml` via `envVars`. +Read [environment-variables.md](environment-variables.md) first for current syntax discovery, secret handling, precedence, and mutation safety. When wiring an internal service address or discovery hostname, also read [private-networking.md](private-networking.md). This reference retains cross-resource wiring examples for `render.yaml`. --- @@ -21,6 +21,7 @@ Available properties: | Property | Value | |----------|-------| | `connectionString` | Full `postgres://` URL (most common) | +| `connectionPoolString` | Managed PgBouncer URL when connection pooling is enabled | | `host` | Database hostname | | `port` | Database port | | `user` | Database user | @@ -51,7 +52,6 @@ Available properties: | `connectionString` | Full `redis://` URL | | `host` | Internal hostname | | `port` | Port number | -| `hostport` | `host:port` combined | --- @@ -88,6 +88,7 @@ Available properties for `pserv` and `web`: | Property | Value | |----------|-------| | `host` | Internal hostname | +| `port` | Listening port | | `hostport` | `host:port` combined | Use `envVarKey` to copy a specific environment variable value from the other service. @@ -107,34 +108,6 @@ This adds all variables from the named group to the service. The group must exis --- -## generateValue - -Generate a random base64-encoded 256-bit secret: - -```yaml -envVars: - - key: APP_SECRET - generateValue: true -``` - -The value is generated once on initial Blueprint creation and persists across syncs. - ---- - -## sync: false - -Prompt the user to provide a value in the Dashboard: - -```yaml -envVars: - - key: STRIPE_API_KEY - sync: false -``` - -Use for secrets that should never appear in the Blueprint file. - ---- - ## Combined Example A web service wired to Postgres, Key Value, and a private service: @@ -179,13 +152,11 @@ services: name: cache plan: starter maxmemoryPolicy: allkeys-lru - ipAllowList: - - source: 0.0.0.0/0 - description: everywhere + ipAllowList: [] # Internal access only databases: - name: db - plan: starter + plan: basic-256mb envVarGroups: - name: shared-config @@ -198,8 +169,4 @@ envVarGroups: ## Edge Cases -- **sync: false only prompts on initial Blueprint setup.** On subsequent syncs, existing `sync: false` values are preserved. Adding a new `sync: false` var to an existing Blueprint does not prompt. -- **sync: false is excluded from preview environments.** Users must set these values manually for each preview. -- **sync: false is invalid in envVarGroups.** It is silently ignored if used in a group definition. - **fromService/fromDatabase can reference services outside the Blueprint** but the referenced service must already exist in the workspace. -- **generateValue** generates once on initial create. It does not regenerate on subsequent Blueprint syncs. diff --git a/skills/render-cli/SKILL.md b/skills/render-cli/SKILL.md index 900227e..2c816e3 100644 --- a/skills/render-cli/SKILL.md +++ b/skills/render-cli/SKILL.md @@ -20,6 +20,8 @@ metadata: The Render CLI manages services, databases, and deployments from the terminal. Supports interactive use, non-interactive scripting, and CI/CD automation. +Before installing, authenticating, selecting a workspace, or running commands, read `references/render-access.md` for the current access and command-discovery workflow. + ## When to Use - **Deploying** a service from the terminal or CI/CD @@ -30,74 +32,9 @@ The Render CLI manages services, databases, and deployments from the terminal. S - **Scripting** Render operations in CI/CD pipelines - **Installing** agent skills for AI coding tools -## Installation - -| Method | Command | -|--------|---------| -| **Homebrew** | `brew update && brew install render` | -| **Linux/macOS** | `curl -fsSL https://raw.githubusercontent.com/render-oss/cli/refs/heads/main/bin/install.sh \| sh` | -| **Direct download** | [GitHub releases](https://github.com/render-oss/cli/releases/) | -| **Build from source** | `git clone git@github.com:render-oss/cli.git && cd cli && go build -o render` | - -After install, run `render` with no arguments to confirm. - -## Authentication - -### Interactive (local dev) - -```bash -render login -``` - -Opens the browser to generate a CLI token. Token is saved to `~/.render/cli.yaml`. Tokens expire periodically—re-run `render login` when prompted. - -### Non-interactive (CI/CD) - -```bash -export RENDER_API_KEY=rnd_... -``` - -API keys do not expire. Generate one from **Account Settings > API Keys** in the Dashboard. The API key takes precedence over CLI tokens when set. - -Set the active workspace: - -```bash -render workspace set -``` - ## Command Reference -### Core commands - -| Command | Purpose | Key flags | -|---------|---------|-----------| -| `render login` | Authenticate via browser | — | -| `render workspace set` | Set active workspace | — | -| `render services` | List all services and datastores | `-o json` for scripting | -| `render deploys create [SVC]` | Trigger a deploy | `--wait`, `--commit SHA`, `--image URL` | -| `render deploys list [SVC]` | List deploys for a service | `-o json` | -| `render logs -r [SVC]` | View logs | `--tail` for streaming | -| `render psql [DB]` | Open psql session | `-c "SQL"`, `-o json`, `-- --csv` | -| `render ssh [SVC]` | SSH into running instance | `--ephemeral` / `-e` for isolated shell | -| `render blueprints validate` | Validate `render.yaml` | Defaults to `./render.yaml` | -| `render skills [install\|update\|list]` | Manage agent skills | — | -| `render workspaces` | List workspaces | `-o json` | - -### Non-interactive mode - -For CI/CD and scripts, always set: - -| Flag | Purpose | -|------|---------| -| `-o json` (or `yaml`, `text`) | Machine-readable output | -| `--confirm` | Skip confirmation prompts | - -Output format precedence: `--output` flag > `RENDER_OUTPUT` env var > auto-detect (TTY → interactive, pipe → text). - -```bash -export RENDER_OUTPUT=json -render services --confirm -``` +Use the installed CLI help or generated command reference as directed by `references/render-access.md` for the exact command surface and flags. The patterns below cover common operational workflows. ### Deploy patterns @@ -135,38 +72,37 @@ jobs: steps: - name: Install Render CLI run: | - curl -L https://github.com/render-oss/cli/releases/download/v1.1.0/cli_1.1.0_linux_amd64.zip -o render.zip - unzip render.zip - sudo mv cli_v1.1.0 /usr/local/bin/render + curl --fail-with-body --silent --show-error --location \ + https://raw.githubusercontent.com/render-oss/cli/refs/heads/main/bin/install.sh \ + --output /tmp/install-render-cli.sh + sudo sh /tmp/install-render-cli.sh + render --version - name: Deploy env: RENDER_API_KEY: ${{ secrets.RENDER_API_KEY }} run: render deploys create ${{ secrets.RENDER_SERVICE_ID }} --wait --confirm -o json ``` -Pin to a specific CLI version in CI to avoid breaking changes. +If reproducible builds require a pinned CLI, select a currently supported release and verify its asset name in the current release documentation instead of copying a version from this skill. ## Local Config Config file: `~/.render/cli.yaml` -Override with `RENDER_CLI_CONFIG_PATH` env var. +Override the configuration directory with `RENDER_CLI_CONFIG_DIR`. `RENDER_CLI_CONFIG_PATH` is a legacy file-level override retained for compatibility and is scheduled for deprecation. ## Common Mistakes | Mistake | Fix | |---------|-----| -| Token expired | Re-run `render login` | -| Wrong workspace | Run `render workspace set` to switch | -| Missing `--confirm` in CI | Add `--confirm` to skip interactive prompts | -| Using `--output interactive` in CI | Use `-o json` or `-o text` in non-TTY environments | | Deploying without `--wait` in CI | Add `--wait` so the job fails on deploy failure | ## References | Document | Contents | |----------|----------| -| `references/command-cheatsheet.md` | Full command list with flags, output examples, and scripting patterns | +| `references/render-access.md` | Current CLI authentication, workspace, documentation, output, and authorization workflow | +| `references/command-cheatsheet.md` | Common operational command examples and scripting patterns | ## Related Skills @@ -174,3 +110,16 @@ Override with `RENDER_CLI_CONFIG_PATH` env var. - **render-blueprints** — `render.yaml` authoring and validation - **render-postgres** — Database connections, `render psql` usage - **render-debug** — Using `render logs` and `render ssh` for troubleshooting + + +## Current documentation retrieval + +Whenever this skill directs you to consult current Render documentation: + +1. Retrieve the linked Markdown document directly with an available URL-fetching tool or HTTP client, such as `curl`. Do not substitute web-search summaries for the document. +2. Confirm that retrieval succeeded and returned the expected document, then read its contents. Saving a file or printing its path is not sufficient. +3. If the request fails or your tool cannot read the Markdown response, open and read the linked HTML version instead. +4. If neither version can be retrieved, disclose that the current reference is unavailable and follow any topic-specific fallback in the skill. Use bundled guidance only for stable constraints, and do not guess at changeable platform details. + +When a task requires multiple references, apply this workflow to each one and distinguish the documents you verified from those that remain unavailable. + diff --git a/skills/render-cli/references/command-cheatsheet.md b/skills/render-cli/references/command-cheatsheet.md index cb90197..ee37814 100644 --- a/skills/render-cli/references/command-cheatsheet.md +++ b/skills/render-cli/references/command-cheatsheet.md @@ -1,20 +1,6 @@ # Render CLI Command Cheatsheet -## Authentication - -```bash -# Interactive login (opens browser) -render login - -# CI/CD authentication (no login needed) -export RENDER_API_KEY=rnd_... - -# Set active workspace -render workspace set - -# List workspaces -render workspaces -o json -``` +For authentication, workspace selection, exact command discovery, and non-interactive output guidance, first read [render-access.md](render-access.md). ## Services @@ -118,21 +104,6 @@ render skills update render skills list ``` -## Output Formats - -| Flag | Format | Use case | -|------|--------|----------| -| `-o json` | JSON | Scripting, piping to `jq` | -| `-o yaml` | YAML | Config generation | -| `-o text` | Plain text | Human-readable in CI logs | -| `-o interactive` | Menu-based | Default in TTY | - -Set globally: - -```bash -export RENDER_OUTPUT=json -``` - ## Non-Interactive Patterns Always include `--confirm` and `-o ` for CI/CD: diff --git a/skills/render-cli/references/render-access.md b/skills/render-cli/references/render-access.md new file mode 100644 index 0000000..864c854 --- /dev/null +++ b/skills/render-cli/references/render-access.md @@ -0,0 +1,50 @@ + +## Accessing Render + +Prefer the hosted Render MCP server for structured access to Render resources when its tools are available. Use the Render CLI when MCP is unavailable or does not support the required operation, and use the Render Dashboard or API for capabilities exposed by neither. Do not assume that a remembered MCP tool or CLI command is still available; inspect the tools in the current environment or consult the current documentation. + +The hosted Render MCP server uses streamable HTTP at: + +```text +https://mcp.render.com/mcp +``` + +Official Render plugins and connectors can authenticate MCP with browser-based OAuth. Manual and non-interactive configurations can use a Render API key as a bearer token. Never write an API key or OAuth token into a repository, skill, command output, chat response, or log. Prefer the client's supported secret storage or environment-variable mechanism. If a client requires a credential in local configuration, keep that file out of version control and restrict access to it. + +Treat MCP responses as potentially sensitive even when the server attempts to minimize credential exposure. Request connection strings, credentials, secret environment variables, or other sensitive fields only when the task requires them. Do not repeat sensitive values in the response or persist them in files or logs. + +Before configuring or troubleshooting MCP, fetch the current setup and capability reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/mcp-server.md) or its [HTML version](https://render.com/docs/mcp-server). + +Read the relevant client setup, supported-actions, and limitations sections. Prefer the hosted server unless the user's environment requires a local MCP server. After installing, updating, or reconfiguring an MCP integration, reload the client as required and verify the connection with a read-only operation such as listing services. + +Most MCP operations and Render CLI commands that access Render resources are scoped to an active workspace. Check the selected workspace before reading or changing resources. If no workspace is selected—or if the intended workspace is ambiguous—list the available workspaces and have the user identify the correct one. Do not silently switch workspace context or infer it from a resource name. Commands for authentication, help, CLI configuration, and workspace discovery or selection do not require an already selected workspace. + +For interactive CLI use, authenticate with `render login`. For automation, use a securely stored `RENDER_API_KEY`; an API key takes precedence over a saved CLI token. Verify CLI access and the active workspace with read-only commands before operating on resources: + +```bash +render whoami --output json +render workspace current --output json +``` + +For CLI installation, authentication, workspace setup, and usage patterns, fetch the current CLI overview: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/cli.md) or its [HTML version](https://render.com/docs/cli). + +For exact command syntax and flags, prefer the help text from the installed CLI because it matches the version being used: + +```bash +render help +``` + +The published CLI command reference is generated automatically from the CLI's help text. Use it to browse the full command surface or when the CLI is not installed: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/cli-reference.md) or its [HTML version](https://render.com/docs/cli-reference). + +When an agent or automation invokes the CLI, select a non-interactive output format such as `--output json`, `--output yaml`, or `--output text` so results can be inspected reliably. The global `--confirm` flag skips confirmation prompts; use it for a mutating command only after that mutation is authorized. It is an execution convenience, not permission to perform the action. + +Authentication establishes access; it does not establish user authorization for every available action. Use read-only discovery to resolve workspace, resource identity, and current state before a mutation. Perform changes only when they are within the user's requested scope, and retain normal approval requirements for consequential operations such as creation, configuration changes, deploys, restarts, scaling, or deletion. + +When authentication or connectivity fails, report which access path failed, preserve the underlying error without exposing credentials, and either use an available supported fallback or explain what the user must configure before the task can continue. + diff --git a/skills/render-cron-jobs/SKILL.md b/skills/render-cron-jobs/SKILL.md index d2ae2bf..c17eb20 100644 --- a/skills/render-cron-jobs/SKILL.md +++ b/skills/render-cron-jobs/SKILL.md @@ -30,10 +30,13 @@ This skill covers **Cron Job** services on Render: how schedules run, what the p Expression cheat sheets, framework `startCommand` examples, and Heroku Scheduler migration mapping live under `references/`. +Before configuring or troubleshooting a cron job's outbound private-network connection, read `references/private-networking.md`. +When choosing between a cron job, worker, and Workflow, read `references/service-types.md`. + ## Configuration - **Schedule**: a **cron expression evaluated in UTC**, not the team’s local timezone. All times in the Dashboard and Blueprints are UTC. -- **Command**: any valid **Linux shell command** or **bash script** path. The process must **exit** when work is done—**billing is based on run duration** (prorated by the second). +- **Command**: any valid **Linux shell command** or **bash script** path. The process must **exit** when work is done because longer runs consume more billable compute. Confirm current details at [Render pricing](https://render.com/pricing). - **Source**: - **Git repository** — Render **builds on push** (same deploy model as other repo-backed services); the built artifact runs on each scheduled invocation. - **Prebuilt Docker image** — the image is **pulled before each run** and is **not retained between runs** (no warm cache of the image layer set across invocations in the same way as a long-lived service). @@ -43,7 +46,7 @@ Expression cheat sheets, framework `startCommand` examples, and Heroku Scheduler - **No persistent disk** — cron job services **cannot** provision or attach Render persistent disks; plan for object storage or databases instead. - **Single-run guarantee** — at most **one active run** per cron service at a time. A new scheduled tick does not start a second overlapping instance. - **Maximum run length**: **12 hours** per invocation. -- **Pricing**: **$1/month minimum** per cron job service; usage is **prorated by the second** beyond plan/minimum rules that apply to your account. +- **Pricing**: Running cron jobs incurs an additional cost. Confirm current details at [Render pricing](https://render.com/pricing). - **Private network**: cron jobs **can send** traffic **to** other services on the private network; they **cannot receive** inbound private-network connections (no internal hostname for accepting traffic from other services). ## Execution Behavior @@ -98,6 +101,8 @@ services: | Topic | File | |--------|------| +| Private-network scope, internal addresses, and troubleshooting | `references/private-networking.md` | +| Service-type selection and execution models | `references/service-types.md` | | Expression examples, framework commands, errors, env vars | `references/cron-patterns.md` | | Heroku Scheduler → Render mapping, blueprint example | `references/migration-from-scheduler.md` | @@ -107,3 +112,16 @@ services: - **render-blueprints** — Full `render.yaml` schema, previews, common mistakes - **render-background-workers** — Long-lived processes, queues, no 12h cap - **render-workflows** — Orchestrated and parallel jobs, often triggered on a schedule from cron + + +## Current documentation retrieval + +Whenever this skill directs you to consult current Render documentation: + +1. Retrieve the linked Markdown document directly with an available URL-fetching tool or HTTP client, such as `curl`. Do not substitute web-search summaries for the document. +2. Confirm that retrieval succeeded and returned the expected document, then read its contents. Saving a file or printing its path is not sufficient. +3. If the request fails or your tool cannot read the Markdown response, open and read the linked HTML version instead. +4. If neither version can be retrieved, disclose that the current reference is unavailable and follow any topic-specific fallback in the skill. Use bundled guidance only for stable constraints, and do not guess at changeable platform details. + +When a task requires multiple references, apply this workflow to each one and distinguish the documents you verified from those that remain unavailable. + diff --git a/skills/render-cron-jobs/references/migration-from-scheduler.md b/skills/render-cron-jobs/references/migration-from-scheduler.md index 077fe11..a4483dd 100644 --- a/skills/render-cron-jobs/references/migration-from-scheduler.md +++ b/skills/render-cron-jobs/references/migration-from-scheduler.md @@ -41,7 +41,7 @@ Set `buildCommand` to install dependencies (e.g., `bundle install`, `pip install | Concurrent runs | May overlap | Single-run guarantee (at most one active) | | Execution guarantee | Best-effort (may skip) | Reliable (runs at scheduled time) | | Dedicated service | No (runs on a one-off dyno) | Yes (own build/deploy cycle) | -| Cost model | Per-dyno-second | $1/month minimum + per-second billing | +| Cost model | Usage-based | Incurs an additional cost; confirm at [Render pricing](https://render.com/pricing) | | Persistent disk | N/A | Not available | --- @@ -69,7 +69,7 @@ services: databases: - name: my-db - plan: starter + plan: basic-256mb ``` --- diff --git a/skills/render-cron-jobs/references/private-networking.md b/skills/render-cron-jobs/references/private-networking.md new file mode 100644 index 0000000..d68d6be --- /dev/null +++ b/skills/render-cron-jobs/references/private-networking.md @@ -0,0 +1,25 @@ + +## Private networking + +Render services can communicate over a private network without traversing the public internet. Private-network peers must belong to the same workspace and run in the same region. An isolated project environment can additionally block traffic both to and from resources outside that environment, so workspace and region matching alone do not guarantee connectivity. + +Before designing, configuring, or troubleshooting private-network communication, fetch the current Render private-network reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/private-network.md) or its [HTML version](https://render.com/docs/private-network). + +Read the relevant sections. Confirm current service-type capabilities, port restrictions, environment-isolation behavior, discovery-hostname guidance, and plan requirements instead of relying on a memorized catalog. + +Web services and private services have internal hostnames and can receive private-network traffic. A private service must bind at least one port; use a background worker instead when a workload does not need to accept inbound connections. Render Postgres and Key Value instances provide internal connection URLs. Workflows, background workers, and cron jobs can initiate private-network connections but do not have an internal address for receiving them. Static sites are not on the private network. Free web services can initiate private-network connections but cannot receive them. + +Prefer the internal address or URL shown under **Connect > Internal** in the Render Dashboard. Include the protocol when the client or server requires one; an address such as `service:10000` does not by itself establish whether to use HTTP, HTTPS, or another protocol. A process that receives traffic must listen on the intended port and on an interface reachable outside its own container, such as `0.0.0.0`, rather than only on loopback. + +For Blueprint-managed connections, fetch the current Blueprint specification and use supported service or database references instead of copying a generated hostname, port, credential, or connection string. Web and private services currently expose `host`, `port`, and `hostport` properties. A Blueprint can obtain another service's discovery hostname by referencing that service's `RENDER_DISCOVERY_SERVICE` environment variable with `fromService.envVarKey`; the discovery hostname is not a service property. The fetched specification is authoritative for the syntax and supported references. + +A service can expose at most 75 ports on the private network. Ports `18012`, `18013`, and `19099` are unavailable for private-network communication. Port `10000` is not generally blocked: for a web service, private traffic to port `10000` routes to its primary HTTP server even when that server binds to another port. In that case, both port `10000` and the actual primary HTTP port route to the same server. + +Use a service's normal internal hostname for ordinary service-to-service traffic. For advanced per-instance communication, each web or private service has a discovery hostname, conventionally formed by appending `-discovery` to its internal hostname, that resolves to all active instance IP addresses. A service receives its own discovery hostname in `RENDER_DISCOVERY_SERVICE`. Use DNS APIs that honor the system resolver configuration, and do not persist resolved instance IPs because they can change between deploys. Prefer hostname-based communication unless per-instance addressing or custom load balancing is specifically required. + +When a private-network connection fails, verify the workspace, region, project-environment isolation settings, whether the destination service type accepts inbound traffic, the internal hostname or URL, protocol, port, listening interface, current deploy health, and DNS resolution. Do not substitute a public URL or expose a private service merely to bypass a private-network configuration problem. + +AWS PrivateLink is a separate Pro-or-higher feature for connecting a Render private network to compatible AWS-hosted systems. Fetch its current documentation before proposing or configuring it; do not treat ordinary Render service-to-service networking and PrivateLink as interchangeable. + diff --git a/skills/render-cron-jobs/references/service-types.md b/skills/render-cron-jobs/references/service-types.md new file mode 100644 index 0000000..a0a3786 --- /dev/null +++ b/skills/render-cron-jobs/references/service-types.md @@ -0,0 +1,37 @@ + +## Render service types + +Use this guidance when selecting or comparing Render service types, or when a task's architecture depends on the distinction between them. A task that is already unambiguously scoped to one service type does not need this entire overview. + +On Render, a service represents code deployed for a particular execution model. Render runs that service on one or more instances, and the service's compute plan determines the CPU and memory available to each instance. + +Before choosing a service type, fetch the current service-types reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/service-types.md) or its [HTML version](https://render.com/docs/service-types). + +If neither version can be retrieved, use the bundled overview below only for basic service-type selection. State that current platform details could not be verified, and do not guess about changeable capabilities such as supported runtimes, plans, scaling, networking, disks, health checks, deployment behavior, availability, or limits. + +Render provides six public service types for running code: + +- **Web service:** A continuously running server that receives public HTTP traffic and also has an internal hostname for private-network traffic. Use it for dynamic websites, APIs, and other internet-facing server applications. +- **Static site:** Built HTML, CSS, JavaScript, and other static assets served publicly from Render's global CDN. Use it only when the deployed application does not require server-side runtime logic. +- **Private service:** A continuously running server that receives traffic only over Render's private network. Use it for internal HTTP, TCP, gRPC, or other server processes that need an internal hostname but no public URL. +- **Background worker:** A continuously running process that does not receive incoming traffic or expose a public or internal hostname. Use it for queue consumers and other processes that pull or poll for work. +- **Cron job:** A command or process that starts on a schedule, performs a bounded unit of work, and exits. Use it for straightforward recurring tasks rather than an always-running process. +- **Workflow:** A collection of on-demand tasks executed across distributed compute, with Render handling task queuing, orchestration, and provisioning. Use it when the workload benefits from independently invoked tasks, retries, composition, or parallel execution instead of a continuously running worker process. + +Choose based on how the code executes and receives work: + +- Public incoming traffic that requires server-side logic belongs on a web service. Public static assets with no runtime server belong on a static site. +- An application that needs both public and private ingress remains a web service; use its internal hostname for traffic from other Render services. +- A process that receives private-network requests belongs on a private service. A process that only initiates connections and pulls work belongs on a background worker. +- A simple scheduled command that exits belongs on a cron job. An always-running queue consumer belongs on a background worker. On-demand or distributed tasks for which Render should manage queuing and per-run compute belong in a workflow. + +Cron jobs and Workflows use invocation-based execution models. The ordinary instance-count and autoscaling model used by continuously running services does not apply to them. + +Render Postgres and Render Key Value are fully managed datastores, not general-purpose compute service types for running application code. Use Render Postgres for relational data and Render Key Value for use cases such as shared caching and job queues. An attached persistent disk is a storage feature of certain compute services, not a service type of its own. + +After selecting a type, fetch the product article linked from the service-types reference before relying on details such as supported runtimes and sources, plans, scaling, networking, disks, health checks, deployment behavior, scheduling semantics, availability, or limits. These capabilities are not uniform across service types and can change independently. + +Human-facing service names do not always map directly to configuration identifiers or structure. When creating or editing a Blueprint, fetch the current Blueprint specification and use its service-type schema instead of inferring fields or values from this overview. In particular, do not assume that every Dashboard service type has a same-named Blueprint `type` or that managed datastores are declared like compute services. + diff --git a/skills/render-debug/SKILL.md b/skills/render-debug/SKILL.md index 4b6820a..8bf9788 100644 --- a/skills/render-debug/SKILL.md +++ b/skills/render-debug/SKILL.md @@ -24,35 +24,17 @@ Activate this skill when: - Performance issues (slow responses) - Database connection problems -## Prerequisites +## Render Access -**MCP tools (preferred):** Test with `list_services()` - provides structured data - -**CLI (fallback):** `render --version` - use if MCP tools unavailable - -**Authentication:** If you installed the Render plugin (Cursor, Codex, Claude Code), it provides OAuth for MCP — complete the OAuth prompt. For manual MCP clients, use a Render API key. For CLI, verify with `render whoami -o json`. - -**Workspace:** `get_selected_workspace()` or `render workspace current -o json` - -> **Note:** MCP tools require the Render MCP server. If unavailable, use the CLI for logs and deploy status; metrics and structured database queries require MCP. - -## MCP Setup - -If `list_services()` fails, set up the Render MCP server. For detailed per-tool walkthroughs, see **render-mcp**. - -**Plugin setup:** If the Render plugin is installed, complete Render OAuth when prompted, then reload your tool and retry `list_services()`. - -**Manual MCP setup:** Add the Render MCP server to your AI tool's MCP config: -- **URL:** `https://mcp.render.com/mcp` -- **Auth header:** `Authorization: Bearer ` -- **API key:** `https://dashboard.render.com/u/*/settings#api-keys` - -After configuring, restart your tool and retry `list_services()`. Then set your workspace with `list_workspaces()` / `get_selected_workspace()`. +Before reading logs, metrics, or database state, follow `references/render-access.md` to establish access and verify the intended workspace. Prefer MCP when available; the CLI can provide logs and deploy status, while metrics and structured database queries require MCP. --- ## Debugging Workflow +When the failure involves configuration or secrets, read `references/environment-variables.md` before inspecting or changing service variables. +When the failure involves deploy state, rollout, health checks, restart, rollback, or shutdown, read `references/deployments.md` before diagnosing it. + ### Step 1: Identify Failed Service ``` @@ -236,6 +218,10 @@ render deploys create --wait ## References +- **Render access:** [references/render-access.md](references/render-access.md) +- **Environment variables:** [references/environment-variables.md](references/environment-variables.md) +- **Compute plans:** [references/compute-plans.md](references/compute-plans.md) +- **Deployments:** [references/deployments.md](references/deployments.md) - **Error patterns:** [references/error-patterns.md](references/error-patterns.md) - **Metrics debugging:** [references/metrics-debugging.md](references/metrics-debugging.md) - **Database debugging:** [references/database-debugging.md](references/database-debugging.md) @@ -247,4 +233,17 @@ render deploys create --wait - **render-deploy** — Deploy new applications to Render - **render-monitor** — Ongoing service health monitoring -- **render-mcp** — MCP server setup and tool catalog +- **render-mcp** — MCP server setup and capability discovery + + +## Current documentation retrieval + +Whenever this skill directs you to consult current Render documentation: + +1. Retrieve the linked Markdown document directly with an available URL-fetching tool or HTTP client, such as `curl`. Do not substitute web-search summaries for the document. +2. Confirm that retrieval succeeded and returned the expected document, then read its contents. Saving a file or printing its path is not sufficient. +3. If the request fails or your tool cannot read the Markdown response, open and read the linked HTML version instead. +4. If neither version can be retrieved, disclose that the current reference is unavailable and follow any topic-specific fallback in the skill. Use bundled guidance only for stable constraints, and do not guess at changeable platform details. + +When a task requires multiple references, apply this workflow to each one and distinguish the documents you verified from those that remain unavailable. + diff --git a/skills/render-debug/references/compute-plans.md b/skills/render-debug/references/compute-plans.md new file mode 100644 index 0000000..5d0ccc1 --- /dev/null +++ b/skills/render-debug/references/compute-plans.md @@ -0,0 +1,23 @@ + +## Compute plans + +A compute plan determines the CPU and RAM available to each instance of a Render service. Use **compute plan**, not the former term **instance type**. Do not confuse a service's compute plan with its workspace plan, which controls account-level features and limits. + +Compute plans differ by service type: + +- Web services, private services, background workers, and cron jobs use CPU-and-memory plan IDs such as `0.5c-512mb` and `1c-2g`. +- Render Postgres has its own plan catalog and connection limits. +- Render Key Value uses memory-based plan IDs such as `256mb` and `1g`. +- Workflow tasks select a compute plan in application code; a Workflow service does not set a Blueprint `plan`. +- Static sites do not have compute plans. + +Legacy plan names such as `starter`, `standard`, and `pro` remain valid in Render tooling, including Blueprints and API requests. For new configuration, prefer the current plan ID when the selected configuration surface accepts it. Before passing a plan to an API, MCP tool, or CLI command, inspect that operation's current schema or help and use one of its accepted values; the compute-plan reference describes the product catalog, not every tool version's input contract. Do not rename an existing legacy plan merely for consistency unless the user asks for that change. + +Do not rely on a memorized plan catalog. When a task depends on current plan IDs, specifications, defaults, availability, or pricing, fetch the canonical compute-plan reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/compute-plans.md) or its [HTML version](https://render.com/docs/compute-plans). + +Read the section for the relevant service type. If the document cannot be fetched, do not guess at current plan details. Preserve an existing valid plan where possible, or explain that the plan must be confirmed in the Render Dashboard or current documentation. + +When estimating capacity or cost, remember that every instance of a scaled service uses the selected compute plan and is billed accordingly. Changing the compute plan for Render Postgres, Render Key Value, or a service with an attached persistent disk requires brief downtime; other services normally apply the change with a zero-downtime deploy. + diff --git a/skills/render-debug/references/database-debugging.md b/skills/render-debug/references/database-debugging.md index 1a0a20c..70e1406 100644 --- a/skills/render-debug/references/database-debugging.md +++ b/skills/render-debug/references/database-debugging.md @@ -63,13 +63,7 @@ query_render_postgres( ) ``` -**Connection limits by plan:** -| Plan | Max Connections | -|------|----------------| -| Free | 97 | -| Basic | 97 | -| Standard | 120-500 | -| Pro | 500+ | +Connection limits vary by Postgres compute plan. Fetch the current plan table and limits using [compute-plans.md](compute-plans.md), then compare them with the database's live `max_connections` value. ### Fix Connection Issues @@ -77,7 +71,7 @@ query_render_postgres( 1. Implement connection pooling in your app 2. Reduce connection timeout 3. Close connections properly -4. Upgrade database plan +4. Upgrade the database compute plan **Node.js connection pooling:** ```javascript diff --git a/skills/render-debug/references/deployments.md b/skills/render-debug/references/deployments.md new file mode 100644 index 0000000..5ca9905 --- /dev/null +++ b/skills/render-debug/references/deployments.md @@ -0,0 +1,50 @@ + +## Deployments and health checks + +A Render deploy is asynchronous. A successful trigger means only that Render accepted or queued the deploy; it does not mean the new version is live. Before triggering a deploy, confirm the workspace, service, intended source commit or image, and current live deploy. Capture the new deploy ID, monitor it to a terminal state, and do not report success until its status is `live` and the deployed workload has been verified. + +Before configuring or troubleshooting deployments and health checks, fetch the current Render references: + +- [deploys.md](https://render.com/docs/deploys.md) (HTML: ) +- [health-checks.md](https://render.com/docs/health-checks.md) (HTML: ) + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read both references. + +Read the relevant sections of both documents. Confirm current service-type support, command timeouts, health-check thresholds, rollout behavior, and configuration syntax rather than relying on remembered values. + +Automatic deployment behavior depends on the service's source and settings. A service linked to a branch through a connected Git provider can deploy on each commit, wait for supported CI checks, or require manual triggers. Services that pull a prebuilt image and services linked by a public Git repository URL require manual deploys; moving a mutable image tag does not itself trigger one. When manually deploying a historical commit, verify whether that trigger method changes automatic-deploy settings. If automatic deploys remain enabled, a later branch update can replace the selected commit. + +The normal lifecycle is build command, optional pre-deploy command, then start command and readiness checks. If a command fails or times out, the deploy fails and later steps do not run. A pre-deploy command runs after the build on a separate instance before the new version is deployed. Neither the build nor pre-deploy instance can access an attached persistent disk, and pre-deploy filesystem changes do not carry into the running service. Use pre-deploy for release tasks such as database migrations, not for producing runtime artifacts. Pre-deploy commands are supported for paid web services, private services, and background workers. + +Render normally deploys services without downtime by starting the new version before retiring the current one. Web and private services continue routing traffic to the current instances until the new instances are ready. Multi-instance services roll out one instance at a time; if a replacement does not become healthy, Render cancels the rollout and retains or restores the previous version. Attaching a persistent disk disables zero-downtime deploys, so plan explicitly for an interruption. + +A workflow deployment has a different completion model. It builds and caches the image used by future task runs and includes a task-registration step, but it does not execute those tasks. After a workflow deploy succeeds, verify that the expected task definitions are registered. Trigger and monitor a task run separately only when execution is intended. For workflow-specific deployment behavior, fetch the current workflow overview: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/workflows.md) or its [HTML version](https://render.com/docs/workflows). + +Health checks apply to web services and private services. Both use TCP socket checks by default. Only web services support a configured HTTP health-check path. Render sends an HTTP `GET`; any `2xx` or `3xx` response received within five seconds succeeds, while other status codes, timeouts, and connection failures fail. Private services support TCP checks only. + +For a new deploy, all new instances must pass their checks at the same time within the current readiness window, documented as 15 minutes, before Render routes traffic to them. For a running service, consecutive failures currently remove an instance from routing after 15 seconds and restart it after 60 seconds. Treat these thresholds as platform behavior, not user-tunable health-check interval settings, and verify them in the fetched reference before relying on exact timing. + +Design an HTTP health endpoint to represent readiness for production traffic. Keep it fast and side-effect free. Check critical dependencies only when losing that dependency should make the entire instance unavailable; otherwise a transient dependency failure can unnecessarily remove healthy application capacity. Verify the configured path, response status, response time, listening port, and `0.0.0.0` binding when checks fail. + +After traffic moves, Render gives the previous instance a drain period, then sends `SIGTERM`. The application should stop accepting new work, finish or safely abandon in-flight work, close connections, and exit within its shutdown delay. Ensure the actual application process receives the signal: container entrypoints and shell wrappers should use `exec` or explicitly forward signals. Render sends `SIGKILL` if the process remains running after the delay. The documented default shutdown delay is 30 seconds and the usual maximum is 300 seconds, but support varies by service configuration; confirm the current reference and Blueprint or API validation before setting `maxShutdownDelaySeconds`. + +A service restart is a special deploy of the same commit and user-defined environment-variable values as the current running instance. It does not incorporate configuration changes saved after that deploy. Use a standard deploy when pending configuration must take effect. + +Only one deploy runs at a time for a service. A workspace's overlapping-deploy policy determines whether a new trigger waits or cancels the in-progress deploy. Do not assume the policy or wait for every intermediate revision: inspect the workspace setting and identify the deploy that actually became live. + +Treat rollback as a new deploy based on a retained previous build artifact, not as restoration of the entire service to an earlier point in time. It does not reverse database migrations, messages, external writes, or other side effects from the release, so confirm that the previous application version remains compatible with current external state. Disks and their data are not rolled back, some settings continue using current configuration, mutable image tags can resolve to a different image, and eligible artifacts are retained only for a limited period. Before rolling back, fetch the current rollback reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/rollbacks.md) or its [HTML version](https://render.com/docs/rollbacks). + +Read which configuration comes from the target deploy and which remains current. After the rollback is created, inspect the service's resulting automatic-deploy setting instead of assuming whether it remains enabled, and deliberately restore the intended setting after the underlying issue is resolved. + +Deploy hooks are secret credentials that authorize deploys. Never print, commit, or expose their full URLs. Before using one, fetch the current deploy-hook reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/deploy-hooks.md) or its [HTML version](https://render.com/docs/deploy-hooks). + +Distinguish an immediately started deploy from a queued one, and continue monitoring the resulting deploy rather than treating the HTTP response as completion. + +After a deploy becomes live, verify the behavior appropriate to the service type: make a request to a web or private service, confirm a worker is processing work, confirm a cron job or workflow invocation completes, and inspect recent runtime logs for new errors. If a deploy fails, diagnose the first failed lifecycle stage before retrying. + diff --git a/skills/render-debug/references/environment-variables.md b/skills/render-debug/references/environment-variables.md new file mode 100644 index 0000000..e9de03c --- /dev/null +++ b/skills/render-debug/references/environment-variables.md @@ -0,0 +1,38 @@ + +## Environment variables and secrets + +Render environment-variable values are strings. Applications must explicitly parse values that represent booleans, numbers, lists, or structured data; for example, the string `"false"` is truthy in many languages. + +Environment variables can be managed through the Render Dashboard, Blueprints, environment groups, and supported API, MCP, or CLI operations. Before changing a service, determine which mechanism is intended to be the source of truth. Do not make parallel Dashboard and infrastructure-as-code edits without explaining how future syncs or deploys will reconcile them. + +Never commit secret values to application source, `render.yaml`, checked-in `.env` files, fixtures, examples, or logs. Keep local secret-bearing `.env` files out of version control. Do not print or repeat secret values returned by the user, Render, or another provider. Use Render's supported secret mechanisms or an external secret manager appropriate to the user's workflow. + +Before configuring environment variables, secret files, or environment groups, fetch the current Render configuration reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/configure-environment-variables.md) or its [HTML version](https://render.com/docs/configure-environment-variables). + +Read the sections relevant to the configuration surface being used. Dashboard save options can rebuild and deploy, deploy the existing build, or save without deploying; do not assume a changed value is active until the applicable deploy occurs. + +For Blueprint-managed variables, also consult the current Blueprint YAML reference before writing syntax or predicting update behavior. In particular: + +- Use literal `value` entries only for non-sensitive configuration. +- `generateValue: true` creates a platform-generated secret when the variable does not already exist. +- `sync: false` prompts for a value only during initial Blueprint creation. It is ignored for existing services during later Blueprint updates, is not included in preview environments, and is not valid in environment groups. +- Use current `fromDatabase`, `fromService`, and `fromGroup` syntax instead of hardcoding connection strings or copying shared values. + +Blueprint syncs preserve existing service environment variables that are omitted from the Blueprint; omission does not delete them. Values defined with `fromDatabase` or `fromService` refresh on each Blueprint sync, not immediately when the referenced property or variable changes. + +Environment groups provide shared variables and secret files to linked services. A variable defined directly on a service takes precedence over the same key from a linked group. Precedence between multiple linked groups with the same key is not guaranteed; avoid collisions instead of depending on group creation order. Respect project-environment scoping when linking groups to services. + +Use secret files for credentials or configuration that must be read from the filesystem rather than an environment variable. Confirm current size and runtime-path rules in the fetched reference. Treat secret-file contents with the same precautions as other credentials. + +Render also injects documented default environment variables. Do not maintain a memorized catalog. Fetch the current default-variable reference when a task depends on a variable's name, availability, build/runtime scope, or semantics: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/environment-variables.md) or its [HTML version](https://render.com/docs/environment-variables). + +Depend only on documented platform variables. Other `RENDER_*` variables are internal and can change without notice. + +Treat environment-variable changes as service configuration mutations. Confirm the target workspace and service, inspect the existing keys without exposing their values, and preserve variables outside the user's requested scope. Before using an API, MCP, or CLI operation, check whether it patches individual keys or replaces the complete collection. After the applicable deploy, verify that required keys are present and that the service starts successfully without logging secret values. + +If the current references or live configuration cannot be inspected, do not guess at secret behavior, precedence, or replacement semantics. Preserve existing configuration where possible and explain what must be confirmed before making the change. + diff --git a/skills/render-debug/references/error-patterns.md b/skills/render-debug/references/error-patterns.md index f2ea22c..fd243ca 100644 --- a/skills/render-debug/references/error-patterns.md +++ b/skills/render-debug/references/error-patterns.md @@ -45,7 +45,7 @@ list_logs( **Common Variables:** - `DATABASE_URL` - PostgreSQL connection string -- `REDIS_URL` - Redis connection string +- `REDIS_URL` - Key Value connection string - `JWT_SECRET` - Authentication secret - `API_KEY` - Third-party API keys - `SECRET_KEY` - Django secret key @@ -60,56 +60,16 @@ list_logs( **Fix Strategy:** -**Step 1:** Add to render.yaml -```yaml -envVars: - # For database connections - - key: DATABASE_URL - fromDatabase: - name: postgres - property: connectionString - - # For secrets (user fills in Dashboard) - - key: JWT_SECRET - sync: false - - key: API_KEY - sync: false - - # For generated secrets - - key: SESSION_SECRET - generateValue: true - - # For hardcoded config - - key: NODE_ENV - value: production -``` - -**Step 2:** For existing services, use MCP to add env vars directly: -``` -update_environment_variables( - serviceId: "", - envVars: [ - {"key": "DATABASE_URL", "value": ""}, - {"key": "JWT_SECRET", "value": ""} - ] -) -``` - -**Step 3:** Commit and push (for Blueprint-managed services): -```bash -git add render.yaml -git commit -m "Add missing environment variables" -git push origin main -``` - -**Step 4:** If `sync: false` is used, remind user to fill values in Dashboard at: -`https://dashboard.render.com/web/[service-name]/env` +1. Read [environment-variables.md](environment-variables.md) and determine whether the service is managed through a Blueprint, Dashboard configuration, or an API/MCP operation. +2. Inspect existing keys without exposing values, then add only the missing configuration through the intended source of truth. +3. Use current Blueprint resource references rather than copied connection strings, and use an appropriate secret mechanism for sensitive values. +4. Apply the applicable deploy and verify successful startup in logs. **Prevention:** -- Always declare ALL env vars in render.yaml -- Use `sync: false` for secrets +- Keep the chosen configuration source authoritative +- Never commit or print secret values - Double-check variable names (case-sensitive) -- Test locally with `.env` file first +- Keep local secret-bearing `.env` files out of version control --- @@ -376,6 +336,8 @@ buildCommand: pip install -r requirements.txt ### 6. HEALTH_CHECK_TIMEOUT +Read [deployments.md](deployments.md) for current health-check behavior, timing, and service-type support before interpreting this failure. + **MCP Detection:** ``` list_logs( @@ -405,12 +367,12 @@ get_metrics( **Patterns to Match:** - `Health check timeout` -- `failed to become healthy within 300 seconds` +- `failed to become healthy` - `Service did not pass health check` - `GET / returned status 404` **Root Causes:** -1. No health check endpoint implemented +1. Configured health check endpoint is missing or incorrect 2. App not binding to correct port 3. Slow application startup 4. Health check path incorrect @@ -572,7 +534,7 @@ except Exception as e: **Description:** Build takes longer than allowed time. **Patterns to Match:** -- `Build timed out after 15 minutes` +- `Build timed out after 120 minutes` - `Command timed out` - `Build exceeded time limit` @@ -599,9 +561,7 @@ except Exception as e: buildCommand: npm ci --prefer-offline && npm run build ``` -**Consider upgrading:** -- Free tier: 15 minute build timeout -- Paid tiers: Longer timeouts available +If the build cannot complete within the 120-minute command limit, move expensive artifact generation to CI/CD or another build stage and deploy the resulting artifact or image. --- diff --git a/skills/render-debug/references/metrics-debugging.md b/skills/render-debug/references/metrics-debugging.md index 2303b2d..7334053 100644 --- a/skills/render-debug/references/metrics-debugging.md +++ b/skills/render-debug/references/metrics-debugging.md @@ -65,12 +65,7 @@ get_metrics( | 85-95% | Danger | Investigate immediately | | >95% | Critical | OOM imminent | -**Memory limits by plan:** -| Plan | Memory | -|------|--------| -| Free/Starter | 512 MB | -| Standard | 2 GB | -| Pro | 4 GB | +Use the resource's reported memory limit instead of inferring capacity from a legacy plan name. When the current plan specification matters, fetch it using [compute-plans.md](compute-plans.md). **High memory causes:** - Memory leaks (objects not garbage collected) diff --git a/skills/render-debug/references/quick-workflows.md b/skills/render-debug/references/quick-workflows.md index fbdcc73..e2613ea 100644 --- a/skills/render-debug/references/quick-workflows.md +++ b/skills/render-debug/references/quick-workflows.md @@ -35,7 +35,7 @@ list_logs( - Missing dependencies in package.json/requirements.txt - Build command syntax errors - Missing environment variables during build -- Build timeout (>15 min on free tier) +- Build timeout (120-minute build-command limit) --- @@ -292,6 +292,6 @@ get_metrics( # 4. Verify: # - App binds to 0.0.0.0:$PORT -# - Health check endpoint exists -# - App starts within timeout (300s default) +# - Configured health check endpoint exists and responds quickly +# - App becomes ready within the current window documented in deployments.md ``` diff --git a/skills/render-debug/references/render-access.md b/skills/render-debug/references/render-access.md new file mode 100644 index 0000000..864c854 --- /dev/null +++ b/skills/render-debug/references/render-access.md @@ -0,0 +1,50 @@ + +## Accessing Render + +Prefer the hosted Render MCP server for structured access to Render resources when its tools are available. Use the Render CLI when MCP is unavailable or does not support the required operation, and use the Render Dashboard or API for capabilities exposed by neither. Do not assume that a remembered MCP tool or CLI command is still available; inspect the tools in the current environment or consult the current documentation. + +The hosted Render MCP server uses streamable HTTP at: + +```text +https://mcp.render.com/mcp +``` + +Official Render plugins and connectors can authenticate MCP with browser-based OAuth. Manual and non-interactive configurations can use a Render API key as a bearer token. Never write an API key or OAuth token into a repository, skill, command output, chat response, or log. Prefer the client's supported secret storage or environment-variable mechanism. If a client requires a credential in local configuration, keep that file out of version control and restrict access to it. + +Treat MCP responses as potentially sensitive even when the server attempts to minimize credential exposure. Request connection strings, credentials, secret environment variables, or other sensitive fields only when the task requires them. Do not repeat sensitive values in the response or persist them in files or logs. + +Before configuring or troubleshooting MCP, fetch the current setup and capability reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/mcp-server.md) or its [HTML version](https://render.com/docs/mcp-server). + +Read the relevant client setup, supported-actions, and limitations sections. Prefer the hosted server unless the user's environment requires a local MCP server. After installing, updating, or reconfiguring an MCP integration, reload the client as required and verify the connection with a read-only operation such as listing services. + +Most MCP operations and Render CLI commands that access Render resources are scoped to an active workspace. Check the selected workspace before reading or changing resources. If no workspace is selected—or if the intended workspace is ambiguous—list the available workspaces and have the user identify the correct one. Do not silently switch workspace context or infer it from a resource name. Commands for authentication, help, CLI configuration, and workspace discovery or selection do not require an already selected workspace. + +For interactive CLI use, authenticate with `render login`. For automation, use a securely stored `RENDER_API_KEY`; an API key takes precedence over a saved CLI token. Verify CLI access and the active workspace with read-only commands before operating on resources: + +```bash +render whoami --output json +render workspace current --output json +``` + +For CLI installation, authentication, workspace setup, and usage patterns, fetch the current CLI overview: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/cli.md) or its [HTML version](https://render.com/docs/cli). + +For exact command syntax and flags, prefer the help text from the installed CLI because it matches the version being used: + +```bash +render help +``` + +The published CLI command reference is generated automatically from the CLI's help text. Use it to browse the full command surface or when the CLI is not installed: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/cli-reference.md) or its [HTML version](https://render.com/docs/cli-reference). + +When an agent or automation invokes the CLI, select a non-interactive output format such as `--output json`, `--output yaml`, or `--output text` so results can be inspected reliably. The global `--confirm` flag skips confirmation prompts; use it for a mutating command only after that mutation is authorized. It is an execution convenience, not permission to perform the action. + +Authentication establishes access; it does not establish user authorization for every available action. Use read-only discovery to resolve workspace, resource identity, and current state before a mutation. Perform changes only when they are within the user's requested scope, and retain normal approval requirements for consequential operations such as creation, configuration changes, deploys, restarts, scaling, or deletion. + +When authentication or connectivity fails, report which access path failed, preserve the underlying error without exposing credentials, and either use an available supported fallback or explain what the user must configure before the task can continue. + diff --git a/skills/render-debug/references/troubleshooting.md b/skills/render-debug/references/troubleshooting.md index eb6aa6d..d78494f 100644 --- a/skills/render-debug/references/troubleshooting.md +++ b/skills/render-debug/references/troubleshooting.md @@ -50,56 +50,10 @@ render logs -r --level error -o json | grep "not defined" **Fix Procedure:** -**Step 1:** Add to render.yaml - -For database connections: -```yaml -envVars: - - key: DATABASE_URL - fromDatabase: - name: postgres - property: connectionString -``` - -For secrets (user provides): -```yaml -envVars: - - key: JWT_SECRET - sync: false - - key: API_KEY - sync: false -``` - -For generated values: -```yaml -envVars: - - key: SESSION_SECRET - generateValue: true -``` - -For hardcoded config: -```yaml -envVars: - - key: NODE_ENV - value: production -``` - -**Step 2:** Commit and push -```bash -git add render.yaml -git commit -m "Add missing environment variable: DATABASE_URL" -git push origin main -``` - -**Step 3:** If using `sync: false`, instruct user: -1. Go to Dashboard: `https://dashboard.render.com/web/[service]/env` -2. Fill in the secret value -3. Click "Save Changes" - -**Step 4:** Redeploy -```bash -render deploys create --wait -``` +1. Read [environment-variables.md](environment-variables.md), identify the intended source of truth, and inspect existing keys without exposing values. +2. Add the missing key through that configuration surface, using current Blueprint wiring for resource references and an appropriate secret mechanism for sensitive values. +3. Commit and push if the service is Blueprint-managed; otherwise apply the authorized service configuration change. +4. Trigger the applicable deploy so the new value becomes active. **Verification:** ```bash @@ -353,7 +307,7 @@ buildCommand: pip install -r requirements.txt buildCommand: go build -o bin/app . ``` -**Build Timeout (Free tier: 15 minutes):** +**Build Timeout (120-minute build-command limit):** Optimize: ```yaml @@ -361,7 +315,7 @@ Optimize: buildCommand: npm ci --prefer-offline && npm run build # Remove unused dependencies -# Upgrade to paid tier for longer timeout +# Consider pre-building expensive artifacts in CI/CD ``` --- @@ -370,14 +324,16 @@ buildCommand: npm ci --prefer-offline && npm run build ### Problem: Health Check Timeout +Read [deployments.md](deployments.md) for current health-check behavior, timing, and service-type support before diagnosing this failure. + **Symptoms:** -- `Health check timeout after 300 seconds` +- `Health check timeout` - `failed to become healthy` **Diagnosis Steps:** 1. Check if app is binding to correct port -2. Check if health check endpoint exists +2. Check whether the configured health check endpoint exists and returns an accepted response 3. Check startup time **Fix Procedure:** @@ -586,8 +542,8 @@ Deployment Failed? Before asking for help, verify: -- [ ] All environment variables are declared in render.yaml -- [ ] Secrets have `sync: false` and are filled in Dashboard +- [ ] Required environment-variable keys exist in the intended configuration source +- [ ] Secret configuration is complete without exposing values - [ ] App binds to `process.env.PORT` (or equivalent) - [ ] App binds to `0.0.0.0` (not localhost) - [ ] Build command is non-interactive diff --git a/skills/render-deploy/SKILL.md b/skills/render-deploy/SKILL.md index d9c03bf..69dc934 100644 --- a/skills/render-deploy/SKILL.md +++ b/skills/render-deploy/SKILL.md @@ -34,7 +34,7 @@ Activate this skill when users want to: ## Happy Path (New Users) -Use this short prompt sequence before deep analysis to reduce friction: +Use this short prompt sequence only to fill missing information. Do not ask the user to repeat details they already supplied. If the source and required resources are clear, proceed directly to method selection and deployment. 1. Ask whether they want to deploy from a Git repo or a prebuilt Docker image. 2. Ask whether Render should provision everything the app needs (based on what seems likely from the user's description) or only the app while they bring their own infra. If dependencies are unclear, ask a short follow-up to confirm whether they need a database, workers, cron, or other services. @@ -73,7 +73,7 @@ If this path fits and MCP isn't configured yet, stop and guide MCP setup before **Use Blueprint when ANY are true:** - Multiple services (web + worker, API + frontend, etc.) -- Databases, Redis/Key Value, or other datastores are required +- Databases, Key Value, or other datastores are required - Cron jobs, background workers, or private services - You want reproducible IaC or a render.yaml committed to the repo - Monorepo or multi-env setup that needs consistent configuration @@ -94,70 +94,17 @@ git remote -v - If no remote exists, stop and ask the user to create/push a remote **or** switch to Docker image deploy. -**2. Check MCP Tools Availability (Preferred for Single-Service)** +**2. Establish Render Access** -MCP tools provide the best experience. Check if available by attempting: -``` -list_services() -``` - -If MCP tools are available, you can skip CLI installation for most operations. - -**3. Check Render CLI Installation (for Blueprint validation)** -```bash -render --version -``` -If not installed, offer to install: -- macOS: `brew install render` -- Linux/macOS: `curl -fsSL https://raw.githubusercontent.com/render-oss/cli/main/bin/install.sh | sh` - -**4. MCP Setup (if MCP isn't configured)** - -If `list_services()` fails, set up the Render MCP server. For detailed per-tool walkthroughs, see **render-mcp**. - -**Plugin setup:** If the Render plugin is installed, complete Render OAuth when prompted, then reload your tool and retry `list_services()`. - -**Manual MCP setup:** Add the Render MCP server to your AI tool's MCP config: -- **URL:** `https://mcp.render.com/mcp` -- **Auth header:** `Authorization: Bearer ` -- **API key:** `https://dashboard.render.com/u/*/settings#api-keys` - -After configuring, restart your tool and retry `list_services()`. Then set your workspace with `list_workspaces()` / `get_selected_workspace()`. - -**5. Check Authentication (CLI fallback only)** +Before reading or changing Render resources, follow [references/render-access.md](references/render-access.md) to choose an access path, authenticate, verify the intended workspace, and confirm the required capability. Blueprint validation still requires the Render CLI even when MCP is available. -If MCP isn't available, use the CLI instead and verify you can access your account: -```bash -# Check if user is logged in (use -o json for non-interactive mode) -render whoami -o json -``` - -If `render whoami` fails or returns empty data, the CLI is not authenticated. The CLI won't always prompt automatically, so explicitly prompt the user to authenticate: - -If neither is configured, ask user which method they prefer: -- **API Key (CLI)**: `export RENDER_API_KEY="rnd_xxxxx"` (Get from https://dashboard.render.com/u/*/settings#api-keys) -- **Login**: `render login` (Opens browser for OAuth) - -**6. Check Workspace Context** - -Verify the active workspace: -``` -get_selected_workspace() -``` - -Or via CLI: -```bash -render workspace current -o json -``` +Once prerequisites are met, proceed with deployment workflow. -To list available workspaces: -``` -list_workspaces() -``` +Before triggering, monitoring, restarting, or rolling back a deploy, read [references/deployments.md](references/deployments.md) for the current lifecycle, health-check, and verification workflow. -If user needs to switch workspaces, they must do so via Dashboard or CLI (`render workspace set`). +When resources communicate over Render's private network, read [references/private-networking.md](references/private-networking.md) before choosing regions or wiring addresses and ports. -Once prerequisites are met, proceed with deployment workflow. +Before selecting or changing a service type, read [references/service-types.md](references/service-types.md). --- @@ -173,13 +120,15 @@ Analyze the codebase to determine framework/runtime, build and start commands, r Create a `render.yaml` Blueprint file following the Blueprint specification. -Complete specification: [references/blueprint-spec.md](references/blueprint-spec.md) +Before authoring or changing the file, read [references/blueprints.md](references/blueprints.md) and follow its current specification-fetch, validation, repository-sync, and safety workflow. + +For variables, secrets, secret files, or environment groups, also read [references/environment-variables.md](references/environment-variables.md). **Key Points:** -- Always use `plan: free` unless user specifies otherwise -- Include ALL environment variables the app needs -- Mark secrets with `sync: false` (user fills these in Dashboard) -- Use appropriate service type: `web`, `worker`, `cron`, `static`, or `pserv` +- Select a compute plan appropriate to the resource and workload. Consult [references/compute-plans.md](references/compute-plans.md) for current Plan IDs, defaults, availability, and pricing guidance instead of relying on examples in this skill. +- Unless the user specifies a region, place new resources in the same region as their related existing services to preserve private network connectivity. +- Include every environment variable the app requires and use the intended source of truth and secret mechanism from `references/environment-variables.md` +- Use appropriate service type: `web`, `worker`, `cron`, `keyvalue`, or `pserv` (`type: web` with `runtime: static` for static sites) - Use appropriate runtime: [references/runtimes.md](references/runtimes.md) **Basic Structure:** @@ -209,8 +158,12 @@ databases: - `web`: HTTP services, APIs, web applications (publicly accessible) - `worker`: Background job processors (not publicly accessible) - `cron`: Scheduled tasks that run on a cron schedule -- `static`: Static sites (HTML/CSS/JS served via CDN) -- `pserv`: Private services (internal only, within same account) +- `pserv`: Private services (internal only, within same account and region) +- `keyvalue`: Redis-compatible key-value store + +A service with `type: web` and `runtime: static` is a static site served via global CDN. Static sites do not have a `plan`. + +Postgres databases are defined under the `databases` key instead of the `services` key. They do not have a `type`. Service type details: [references/service-types.md](references/service-types.md) Runtime options: [references/runtimes.md](references/runtimes.md) @@ -219,23 +172,24 @@ Template examples: [assets/](assets/) ### Step 2.5: Immediate Next Steps (Always Provide) After creating `render.yaml`, always give the user a short, explicit checklist and run validation immediately when the CLI is available: -1. **Authenticate (CLI)**: run `render whoami -o json` (if not logged in, run `render login` or set `RENDER_API_KEY`) -2. **Validate (recommended)**: run `render blueprints validate` +1. **Confirm access**: follow [references/render-access.md](references/render-access.md) +2. **Validate**: run `render blueprints validate render.yaml` - If the CLI isn't installed, offer to install it and provide the command. 3. **Commit + push**: `git add render.yaml && git commit -m "Add Render deployment configuration" && git push origin main` 4. **Open Dashboard**: Use the Blueprint deeplink and complete Git OAuth if prompted -5. **Fill secrets**: Set env vars marked `sync: false` +5. **Complete secret configuration**: Supply any values required by the selected environment-variable workflow 6. **Deploy**: Click "Apply" and monitor the deploy ### Step 3: Validate Configuration -Validate the render.yaml file to catch errors before deployment. If the CLI is installed, run the commands directly; only prompt the user if the CLI is missing: +Follow the validation workflow in [references/blueprints.md](references/blueprints.md). If the CLI is installed, run the commands directly; only prompt the user if the CLI is missing: ```bash -render whoami -o json # Ensure CLI is authenticated (won't always prompt) -render blueprints validate +render blueprints validate render.yaml ``` +If the Blueprint is not at `render.yaml` relative to the current directory, pass its actual file path instead. + Fix any validation errors before proceeding. Common issues: - Missing required fields (`name`, `type`, `runtime`) - Invalid runtime values @@ -300,7 +254,7 @@ Provide the deeplink to the user with these instructions: 2. Click the deeplink to open Render Dashboard 3. Complete Git provider OAuth if prompted 4. Name the Blueprint (or use default from render.yaml) -5. Fill in secret environment variables (marked with `sync: false`) +5. Complete any required secret configuration without exposing values 6. Review services and databases configuration 7. Click "Apply" to deploy @@ -308,26 +262,7 @@ The deployment will begin automatically. Users can monitor progress in the Rende ### Step 7: Verify Deployment -After the user deploys via Dashboard, verify everything is working. - -**Check deployment status via MCP:** -``` -list_deploys(serviceId: "", limit: 1) -``` -Look for `status: "live"` to confirm successful deployment. - -**Check for runtime errors (wait 2-3 minutes after deploy):** -``` -list_logs(resource: [""], level: ["error"], limit: 20) -``` - -**Check service health metrics:** -``` -get_metrics( - resourceId: "", - metricTypes: ["http_request_count", "cpu_usage", "memory_usage"] -) -``` +After the user deploys via Dashboard, follow [references/deployments.md](references/deployments.md) to monitor the specific deploy through a terminal status and verify the resulting workload. If errors are found, proceed to the **Post-deploy verification and basic triage** section below. @@ -372,7 +307,7 @@ Create the service (web or static) and any required databases or key-value store If MCP returns an error about missing Git credentials or repo access, stop and guide the user to connect their Git provider in the Render Dashboard, then retry. ### Step 3: Configure Environment Variables -Add required env vars via MCP after creation. See [references/direct-creation.md](references/direct-creation.md). +Before changing service configuration, read [references/environment-variables.md](references/environment-variables.md). Add required env vars via MCP after creation using [references/direct-creation.md](references/direct-creation.md). Remind the user that secrets can be set in the Dashboard if they prefer not to pass them via MCP. @@ -387,12 +322,7 @@ For service discovery, configuration details, quick commands, and common issues, # Post-deploy verification and basic triage (All Methods) -Keep this short and repeatable. If any check fails, fix it before redeploying. - -1. Confirm the latest deploy is `live` and serving traffic -2. Hit the health endpoint (or root) and verify a 200 response -3. Scan recent error logs for a clear failure signature -4. Verify required env vars and port binding (`0.0.0.0:$PORT`) +Follow [references/deployments.md](references/deployments.md) for deploy-state interpretation and post-live verification. If any check fails, fix it before redeploying. Detailed checklist and commands: [references/post-deploy-checks.md](references/post-deploy-checks.md) @@ -401,3 +331,16 @@ If the service fails to start or health checks time out, use the basic triage gu Optional: If you need deeper diagnostics (metrics/DB checks/error catalog), suggest installing the `render-debug` skill. It is not required for the core deploy flow. + + +## Current documentation retrieval + +Whenever this skill directs you to consult current Render documentation: + +1. Retrieve the linked Markdown document directly with an available URL-fetching tool or HTTP client, such as `curl`. Do not substitute web-search summaries for the document. +2. Confirm that retrieval succeeded and returned the expected document, then read its contents. Saving a file or printing its path is not sufficient. +3. If the request fails or your tool cannot read the Markdown response, open and read the linked HTML version instead. +4. If neither version can be retrieved, disclose that the current reference is unavailable and follow any topic-specific fallback in the skill. Use bundled guidance only for stable constraints, and do not guess at changeable platform details. + +When a task requires multiple references, apply this workflow to each one and distinguish the documents you verified from those that remain unavailable. + diff --git a/skills/render-deploy/assets/docker.yaml b/skills/render-deploy/assets/docker.yaml index c3f9d3a..01f1385 100644 --- a/skills/render-deploy/assets/docker.yaml +++ b/skills/render-deploy/assets/docker.yaml @@ -8,7 +8,7 @@ services: plan: free region: oregon branch: main - autoDeploy: true + autoDeployTrigger: commit dockerfilePath: ./Dockerfile # Path to your Dockerfile dockerContext: . # Build context directory healthCheckPath: /health @@ -22,12 +22,19 @@ services: name: postgres property: connectionString - key: REDIS_URL - fromDatabase: + fromService: name: redis + type: keyvalue property: connectionString - key: SECRET_KEY sync: false # User provides in Dashboard + - type: keyvalue + name: redis + plan: free + maxmemoryPolicy: allkeys-lru + ipAllowList: [] + databases: - name: postgres databaseName: app_production @@ -36,11 +43,6 @@ databases: postgresMajorVersion: "15" ipAllowList: [] - - name: redis - plan: free - maxmemoryPolicy: allkeys-lru - ipAllowList: [] - # Example multi-stage Dockerfile: # # # Build stage diff --git a/skills/render-deploy/assets/go-api.yaml b/skills/render-deploy/assets/go-api.yaml index dd24eb7..673b772 100644 --- a/skills/render-deploy/assets/go-api.yaml +++ b/skills/render-deploy/assets/go-api.yaml @@ -8,7 +8,7 @@ services: plan: free region: oregon branch: main - autoDeploy: true + autoDeployTrigger: commit buildCommand: go build -o bin/app -ldflags="-s -w" . startCommand: ./bin/app healthCheckPath: /health diff --git a/skills/render-deploy/assets/nextjs-postgres.yaml b/skills/render-deploy/assets/nextjs-postgres.yaml index ef70b75..40f98cb 100644 --- a/skills/render-deploy/assets/nextjs-postgres.yaml +++ b/skills/render-deploy/assets/nextjs-postgres.yaml @@ -8,9 +8,11 @@ services: plan: free region: oregon branch: main - autoDeploy: true + autoDeployTrigger: commit buildCommand: npm ci && npm run build - startCommand: npm start + # NextAuth.js v4 needs its canonical URL. Use Render's injected hostname by default; + # set NEXTAUTH_URL explicitly if the application should use a custom domain instead. + startCommand: NEXTAUTH_URL="${NEXTAUTH_URL:-https://$RENDER_EXTERNAL_HOSTNAME}" npm start healthCheckPath: /api/health envVars: - key: NODE_ENV @@ -19,8 +21,6 @@ services: fromDatabase: name: postgres property: connectionString - - key: NEXTAUTH_URL - value: https://nextjs-app.onrender.com - key: NEXTAUTH_SECRET sync: false # User provides in Dashboard - key: JWT_SECRET diff --git a/skills/render-deploy/assets/node-express.yaml b/skills/render-deploy/assets/node-express.yaml index 04facaf..3c6be1e 100644 --- a/skills/render-deploy/assets/node-express.yaml +++ b/skills/render-deploy/assets/node-express.yaml @@ -8,7 +8,7 @@ services: plan: free region: oregon branch: main - autoDeploy: true + autoDeployTrigger: commit buildCommand: npm ci startCommand: npm start healthCheckPath: /health diff --git a/skills/render-deploy/assets/python-django.yaml b/skills/render-deploy/assets/python-django.yaml index 2be69d2..3163a79 100644 --- a/skills/render-deploy/assets/python-django.yaml +++ b/skills/render-deploy/assets/python-django.yaml @@ -1,5 +1,5 @@ # Django Application with Worker and Databases -# Full Django stack with Celery worker, PostgreSQL, and Redis +# Full Django stack with Celery worker, PostgreSQL, and Key Value services: # Django web service @@ -9,8 +9,11 @@ services: plan: free region: oregon branch: main - autoDeploy: true + autoDeployTrigger: commit + # Free web services do not support preDeployCommand, so migrations run during the build. buildCommand: pip install -r requirements.txt && python manage.py collectstatic --no-input && python manage.py migrate + # In settings.py, append RENDER_EXTERNAL_HOSTNAME to ALLOWED_HOSTS and add any + # custom domains explicitly. Render injects this hostname at runtime. startCommand: gunicorn config.wsgi:application --bind 0.0.0.0:$PORT --workers 2 healthCheckPath: /health/ envVars: @@ -20,25 +23,24 @@ services: value: config.settings.production - key: DJANGO_SECRET_KEY sync: false # User provides in Dashboard - - key: DJANGO_ALLOWED_HOSTS - value: django-web.onrender.com - key: DATABASE_URL fromDatabase: name: postgres property: connectionString - key: REDIS_URL - fromDatabase: + fromService: name: redis + type: keyvalue property: connectionString # Celery worker for background tasks - type: worker name: celery-worker runtime: python - plan: free + plan: starter region: oregon branch: main - autoDeploy: true + autoDeployTrigger: commit buildCommand: pip install -r requirements.txt startCommand: celery -A config.celery_app worker --loglevel=info --concurrency=2 envVars: @@ -51,28 +53,37 @@ services: name: postgres property: connectionString - key: REDIS_URL - fromDatabase: + fromService: name: redis + type: keyvalue property: connectionString # Celery beat for periodic tasks (optional) - type: worker name: celery-beat runtime: python - plan: free + plan: starter region: oregon branch: main - autoDeploy: true + autoDeployTrigger: commit buildCommand: pip install -r requirements.txt startCommand: celery -A config.celery_app beat --loglevel=info envVars: - key: DJANGO_SETTINGS_MODULE value: config.settings.production - key: REDIS_URL - fromDatabase: + fromService: name: redis + type: keyvalue property: connectionString + # Key Value for Celery and caching. Queue brokers must not evict queued jobs. + - type: keyvalue + name: redis + plan: free + maxmemoryPolicy: noeviction + ipAllowList: [] # Internal access only + databases: # PostgreSQL database - name: postgres @@ -81,9 +92,3 @@ databases: plan: free postgresMajorVersion: "15" ipAllowList: [] # Internal access only - - # Redis for Celery and caching - - name: redis - plan: free - maxmemoryPolicy: allkeys-lru - ipAllowList: [] # Internal access only diff --git a/skills/render-deploy/assets/static-site.yaml b/skills/render-deploy/assets/static-site.yaml index 0f5ff61..d8de9e0 100644 --- a/skills/render-deploy/assets/static-site.yaml +++ b/skills/render-deploy/assets/static-site.yaml @@ -5,9 +5,8 @@ services: - type: web name: react-app runtime: static - plan: free branch: main - autoDeploy: true + autoDeployTrigger: commit buildCommand: npm ci && npm run build staticPublishPath: ./build # Change to ./dist for Vue/Vite, ./public for Gatsby diff --git a/skills/render-deploy/references/blueprint-spec.md b/skills/render-deploy/references/blueprint-spec.md deleted file mode 100644 index 01c29b2..0000000 --- a/skills/render-deploy/references/blueprint-spec.md +++ /dev/null @@ -1,718 +0,0 @@ -# Render Blueprint Specification - -Complete reference for render.yaml Blueprint files. Blueprints define your infrastructure as code for reproducible deployments on Render. - -## Overview - -A Blueprint is a YAML file (typically `render.yaml`) placed in your repository root that describes: -- Services (web, worker, cron, static, private) -- Databases (PostgreSQL, Redis) -- Environment variables and secrets -- Scaling and resource configuration -- Project organization - -## Root-Level Structure - -```yaml -# Top-level fields -services: [] # Array of service definitions -databases: [] # Array of PostgreSQL databases -envVarGroups: [] # Reusable environment variable groups (optional) -projects: [] # Project organization (optional) -ungrouped: [] # Resources outside projects (optional) -previews: # Preview environment configuration (optional) - generation: auto_preview | manual | none -``` - -## Service Types - -### Web Services (`type: web`) - -HTTP services, APIs, and web applications. Publicly accessible via HTTPS. - -**Required fields:** -- `name`: Unique service identifier -- `type`: Must be `web` -- `runtime`: Language/environment (see Runtimes section) -- `buildCommand`: Command to build the application -- `startCommand`: Command to start the server - -**Common optional fields:** -- `plan`: Instance type (default: `free`) -- `region`: Deployment region (default: `oregon`) -- `branch`: Git branch to deploy (default: `main`) -- `autoDeploy`: Auto-deploy on push (default: `true`) -- `envVars`: Environment variables array -- `healthCheckPath`: Health check endpoint (default: `/`) -- `numInstances`: Number of instances (manual scaling) -- `scaling`: Autoscaling configuration - -**Example:** -```yaml -services: - - type: web - name: api-server - runtime: node - plan: free - buildCommand: npm ci - startCommand: npm start - branch: main - autoDeploy: true - envVars: - - key: NODE_ENV - value: production - - key: PORT - value: 10000 -``` - -### Worker Services (`type: worker`) - -Background job processors, queue consumers. Not publicly accessible. - -**Required fields:** -- `name`: Unique service identifier -- `type`: Must be `worker` -- `runtime`: Language/environment -- `buildCommand`: Command to build -- `startCommand`: Command to start worker process - -**Key differences from web services:** -- No public URL -- No health checks -- No port binding required - -**Example:** -```yaml -services: - - type: worker - name: job-processor - runtime: python - plan: free - buildCommand: pip install -r requirements.txt - startCommand: celery -A tasks worker --loglevel=info - envVars: - - key: REDIS_URL - fromDatabase: - name: redis - property: connectionString -``` - -### Cron Jobs (`type: cron`) - -Scheduled tasks that run on a cron schedule. - -**Required fields:** -- `name`: Unique service identifier -- `type`: Must be `cron` -- `runtime`: Language/environment -- `schedule`: Cron expression -- `buildCommand`: Command to build -- `startCommand`: Command to execute on schedule - -**Schedule format:** Standard cron syntax (minute hour day month weekday) - -**Examples:** -- `0 0 * * *` - Daily at midnight UTC -- `*/15 * * * *` - Every 15 minutes -- `0 9 * * 1` - Every Monday at 9 AM UTC - -**Example:** -```yaml -services: - - type: cron - name: daily-backup - runtime: node - schedule: "0 2 * * *" - buildCommand: npm ci - startCommand: node scripts/backup.js - envVars: - - key: DATABASE_URL - fromDatabase: - name: postgres - property: connectionString -``` - -### Static Sites (`type: static` or `type: web` with `runtime: static`) - -Serve static HTML/CSS/JS files via CDN. - -**Required fields:** -- `name`: Unique service identifier -- `type`: `web` -- `runtime`: `static` -- `buildCommand`: Command to build static assets -- `staticPublishPath`: Path to built files (e.g., `./build`, `./dist`) - -**Optional configuration:** -- `routes`: Routing rules for SPAs -- `headers`: Custom HTTP headers -- `buildFilter`: Path filters for build triggers - -**Example:** -```yaml -services: - - type: web - name: react-app - runtime: static - buildCommand: npm ci && npm run build - staticPublishPath: ./dist - routes: - - type: rewrite - source: /* - destination: /index.html - headers: - - path: /* - name: Cache-Control - value: public, max-age=31536000, immutable -``` - -### Private Services (`type: pserv`) - -Internal services accessible only within your Render account. - -**Required fields:** -- `name`: Unique service identifier -- `type`: Must be `pserv` -- `runtime`: Language/environment -- `buildCommand`: Command to build -- `startCommand`: Command to start - -**Use cases:** -- Internal APIs -- Database proxies -- Microservices not exposed to internet - -**Example:** -```yaml -services: - - type: pserv - name: internal-api - runtime: go - plan: free - buildCommand: go build -o bin/app - startCommand: ./bin/app -``` - -## Runtimes - -### Native Runtimes - -**Node.js (`runtime: node`):** -- Versions: 14, 16, 18, 20, 21 -- Default version: 20 -- Specify version in `package.json` engines field - -**Python (`runtime: python`):** -- Versions: 3.8, 3.9, 3.10, 3.11, 3.12 -- Default version: 3.11 -- Specify version in `runtime.txt` or `Pipfile` - -**Go (`runtime: go`):** -- Versions: 1.20, 1.21, 1.22, 1.23 -- Uses go modules -- Version from `go.mod` - -**Ruby (`runtime: ruby`):** -- Versions: 3.0, 3.1, 3.2, 3.3 -- Uses Bundler -- Version from `.ruby-version` or `Gemfile` - -**Rust (`runtime: rust`):** -- Latest stable version -- Uses Cargo - -**Elixir (`runtime: elixir`):** -- Latest stable version -- Uses Mix - -### Docker Runtime - -**Docker (`runtime: docker`):** -Build from a Dockerfile in your repository. - -**Additional fields:** -- `dockerfilePath`: Path to Dockerfile (default: `./Dockerfile`) -- `dockerContext`: Build context directory (default: `.`) - -**Example:** -```yaml -services: - - type: web - name: docker-app - runtime: docker - dockerfilePath: ./docker/Dockerfile - dockerContext: . - plan: free -``` - -**Image (`runtime: image`):** -Deploy pre-built Docker images from a registry. - -**Additional fields:** -- `image`: Image URL (e.g., `registry.com/image:tag`) -- `registryCredential`: Credentials for private registries - -**Example:** -```yaml -services: - - type: web - name: prebuilt-app - runtime: image - image: myregistry.com/app:v1.2.3 - plan: free -``` - -## Service Plans - -Available instance types: - -| Plan | RAM | CPU | Price | -|------|-----|-----|-------| -| `free` | 512 MB | 0.5 | Free (750 hrs/mo) | -| `starter` | 512 MB | 0.5 | $7/month | -| `standard` | 2 GB | 1 | $25/month | -| `pro` | 4 GB | 2 | $85/month | -| `pro_plus` | 8 GB | 4 | $175/month | - -**Always default to `plan: free` unless user specifies otherwise.** - -## Regions - -Available deployment regions: - -- `oregon` (US West) - Default -- `ohio` (US East) -- `virginia` (US East) -- `frankfurt` (EU) -- `singapore` (Asia) - -**Example:** -```yaml -services: - - type: web - name: my-app - runtime: node - region: frankfurt -``` - -## Environment Variables - -Three patterns for defining environment variables: - -### 1. Hardcoded Values - -For non-sensitive configuration: - -```yaml -envVars: - - key: NODE_ENV - value: production - - key: API_URL - value: https://api.example.com - - key: LOG_LEVEL - value: info -``` - -### 2. Generated Secrets - -Render generates a base64-encoded 256-bit random value: - -```yaml -envVars: - - key: SESSION_SECRET - generateValue: true - - key: ENCRYPTION_KEY - generateValue: true -``` - -### 3. User-Provided Secrets - -Prompt user for values during Blueprint creation: - -```yaml -envVars: - - key: STRIPE_SECRET_KEY - sync: false - - key: JWT_SECRET - sync: false - - key: API_KEY - sync: false -``` - -**The `sync: false` flag means "user will fill this in the Dashboard".** - -### 4. Database References - -Link to database connection strings: - -```yaml -envVars: - - key: DATABASE_URL - fromDatabase: - name: postgres - property: connectionString - - key: REDIS_URL - fromDatabase: - name: redis - property: connectionString -``` - -**Available properties:** -- `connectionString`: Full connection URL -- `host`: Database host -- `port`: Database port -- `user`: Database username -- `password`: Database password -- `database`: Database name -- `hostport`: Combined `host:port` - -### 5. Service References - -Link to other services: - -```yaml -envVars: - - key: API_URL - fromService: - name: api-server - type: web - property: host -``` - -### 6. Environment Variable Groups - -Reusable groups shared across services: - -```yaml -envVarGroups: - - name: shared-config - envVars: - - key: LOG_LEVEL - value: info - - key: ENVIRONMENT - value: production - -services: - - type: web - name: web-app - runtime: node - envVars: - - fromGroup: shared-config - - key: PORT - value: 10000 -``` - -## Databases - -### PostgreSQL - -```yaml -databases: - - name: postgres - databaseName: myapp_prod - user: myapp_user - plan: free - postgresMajorVersion: "15" - ipAllowList: [] -``` - -**Plans:** -- `free`: 1 GB storage, 97 MB RAM, 0.1 CPU -- `basic-256mb`, `basic-512mb`, `basic-1gb`, `basic-4gb` -- `pro-4gb`, `pro-8gb`, `pro-16gb`, etc. -- `accelerated-4gb`, `accelerated-8gb`, etc. (SSD-backed) - -**Key fields:** -- `name`: Identifier for references -- `databaseName`: Actual PostgreSQL database name -- `user`: Database username -- `postgresMajorVersion`: PostgreSQL version (11-16) -- `ipAllowList`: Array of CIDR blocks (empty = internal only) -- `diskSizeGB`: Storage size (paid plans only) - -**High Availability (paid plans):** -```yaml -databases: - - name: postgres - databaseName: myapp_prod - plan: pro-4gb - highAvailabilityEnabled: true -``` - -**Read Replicas (paid plans):** -```yaml -databases: - - name: postgres - databaseName: myapp_prod - plan: pro-4gb - readReplicas: - - name: read-replica-1 - region: ohio - - name: read-replica-2 - region: frankfurt -``` - -### Redis (Key-Value Store) - -```yaml -databases: - - name: redis - plan: free - maxmemoryPolicy: allkeys-lru - ipAllowList: [] -``` - -**Plans:** Same as PostgreSQL - -**maxmemoryPolicy options:** -- `allkeys-lru`: Evict least recently used keys -- `volatile-lru`: Evict LRU keys with TTL -- `allkeys-random`: Evict random keys -- `volatile-random`: Evict random keys with TTL -- `volatile-ttl`: Evict keys with soonest TTL -- `noeviction`: Return errors when memory full - -## Scaling - -### Manual Scaling - -Fixed number of instances: - -```yaml -services: - - type: web - name: my-app - runtime: node - plan: standard - numInstances: 3 -``` - -### Autoscaling - -Dynamic scaling based on CPU/memory (Professional workspace required): - -```yaml -services: - - type: web - name: my-app - runtime: node - plan: standard - scaling: - minInstances: 1 - maxInstances: 5 - targetCPUPercent: 60 - targetMemoryPercent: 70 -``` - -**Notes:** -- Autoscaling disabled in preview environments -- Preview environments run `minInstances` count -- Requires Professional or higher workspace - -## Health Checks - -Configure health check endpoints: - -```yaml -services: - - type: web - name: my-app - runtime: node - healthCheckPath: /health -``` - -**Default:** `/` (root path) - -**Recommended:** Add a dedicated `/health` endpoint that returns `200 OK`. - -## Build Filters - -Control when builds are triggered based on changed files: - -```yaml -services: - - type: web - name: frontend - runtime: static - buildFilter: - paths: - - frontend/** - ignoredPaths: - - frontend/README.md - - frontend/**/*.test.js -``` - -**Behavior:** -- If `paths` specified: Build only when files in those paths change -- If `ignoredPaths` specified: Don't build when only ignored files change - -## Projects and Environments - -Organize services into projects with multiple environments: - -```yaml -projects: - - name: my-application - environments: - - name: production - services: - - type: web - name: prod-api - runtime: node - plan: pro - buildCommand: npm ci - startCommand: npm start - databases: - - name: prod-postgres - plan: pro-4gb - networking: - isolation: enabled - permissions: - protection: enabled - - - name: staging - services: - - type: web - name: staging-api - runtime: node - plan: starter - buildCommand: npm ci - startCommand: npm start - databases: - - name: staging-postgres - plan: free -``` - -**Environment features:** -- `networking.isolation`: Enable network isolation between environments -- `permissions.protection`: Require approval for environment changes - -## Preview Environments - -Configure automatic preview environments for pull requests: - -```yaml -previews: - generation: auto_preview # auto_preview | manual | none -``` - -**Options:** -- `auto_preview`: Create preview environment for each PR automatically -- `manual`: User manually triggers preview creation -- `none`: Disable preview environments - -## Complete Example - -Full-featured Blueprint with multiple services and databases: - -```yaml -services: - # Web service - - type: web - name: web-app - runtime: node - plan: free - region: oregon - buildCommand: npm ci && npm run build - startCommand: npm start - branch: main - autoDeploy: true - healthCheckPath: /health - envVars: - - key: NODE_ENV - value: production - - key: DATABASE_URL - fromDatabase: - name: postgres - property: connectionString - - key: REDIS_URL - fromDatabase: - name: redis - property: connectionString - - key: JWT_SECRET - sync: false - - # Background worker - - type: worker - name: queue-worker - runtime: node - plan: free - buildCommand: npm ci - startCommand: node worker.js - envVars: - - key: REDIS_URL - fromDatabase: - name: redis - property: connectionString - - # Cron job - - type: cron - name: daily-cleanup - runtime: node - schedule: "0 3 * * *" - buildCommand: npm ci - startCommand: node scripts/cleanup.js - envVars: - - key: DATABASE_URL - fromDatabase: - name: postgres - property: connectionString - - # Static frontend - - type: web - name: frontend - runtime: static - buildCommand: npm ci && npm run build - staticPublishPath: ./dist - routes: - - type: rewrite - source: /* - destination: /index.html - -databases: - - name: postgres - databaseName: app_production - user: app_user - plan: free - postgresMajorVersion: "15" - ipAllowList: [] - - - name: redis - plan: free - maxmemoryPolicy: allkeys-lru - ipAllowList: [] -``` - -## Validation - -Validate your Blueprint before deploying (when CLI command is available): - -```bash -render blueprint validate -``` - -**Common validation errors:** -- Missing required fields -- Invalid runtime values -- Incorrect environment variable references -- Invalid cron expressions -- Invalid YAML syntax - -## Best Practices - -1. **Always use `plan: free` by default** - Let users upgrade if needed -2. **Mark all secrets with `sync: false`** - Never hardcode sensitive values -3. **Use `fromDatabase` for database URLs** - Automatic internal connection strings -4. **Add health check endpoints** - Faster deployment detection -5. **Use non-interactive build commands** - Prevents build hangs -6. **Bind to `0.0.0.0:$PORT`** - Required for web services -7. **Use environment variable groups** - Share config across services -8. **Enable autoDeploy: true** - Deploy automatically on push -9. **Set appropriate regions** - Choose closest to your users -10. **Use build filters** - Optimize build triggers in monorepos - -## Additional Resources - -- Official Blueprint Specification: https://render.com/docs/blueprint-spec -- Render CLI Documentation: https://render.com/docs/cli -- Environment Variables Guide: https://render.com/docs/environment-variables diff --git a/skills/render-deploy/references/blueprints.md b/skills/render-deploy/references/blueprints.md new file mode 100644 index 0000000..35a7b23 --- /dev/null +++ b/skills/render-deploy/references/blueprints.md @@ -0,0 +1,31 @@ + +## Render Blueprints + +A Render Blueprint is a declarative YAML definition of interconnected Render services, databases, and environment groups. The file is usually named `render.yaml` and stored at the root of a Git repository, although its path can be customized when the Blueprint is created. + +Blueprint creation and sync read the file from the linked remote Git repository. Local edits are not available to Render until they are committed and pushed to that repository. + +Do not rely on remembered Blueprint fields, allowed values, defaults, or update behavior. Before creating or modifying a Blueprint, use the documentation-retrieval workflow in the root `SKILL.md` to retrieve and read the [Markdown reference](https://render.com/docs/blueprint-spec.md) or its [HTML version](https://render.com/docs/blueprint-spec). + +If neither version can be retrieved, use the current JSON Schema and Render validation where possible. Use the bundled guidance only for stable workflow and safety constraints, and do not guess at unfamiliar or potentially changed syntax. + +Read the sections relevant to every resource and field being changed. In particular, confirm required fields, service-type support, immutable fields, defaults for new resources, behavior for existing resources, and whether omitting or emptying a field preserves or removes existing configuration. Do not treat an example Blueprint as a complete specification. + +Use the public JSON Schema for editor or programmatic validation: + +```text +https://render.com/schema/render.yaml.json +``` + +When Render CLI v2.7.0 or later is available, validate the finished file: + +```bash +render blueprints validate render.yaml +``` + +Fix validation errors before presenting the Blueprint as ready to deploy. Validation does not apply, sync, or deploy the Blueprint. Schema validation checks structure; Render CLI or API validation can also catch platform-aware errors. If copied examples, the schema, and Render validation disagree, prefer the configuration accepted by current Render validation and call out the discrepancy. + +Blueprint resource names are used to associate definitions with existing resources. Before reusing or changing a name, verify that the Blueprint will manage the intended resource. Do not define the same resource in more than one location, such as both a root-level list and a project environment or `ungrouped`. + +Treat edits to an existing Blueprint as infrastructure changes, not ordinary text edits. Review the proposed diff for replacements, removals, immutable-field changes, and destructive declarative behavior before applying or recommending a sync. Never hardcode secret values in a Blueprint; consult the current environment-variable sections of the specification for supported secret mechanisms and their limitations. + diff --git a/skills/render-deploy/references/codebase-analysis.md b/skills/render-deploy/references/codebase-analysis.md index a258295..99cf2fa 100644 --- a/skills/render-deploy/references/codebase-analysis.md +++ b/skills/render-deploy/references/codebase-analysis.md @@ -29,7 +29,7 @@ Use this reference for framework-specific detection and build/start command sele ## Go Projects - Read `go.mod` for dependencies - Identify web framework (Gin, Echo, Chi, Fiber, net/http) -- Note Go version from `go.mod` +- Note any Go version requirement from `go.mod`. Render's native Go runtime always uses the latest stable Go 1.x release, so use Docker if the project must pin a specific version. ## Static Sites - Look for build output directories (`build/`, `dist/`, `site/`, `public/`) @@ -45,5 +45,5 @@ Use this reference for framework-specific detection and build/start command sele - Build command (e.g., `npm ci`, `pip install -r requirements.txt`, `go build`) - Start command (e.g., `npm start`, `gunicorn app:app`, `./bin/app`) - Environment variables used in code (API keys, database URLs, secrets) -- Database requirements (PostgreSQL, Redis, MongoDB) +- Datastore requirements (PostgreSQL, Key Value, MongoDB) - Port binding (check if app uses an environment variable for port to run on) diff --git a/skills/render-deploy/references/compute-plans.md b/skills/render-deploy/references/compute-plans.md new file mode 100644 index 0000000..74963b6 --- /dev/null +++ b/skills/render-deploy/references/compute-plans.md @@ -0,0 +1,31 @@ + +## Compute plans + +A compute plan determines the CPU and RAM available to each instance of a Render service. Use **compute plan**, not the former term **instance type**. Do not confuse a service's compute plan with its workspace plan, which controls account-level features and limits. + +Compute plans differ by service type: + +- Web services, private services, background workers, and cron jobs use CPU-and-memory plan IDs such as `0.5c-512mb` and `1c-2g`. +- Render Postgres has its own plan catalog and connection limits. +- Render Key Value uses memory-based plan IDs such as `256mb` and `1g`. +- Workflow tasks select a compute plan in application code; a Workflow service does not set a Blueprint `plan`. +- Static sites do not have compute plans. + +Legacy plan names such as `starter`, `standard`, and `pro` remain valid in Render tooling, including Blueprints and API requests. For new configuration, prefer the current plan ID when the selected configuration surface accepts it. Before passing a plan to an API, MCP tool, or CLI command, inspect that operation's current schema or help and use one of its accepted values; the compute-plan reference describes the product catalog, not every tool version's input contract. Do not rename an existing legacy plan merely for consistency unless the user asks for that change. + +Do not rely on a memorized plan catalog. When a task depends on current plan IDs, specifications, defaults, availability, or pricing, fetch the canonical compute-plan reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/compute-plans.md) or its [HTML version](https://render.com/docs/compute-plans). + +Read the section for the relevant service type. If the document cannot be fetched, do not guess at current plan details. Preserve an existing valid plan where possible, or explain that the plan must be confirmed in the Render Dashboard or current documentation. + +When estimating capacity or cost, remember that every instance of a scaled service uses the selected compute plan and is billed accordingly. Changing the compute plan for Render Postgres, Render Key Value, or a service with an attached persistent disk requires brief downtime; other services normally apply the change with a zero-downtime deploy. + + +## Deployment default + +Always use the smallest available compute plan for a particular service type unless the user specifies otherwise. + +## Postgres high availability + +High availability requires PostgreSQL 13 or later and a compute plan with at least 1 CPU. Consult the current [PostgreSQL high availability documentation](https://render.com/docs/postgresql-high-availability.md) before enabling or changing HA. diff --git a/skills/render-deploy/references/configuration-guide.md b/skills/render-deploy/references/configuration-guide.md index baa85f3..4dae83f 100644 --- a/skills/render-deploy/references/configuration-guide.md +++ b/skills/render-deploy/references/configuration-guide.md @@ -4,136 +4,7 @@ Common configuration patterns, best practices, and troubleshooting for Render de ## Environment Variables -### Required vs Optional Variables - -**Always declare ALL environment variables in render.yaml**, even if values are provided by user later. - -**Three categories:** - -1. **Configuration values** (hardcoded): -```yaml -envVars: - - key: NODE_ENV - value: production - - key: LOG_LEVEL - value: info - - key: API_URL - value: https://api.example.com -``` - -2. **Secrets** (user provides): -```yaml -envVars: - - key: JWT_SECRET - sync: false - - key: STRIPE_SECRET_KEY - sync: false - - key: API_KEY - sync: false -``` - -3. **Auto-generated** (Render provides): -```yaml -envVars: - - key: SESSION_SECRET - generateValue: true - - key: ENCRYPTION_KEY - generateValue: true -``` - -### Database Connection Patterns - -**PostgreSQL:** -```yaml -envVars: - - key: DATABASE_URL - fromDatabase: - name: postgres - property: connectionString -``` - -**Redis:** -```yaml -envVars: - - key: REDIS_URL - fromDatabase: - name: redis - property: connectionString -``` - -**Multiple databases:** -```yaml -envVars: - - key: PRIMARY_DB_URL - fromDatabase: - name: postgres-primary - property: connectionString - - key: ANALYTICS_DB_URL - fromDatabase: - name: postgres-analytics - property: connectionString - - key: CACHE_URL - fromDatabase: - name: redis - property: connectionString -``` - -### Cross-Service References - -Reference other services in your account: - -```yaml -services: - - type: web - name: frontend - runtime: node - envVars: - - key: API_URL - fromService: - name: backend-api - type: web - property: host # or hostport, port - - - type: web - name: backend-api - runtime: node -``` - -**Available properties:** -- `host`: Service hostname -- `port`: Service port -- `hostport`: Combined `host:port` - -### Environment Variable Groups - -Share common configuration across services: - -```yaml -envVarGroups: - - name: common-config - envVars: - - key: NODE_ENV - value: production - - key: LOG_LEVEL - value: info - - key: TZ - value: UTC - -services: - - type: web - name: web-app - runtime: node - envVars: - - fromGroup: common-config - - key: PORT - value: 10000 - - - type: worker - name: worker - runtime: node - envVars: - - fromGroup: common-config -``` +Read [environment-variables.md](environment-variables.md) before inspecting or changing configuration. It defines the current documentation, source-of-truth, Blueprint wiring, secret handling, environment-group precedence, and mutation workflow. --- @@ -177,12 +48,22 @@ if __name__ == '__main__': **Python / Django:** -In `settings.py`: +Render automatically provides the web service's `onrender.com` hostname in `RENDER_EXTERNAL_HOSTNAME`. Add it in `settings.py`, along with any custom domains the application serves: ```python -# Django runs on port specified by environment -ALLOWED_HOSTS = ['*'] +import os + +ALLOWED_HOSTS = [] + +render_hostname = os.environ.get('RENDER_EXTERNAL_HOSTNAME') +if render_hostname: + ALLOWED_HOSTS.append(render_hostname) + +# Add known custom domains explicitly when applicable. +# ALLOWED_HOSTS.append('www.example.com') ``` +Do not use `ALLOWED_HOSTS = ['*']` in production, and do not hardcode a guessed `onrender.com` hostname in a reusable Blueprint. + Start command in render.yaml: ```yaml startCommand: gunicorn config.wsgi:application --bind 0.0.0.0:$PORT @@ -303,14 +184,18 @@ buildCommand: bundle install && bundle exec rails assets:precompile ### Build Timeouts -**Free tier:** 15 minutes -**Paid tiers:** Configurable +Render applies these command timeouts across service tiers: + +- **Build command:** 120 minutes +- **Pre-deploy command:** 30 minutes +- **Start command:** 15 minutes + +Do not confuse these command limits with idle spin-down: a Free web service spins down after 15 minutes without inbound traffic. That runtime behavior does not shorten its build-command timeout. **If builds timeout:** 1. Optimize dependencies (remove unused packages) 2. Use build caching 3. Consider pre-building in CI/CD -4. Upgrade to paid tier for longer timeouts --- @@ -320,6 +205,8 @@ buildCommand: bundle install && bundle exec rails assets:precompile **Use internal URLs for better performance:** +Read [private-networking.md](private-networking.md) for current private-network scope and connection requirements. + Use `fromDatabase` to populate an environment variable with the database's internal connection string. ```yaml @@ -332,7 +219,7 @@ envVars: **Benefits:** - Lower latency (same data center) -- No external bandwidth charges +- Private-network traffic does not consume public outbound bandwidth - Automatic internal DNS ### Connection Pooling @@ -374,36 +261,38 @@ DATABASES = { ### Database Migrations -**Run migrations during build:** +For a paid web service, private service, or background worker, run migrations in `preDeployCommand` so they execute after the build and before the new version is deployed: **Django:** ```yaml -buildCommand: pip install -r requirements.txt && python manage.py migrate +buildCommand: pip install -r requirements.txt +preDeployCommand: python manage.py migrate ``` **Rails:** ```yaml -buildCommand: bundle install && bundle exec rails db:migrate +buildCommand: bundle install +preDeployCommand: bundle exec rails db:migrate ``` **Node.js / Prisma:** ```yaml -buildCommand: npm ci && npx prisma migrate deploy +buildCommand: npm ci +preDeployCommand: npx prisma migrate deploy ``` +Free services and service types that do not support a pre-deploy command must use another migration workflow. For a Free web service, include an idempotent migration step in `buildCommand`, for example `pip install -r requirements.txt && python manage.py migrate`. + --- ## Free Tier Limitations ### What's Included -**Free tier provides:** -- 1 web service -- 1 PostgreSQL database (1 GB storage, 97 MB RAM) -- 750 hours/month compute -- 512 MB RAM per service -- 0.5 CPU per service -- 100 GB bandwidth/month +**Free tiers include:** +- Free web services (512 MB RAM, 0.1 CPU, and 750 Free instance hours per workspace each month) +- One active Free PostgreSQL database (1 GB storage, 256 MB RAM, 0.1 CPU) +- Included outbound bandwidth and build pipeline usage ### Resource Limits @@ -492,16 +381,7 @@ services: **Symptom:** Service crashes with "undefined variable" errors -**Solution:** Add all required env vars to render.yaml: -```yaml -envVars: - - key: DATABASE_URL - fromDatabase: - name: postgres - property: connectionString - - key: JWT_SECRET - sync: false # User fills in Dashboard -``` +**Solution:** Follow [environment-variables.md](environment-variables.md), add the missing key through the intended source of truth, and deploy the applicable configuration change. ### Issue 2: Port Binding Errors @@ -515,7 +395,7 @@ app.listen(PORT, '0.0.0.0'); ### Issue 3: Build Hangs -**Symptom:** Build times out after 15 minutes +**Symptom:** Build hangs or reaches the 120-minute build-command timeout **Solution:** Use non-interactive build commands: ```yaml @@ -557,9 +437,9 @@ routes: ## Best Practices Checklist **Environment Variables:** -- [ ] All env vars declared in render.yaml -- [ ] Secrets marked with `sync: false` -- [ ] Database URLs use `fromDatabase` references +- [ ] Required keys configured through the intended source of truth +- [ ] Secrets use an appropriate supported mechanism and are not exposed +- [ ] Resource connection values use current Blueprint references where applicable **Port Binding:** - [ ] App binds to `process.env.PORT` @@ -567,7 +447,7 @@ routes: **Build Commands:** - [ ] Use non-interactive flags (`npm ci`, `-y`, etc.) -- [ ] Build completes under 15 minutes (free tier) +- [ ] Build completes within the 120-minute build-command timeout **Start Commands:** - [ ] Command starts HTTP server correctly @@ -583,7 +463,7 @@ routes: - [ ] SSL enabled if needed **Plans:** -- [ ] Using `plan: free` by default +- [ ] Selected a current Plan ID appropriate to each resource after consulting [compute-plans.md](compute-plans.md); static sites have no compute plan - [ ] Documented upgrade path for users **Git Repository:** @@ -595,7 +475,7 @@ routes: ## Additional Resources -- Blueprint Specification: [blueprint-spec.md](blueprint-spec.md) +- Current Blueprint authoring and validation workflow: [blueprints.md](blueprints.md) - Service Types: [service-types.md](service-types.md) - Runtimes: [runtimes.md](runtimes.md) - Official Render Docs: https://render.com/docs diff --git a/skills/render-deploy/references/deployment-details.md b/skills/render-deploy/references/deployment-details.md index e17bbea..affe4af 100644 --- a/skills/render-deploy/references/deployment-details.md +++ b/skills/render-deploy/references/deployment-details.md @@ -30,44 +30,7 @@ list_key_value() ### Environment Variables -**All environment variables must be declared in render.yaml.** - -**Three patterns for environment variables:** - -1. **Hardcoded values** (non-sensitive configuration): -```yaml -envVars: - - key: NODE_ENV - value: production - - key: API_URL - value: https://api.example.com -``` - -2. **Database connections** (auto-generated): -```yaml -envVars: - - key: DATABASE_URL - fromDatabase: - name: postgres - property: connectionString - - key: REDIS_URL - fromDatabase: - name: redis - property: connectionString -``` - -3. **Secrets** (user fills in Dashboard): -```yaml -envVars: - - key: JWT_SECRET - sync: false - - key: API_KEY - sync: false - - key: STRIPE_SECRET_KEY - sync: false -``` - -Complete environment variable guide: [configuration-guide.md](configuration-guide.md) +Follow [environment-variables.md](environment-variables.md) for the current configuration and mutation workflow. Deployment-specific configuration notes continue in [configuration-guide.md](configuration-guide.md). ### Port Binding @@ -98,9 +61,9 @@ if port == "" { http.ListenAndServe(":"+port, handler) ``` -### Plan Defaults +### Compute plans -**Use `plan: free` unless the user specifies otherwise.** Refer to Render pricing for current limits and capacity. +Select a compute plan appropriate to the resource and workload. Use [compute-plans.md](compute-plans.md) for current Plan IDs, defaults, availability, specifications, and pricing guidance. ### Build Commands @@ -120,47 +83,19 @@ When services connect to databases in the same Render account, use `fromDatabase ### Health Checks -Optional but recommended: add a `/health` endpoint for faster deployment detection. +Follow [deployments.md](deployments.md) for current health-check behavior and endpoint guidance. ## Quick Reference ### MCP Tools (Preferred) -``` -# Service Discovery -list_services() -get_service(serviceId: "") -list_postgres_instances() -list_key_value() -# Service Creation -create_web_service(name, runtime, buildCommand, startCommand, ...) -create_static_site(name, buildCommand, publishPath, ...) -create_cron_job(name, runtime, schedule, buildCommand, startCommand, ...) -create_postgres(name, plan, region) -create_key_value(name, plan, region) - -# Environment Variables -update_environment_variables(serviceId, envVars: [{key, value}, ...]) - -# Deployment & Monitoring -list_deploys(serviceId, limit) -list_logs(resource: [""], level: ["error"]) -get_metrics(resourceId, metricTypes: [...]) - -# Workspace -get_selected_workspace() -list_workspaces() -``` +Follow [render-access.md](render-access.md) and inspect the tools currently available instead of relying on a fixed tool catalog. ### CLI Commands ```bash # Validate Blueprint render blueprints validate -# Check workspace -render workspace current -o json -render workspace set - # List services render services -o json @@ -180,7 +115,7 @@ render deploys create --wait - Docker: [../assets/docker.yaml](../assets/docker.yaml) ### Documentation -- Full Blueprint specification: [blueprint-spec.md](blueprint-spec.md) +- Current Blueprint authoring and validation workflow: [blueprints.md](blueprints.md) - Service types explained: [service-types.md](service-types.md) - Runtime options: [runtimes.md](runtimes.md) - Configuration guide: [configuration-guide.md](configuration-guide.md) @@ -201,7 +136,7 @@ render deploys create --wait **Issue:** Missing environment variables in Dashboard -**Solution:** All env vars must be declared in render.yaml. Add missing vars with `sync: false` for secrets. +**Solution:** Follow [environment-variables.md](environment-variables.md), identify the intended source of truth, and add the missing keys without exposing secret values. --- diff --git a/skills/render-deploy/references/deployments.md b/skills/render-deploy/references/deployments.md new file mode 100644 index 0000000..5ca9905 --- /dev/null +++ b/skills/render-deploy/references/deployments.md @@ -0,0 +1,50 @@ + +## Deployments and health checks + +A Render deploy is asynchronous. A successful trigger means only that Render accepted or queued the deploy; it does not mean the new version is live. Before triggering a deploy, confirm the workspace, service, intended source commit or image, and current live deploy. Capture the new deploy ID, monitor it to a terminal state, and do not report success until its status is `live` and the deployed workload has been verified. + +Before configuring or troubleshooting deployments and health checks, fetch the current Render references: + +- [deploys.md](https://render.com/docs/deploys.md) (HTML: ) +- [health-checks.md](https://render.com/docs/health-checks.md) (HTML: ) + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read both references. + +Read the relevant sections of both documents. Confirm current service-type support, command timeouts, health-check thresholds, rollout behavior, and configuration syntax rather than relying on remembered values. + +Automatic deployment behavior depends on the service's source and settings. A service linked to a branch through a connected Git provider can deploy on each commit, wait for supported CI checks, or require manual triggers. Services that pull a prebuilt image and services linked by a public Git repository URL require manual deploys; moving a mutable image tag does not itself trigger one. When manually deploying a historical commit, verify whether that trigger method changes automatic-deploy settings. If automatic deploys remain enabled, a later branch update can replace the selected commit. + +The normal lifecycle is build command, optional pre-deploy command, then start command and readiness checks. If a command fails or times out, the deploy fails and later steps do not run. A pre-deploy command runs after the build on a separate instance before the new version is deployed. Neither the build nor pre-deploy instance can access an attached persistent disk, and pre-deploy filesystem changes do not carry into the running service. Use pre-deploy for release tasks such as database migrations, not for producing runtime artifacts. Pre-deploy commands are supported for paid web services, private services, and background workers. + +Render normally deploys services without downtime by starting the new version before retiring the current one. Web and private services continue routing traffic to the current instances until the new instances are ready. Multi-instance services roll out one instance at a time; if a replacement does not become healthy, Render cancels the rollout and retains or restores the previous version. Attaching a persistent disk disables zero-downtime deploys, so plan explicitly for an interruption. + +A workflow deployment has a different completion model. It builds and caches the image used by future task runs and includes a task-registration step, but it does not execute those tasks. After a workflow deploy succeeds, verify that the expected task definitions are registered. Trigger and monitor a task run separately only when execution is intended. For workflow-specific deployment behavior, fetch the current workflow overview: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/workflows.md) or its [HTML version](https://render.com/docs/workflows). + +Health checks apply to web services and private services. Both use TCP socket checks by default. Only web services support a configured HTTP health-check path. Render sends an HTTP `GET`; any `2xx` or `3xx` response received within five seconds succeeds, while other status codes, timeouts, and connection failures fail. Private services support TCP checks only. + +For a new deploy, all new instances must pass their checks at the same time within the current readiness window, documented as 15 minutes, before Render routes traffic to them. For a running service, consecutive failures currently remove an instance from routing after 15 seconds and restart it after 60 seconds. Treat these thresholds as platform behavior, not user-tunable health-check interval settings, and verify them in the fetched reference before relying on exact timing. + +Design an HTTP health endpoint to represent readiness for production traffic. Keep it fast and side-effect free. Check critical dependencies only when losing that dependency should make the entire instance unavailable; otherwise a transient dependency failure can unnecessarily remove healthy application capacity. Verify the configured path, response status, response time, listening port, and `0.0.0.0` binding when checks fail. + +After traffic moves, Render gives the previous instance a drain period, then sends `SIGTERM`. The application should stop accepting new work, finish or safely abandon in-flight work, close connections, and exit within its shutdown delay. Ensure the actual application process receives the signal: container entrypoints and shell wrappers should use `exec` or explicitly forward signals. Render sends `SIGKILL` if the process remains running after the delay. The documented default shutdown delay is 30 seconds and the usual maximum is 300 seconds, but support varies by service configuration; confirm the current reference and Blueprint or API validation before setting `maxShutdownDelaySeconds`. + +A service restart is a special deploy of the same commit and user-defined environment-variable values as the current running instance. It does not incorporate configuration changes saved after that deploy. Use a standard deploy when pending configuration must take effect. + +Only one deploy runs at a time for a service. A workspace's overlapping-deploy policy determines whether a new trigger waits or cancels the in-progress deploy. Do not assume the policy or wait for every intermediate revision: inspect the workspace setting and identify the deploy that actually became live. + +Treat rollback as a new deploy based on a retained previous build artifact, not as restoration of the entire service to an earlier point in time. It does not reverse database migrations, messages, external writes, or other side effects from the release, so confirm that the previous application version remains compatible with current external state. Disks and their data are not rolled back, some settings continue using current configuration, mutable image tags can resolve to a different image, and eligible artifacts are retained only for a limited period. Before rolling back, fetch the current rollback reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/rollbacks.md) or its [HTML version](https://render.com/docs/rollbacks). + +Read which configuration comes from the target deploy and which remains current. After the rollback is created, inspect the service's resulting automatic-deploy setting instead of assuming whether it remains enabled, and deliberately restore the intended setting after the underlying issue is resolved. + +Deploy hooks are secret credentials that authorize deploys. Never print, commit, or expose their full URLs. Before using one, fetch the current deploy-hook reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/deploy-hooks.md) or its [HTML version](https://render.com/docs/deploy-hooks). + +Distinguish an immediately started deploy from a queued one, and continue monitoring the resulting deploy rather than treating the HTTP response as completion. + +After a deploy becomes live, verify the behavior appropriate to the service type: make a request to a web or private service, confirm a worker is processing work, confirm a cron job or workflow invocation completes, and inspect recent runtime logs for new errors. If a deploy fails, diagnose the first failed lifecycle stage before retrying. + diff --git a/skills/render-deploy/references/direct-creation.md b/skills/render-deploy/references/direct-creation.md index 6187245..ba04831 100644 --- a/skills/render-deploy/references/direct-creation.md +++ b/skills/render-deploy/references/direct-creation.md @@ -2,6 +2,8 @@ Use this reference for MCP direct-creation examples and follow-on configuration. +The plan values below are examples, not a current plan catalog. Before creating a resource, use [compute-plans.md](compute-plans.md) to select an appropriate plan, then inspect the active MCP tool's schema and pass a value it accepts. Some MCP versions accept legacy plan names but not the corresponding current Plan ID. + ## Direct Creation Workflow ### Step 1: Analyze Codebase @@ -19,7 +21,7 @@ create_web_service( branch: "main", # optional, defaults to repo default branch buildCommand: "npm ci", startCommand: "npm start", - plan: "free", # free, starter, standard, pro, pro_max, pro_plus, pro_ultra + plan: "free", region: "oregon", # oregon, frankfurt, singapore, ohio, virginia envVars: [ {"key": "NODE_ENV", "value": "production"} @@ -50,7 +52,7 @@ create_cron_job( schedule: "0 0 * * *", # Daily at midnight (cron syntax) buildCommand: "npm ci", startCommand: "node scripts/cleanup.js", - plan: "free" + plan: "starter" ) ``` @@ -58,16 +60,16 @@ create_cron_job( ``` create_postgres( name: "myapp-db", - plan: "free", # free, basic_256mb, basic_1gb, basic_4gb, pro_4gb, etc. + plan: "free", region: "oregon" ) ``` -**Create a Key-Value Store (Redis):** +**Create a Key Value instance:** ``` create_key_value( name: "myapp-cache", - plan: "free", # free, starter, standard, pro, pro_plus + plan: "free", region: "oregon", maxmemoryPolicy: "allkeys_lru" # eviction policy ) @@ -94,6 +96,8 @@ update_environment_variables( Services with `autoDeploy: "yes"` (default) will deploy automatically when created. +Follow [deployments.md](deployments.md) to identify the resulting deploy, monitor it to a terminal state, and verify the workload. The creation response alone is not deployment success. + **Check deployment status:** ``` list_deploys(serviceId: "", limit: 1) diff --git a/skills/render-deploy/references/environment-variables.md b/skills/render-deploy/references/environment-variables.md new file mode 100644 index 0000000..e9de03c --- /dev/null +++ b/skills/render-deploy/references/environment-variables.md @@ -0,0 +1,38 @@ + +## Environment variables and secrets + +Render environment-variable values are strings. Applications must explicitly parse values that represent booleans, numbers, lists, or structured data; for example, the string `"false"` is truthy in many languages. + +Environment variables can be managed through the Render Dashboard, Blueprints, environment groups, and supported API, MCP, or CLI operations. Before changing a service, determine which mechanism is intended to be the source of truth. Do not make parallel Dashboard and infrastructure-as-code edits without explaining how future syncs or deploys will reconcile them. + +Never commit secret values to application source, `render.yaml`, checked-in `.env` files, fixtures, examples, or logs. Keep local secret-bearing `.env` files out of version control. Do not print or repeat secret values returned by the user, Render, or another provider. Use Render's supported secret mechanisms or an external secret manager appropriate to the user's workflow. + +Before configuring environment variables, secret files, or environment groups, fetch the current Render configuration reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/configure-environment-variables.md) or its [HTML version](https://render.com/docs/configure-environment-variables). + +Read the sections relevant to the configuration surface being used. Dashboard save options can rebuild and deploy, deploy the existing build, or save without deploying; do not assume a changed value is active until the applicable deploy occurs. + +For Blueprint-managed variables, also consult the current Blueprint YAML reference before writing syntax or predicting update behavior. In particular: + +- Use literal `value` entries only for non-sensitive configuration. +- `generateValue: true` creates a platform-generated secret when the variable does not already exist. +- `sync: false` prompts for a value only during initial Blueprint creation. It is ignored for existing services during later Blueprint updates, is not included in preview environments, and is not valid in environment groups. +- Use current `fromDatabase`, `fromService`, and `fromGroup` syntax instead of hardcoding connection strings or copying shared values. + +Blueprint syncs preserve existing service environment variables that are omitted from the Blueprint; omission does not delete them. Values defined with `fromDatabase` or `fromService` refresh on each Blueprint sync, not immediately when the referenced property or variable changes. + +Environment groups provide shared variables and secret files to linked services. A variable defined directly on a service takes precedence over the same key from a linked group. Precedence between multiple linked groups with the same key is not guaranteed; avoid collisions instead of depending on group creation order. Respect project-environment scoping when linking groups to services. + +Use secret files for credentials or configuration that must be read from the filesystem rather than an environment variable. Confirm current size and runtime-path rules in the fetched reference. Treat secret-file contents with the same precautions as other credentials. + +Render also injects documented default environment variables. Do not maintain a memorized catalog. Fetch the current default-variable reference when a task depends on a variable's name, availability, build/runtime scope, or semantics: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/environment-variables.md) or its [HTML version](https://render.com/docs/environment-variables). + +Depend only on documented platform variables. Other `RENDER_*` variables are internal and can change without notice. + +Treat environment-variable changes as service configuration mutations. Confirm the target workspace and service, inspect the existing keys without exposing their values, and preserve variables outside the user's requested scope. Before using an API, MCP, or CLI operation, check whether it patches individual keys or replaces the complete collection. After the applicable deploy, verify that required keys are present and that the service starts successfully without logging secret values. + +If the current references or live configuration cannot be inspected, do not guess at secret behavior, precedence, or replacement semantics. Preserve existing configuration where possible and explain what must be confirmed before making the change. + diff --git a/skills/render-deploy/references/post-deploy-checks.md b/skills/render-deploy/references/post-deploy-checks.md index a14e8e4..7ef5123 100644 --- a/skills/render-deploy/references/post-deploy-checks.md +++ b/skills/render-deploy/references/post-deploy-checks.md @@ -1,6 +1,6 @@ # Post-deploy checks -Use this after any deploy or service creation. Keep it short; stop when a check fails. +Use this after any deploy or service creation. First follow [deployments.md](deployments.md) to identify the specific deploy, monitor it to a terminal state, and choose service-type-appropriate verification. Keep the checks below short; stop when one fails. ## 1) Confirm deploy status @@ -8,13 +8,13 @@ Use this after any deploy or service creation. Keep it short; stop when a check list_deploys(serviceId: "", limit: 1) ``` -- Expect `status: "live"`. +- Do not report success until the intended deploy is `live`. - If status is failed, inspect build/runtime logs immediately. ## 2) Verify service health -- Hit the health endpoint (preferred) or `/` and confirm a 200 response. -- If there is no health endpoint, add one and redeploy. +- For web services, exercise the intended public behavior and any configured health endpoint. +- For other service types, use the verification appropriate to the workload in [deployments.md](deployments.md). ## 3) Scan recent error logs diff --git a/skills/render-deploy/references/private-networking.md b/skills/render-deploy/references/private-networking.md new file mode 100644 index 0000000..d68d6be --- /dev/null +++ b/skills/render-deploy/references/private-networking.md @@ -0,0 +1,25 @@ + +## Private networking + +Render services can communicate over a private network without traversing the public internet. Private-network peers must belong to the same workspace and run in the same region. An isolated project environment can additionally block traffic both to and from resources outside that environment, so workspace and region matching alone do not guarantee connectivity. + +Before designing, configuring, or troubleshooting private-network communication, fetch the current Render private-network reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/private-network.md) or its [HTML version](https://render.com/docs/private-network). + +Read the relevant sections. Confirm current service-type capabilities, port restrictions, environment-isolation behavior, discovery-hostname guidance, and plan requirements instead of relying on a memorized catalog. + +Web services and private services have internal hostnames and can receive private-network traffic. A private service must bind at least one port; use a background worker instead when a workload does not need to accept inbound connections. Render Postgres and Key Value instances provide internal connection URLs. Workflows, background workers, and cron jobs can initiate private-network connections but do not have an internal address for receiving them. Static sites are not on the private network. Free web services can initiate private-network connections but cannot receive them. + +Prefer the internal address or URL shown under **Connect > Internal** in the Render Dashboard. Include the protocol when the client or server requires one; an address such as `service:10000` does not by itself establish whether to use HTTP, HTTPS, or another protocol. A process that receives traffic must listen on the intended port and on an interface reachable outside its own container, such as `0.0.0.0`, rather than only on loopback. + +For Blueprint-managed connections, fetch the current Blueprint specification and use supported service or database references instead of copying a generated hostname, port, credential, or connection string. Web and private services currently expose `host`, `port`, and `hostport` properties. A Blueprint can obtain another service's discovery hostname by referencing that service's `RENDER_DISCOVERY_SERVICE` environment variable with `fromService.envVarKey`; the discovery hostname is not a service property. The fetched specification is authoritative for the syntax and supported references. + +A service can expose at most 75 ports on the private network. Ports `18012`, `18013`, and `19099` are unavailable for private-network communication. Port `10000` is not generally blocked: for a web service, private traffic to port `10000` routes to its primary HTTP server even when that server binds to another port. In that case, both port `10000` and the actual primary HTTP port route to the same server. + +Use a service's normal internal hostname for ordinary service-to-service traffic. For advanced per-instance communication, each web or private service has a discovery hostname, conventionally formed by appending `-discovery` to its internal hostname, that resolves to all active instance IP addresses. A service receives its own discovery hostname in `RENDER_DISCOVERY_SERVICE`. Use DNS APIs that honor the system resolver configuration, and do not persist resolved instance IPs because they can change between deploys. Prefer hostname-based communication unless per-instance addressing or custom load balancing is specifically required. + +When a private-network connection fails, verify the workspace, region, project-environment isolation settings, whether the destination service type accepts inbound traffic, the internal hostname or URL, protocol, port, listening interface, current deploy health, and DNS resolution. Do not substitute a public URL or expose a private service merely to bypass a private-network configuration problem. + +AWS PrivateLink is a separate Pro-or-higher feature for connecting a Render private network to compatible AWS-hosted systems. Fetch its current documentation before proposing or configuring it; do not treat ordinary Render service-to-service networking and PrivateLink as interchangeable. + diff --git a/skills/render-deploy/references/render-access.md b/skills/render-deploy/references/render-access.md new file mode 100644 index 0000000..864c854 --- /dev/null +++ b/skills/render-deploy/references/render-access.md @@ -0,0 +1,50 @@ + +## Accessing Render + +Prefer the hosted Render MCP server for structured access to Render resources when its tools are available. Use the Render CLI when MCP is unavailable or does not support the required operation, and use the Render Dashboard or API for capabilities exposed by neither. Do not assume that a remembered MCP tool or CLI command is still available; inspect the tools in the current environment or consult the current documentation. + +The hosted Render MCP server uses streamable HTTP at: + +```text +https://mcp.render.com/mcp +``` + +Official Render plugins and connectors can authenticate MCP with browser-based OAuth. Manual and non-interactive configurations can use a Render API key as a bearer token. Never write an API key or OAuth token into a repository, skill, command output, chat response, or log. Prefer the client's supported secret storage or environment-variable mechanism. If a client requires a credential in local configuration, keep that file out of version control and restrict access to it. + +Treat MCP responses as potentially sensitive even when the server attempts to minimize credential exposure. Request connection strings, credentials, secret environment variables, or other sensitive fields only when the task requires them. Do not repeat sensitive values in the response or persist them in files or logs. + +Before configuring or troubleshooting MCP, fetch the current setup and capability reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/mcp-server.md) or its [HTML version](https://render.com/docs/mcp-server). + +Read the relevant client setup, supported-actions, and limitations sections. Prefer the hosted server unless the user's environment requires a local MCP server. After installing, updating, or reconfiguring an MCP integration, reload the client as required and verify the connection with a read-only operation such as listing services. + +Most MCP operations and Render CLI commands that access Render resources are scoped to an active workspace. Check the selected workspace before reading or changing resources. If no workspace is selected—or if the intended workspace is ambiguous—list the available workspaces and have the user identify the correct one. Do not silently switch workspace context or infer it from a resource name. Commands for authentication, help, CLI configuration, and workspace discovery or selection do not require an already selected workspace. + +For interactive CLI use, authenticate with `render login`. For automation, use a securely stored `RENDER_API_KEY`; an API key takes precedence over a saved CLI token. Verify CLI access and the active workspace with read-only commands before operating on resources: + +```bash +render whoami --output json +render workspace current --output json +``` + +For CLI installation, authentication, workspace setup, and usage patterns, fetch the current CLI overview: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/cli.md) or its [HTML version](https://render.com/docs/cli). + +For exact command syntax and flags, prefer the help text from the installed CLI because it matches the version being used: + +```bash +render help +``` + +The published CLI command reference is generated automatically from the CLI's help text. Use it to browse the full command surface or when the CLI is not installed: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/cli-reference.md) or its [HTML version](https://render.com/docs/cli-reference). + +When an agent or automation invokes the CLI, select a non-interactive output format such as `--output json`, `--output yaml`, or `--output text` so results can be inspected reliably. The global `--confirm` flag skips confirmation prompts; use it for a mutating command only after that mutation is authorized. It is an execution convenience, not permission to perform the action. + +Authentication establishes access; it does not establish user authorization for every available action. Use read-only discovery to resolve workspace, resource identity, and current state before a mutation. Perform changes only when they are within the user's requested scope, and retain normal approval requirements for consequential operations such as creation, configuration changes, deploys, restarts, scaling, or deletion. + +When authentication or connectivity fails, report which access path failed, preserve the underlying error without exposing credentials, and either use an available supported fallback or explain what the user must configure before the task can continue. + diff --git a/skills/render-deploy/references/runtimes.md b/skills/render-deploy/references/runtimes.md index 9e11757..3bf4f5c 100644 --- a/skills/render-deploy/references/runtimes.md +++ b/skills/render-deploy/references/runtimes.md @@ -6,8 +6,7 @@ Complete guide to available runtimes on Render, including versions, configuratio ### Node.js (`runtime: node`) -**Supported Versions:** 14, 16, 18, 20, 21 -**Default Version:** 20 +**Current Default Version:** 24.14.1 **Version Specification:** @@ -15,7 +14,7 @@ Specify Node version in `package.json`: ```json { "engines": { - "node": "20.x" + "node": "24.14.1" } } ``` @@ -56,24 +55,31 @@ buildCommand: npm ci && npm run build startCommand: npm start ``` +For NextAuth.js v4, `NEXTAUTH_URL` must be the application's canonical public URL. Render injects the service's `onrender.com` hostname as `RENDER_EXTERNAL_HOSTNAME`, but Blueprint environment-variable values do not interpolate other environment variables. A reusable service can derive the default at startup while allowing an explicitly configured custom-domain URL to take precedence: + +```yaml +startCommand: NEXTAUTH_URL="${NEXTAUTH_URL:-https://$RENDER_EXTERNAL_HOSTNAME}" npm start +``` + +Set `NEXTAUTH_URL` explicitly when a custom domain should be canonical. Do not hardcode a guessed `onrender.com` hostname in a reusable Blueprint. + --- ### Python (`runtime: python`) -**Supported Versions:** 3.8, 3.9, 3.10, 3.11, 3.12 -**Default Version:** 3.11 +**Current Default Version:** 3.14.3 +**Minimum Supported Version:** 3.7.3 **Version Specification:** -Option 1 - `runtime.txt`: +Option 1 - `PYTHON_VERSION` environment variable (must be fully qualified): ``` -python-3.11.5 +PYTHON_VERSION=3.14.3 ``` -Option 2 - `Pipfile`: -```toml -[requires] -python_version = "3.11" +Option 2 - `.python-version`: +``` +3.14.3 ``` **Package Managers:** @@ -116,17 +122,11 @@ startCommand: gunicorn app:app --bind 0.0.0.0:$PORT ### Go (`runtime: go`) -**Supported Versions:** 1.20, 1.21, 1.22, 1.23 -**Default Version:** Latest stable - -**Version Specification:** +**Current Default Version:** Latest stable Go 1.x -Specify in `go.mod`: -```go -module myapp +Render automatically updates its native Go runtime to the latest stable Go 1.x release, usually within 24 hours of a new release. A service begins using the updated version with its next deploy. -go 1.22 -``` +Native Go services cannot pin a Go runtime version with `go.mod` or another setting. Use `runtime: docker` if the service requires a specific Go version. **Build System:** Uses Go modules @@ -164,19 +164,19 @@ startCommand: ./bin/app ### Ruby (`runtime: ruby`) -**Supported Versions:** 3.0, 3.1, 3.2, 3.3 -**Default Version:** 3.3 +**Current Default Version:** 3.4.4 +**Minimum Supported Version:** 3.1.0 **Version Specification:** Option 1 - `.ruby-version`: ``` -3.3.0 +3.4.4 ``` Option 2 - `Gemfile`: ```ruby -ruby '3.3.0' +ruby '3.4.4' ``` **Package Manager:** Bundler (uses `Gemfile` and `Gemfile.lock`) @@ -213,8 +213,7 @@ startCommand: bundle exec puma -C config/puma.rb ### Rust (`runtime: rust`) -**Supported Versions:** Latest stable -**Default Version:** Latest stable +**Default Version:** Latest stable Rust toolchain **Build System:** Cargo @@ -248,8 +247,7 @@ startCommand: ./target/release/myapp ### Elixir (`runtime: elixir`) -**Supported Versions:** Latest stable -**Default Version:** Latest stable +**Current Defaults:** Elixir 1.18.4 and Erlang/OTP 28.0.2 **Build System:** Mix @@ -334,15 +332,16 @@ CMD ["node", "dist/main.js"] Deploy pre-built Docker images from a container registry. **Additional Configuration:** -- `image`: Full image URL with tag or digest -- `registryCredential`: Credentials for private registries +- `image.url`: Full image URL with tag or digest +- `image.creds.fromRegistryCreds.name`: Dashboard-stored registry credential for private images **Example with Public Image:** ```yaml type: web name: prebuilt-app runtime: image -image: ghcr.io/myorg/myapp:v1.2.3 +image: + url: ghcr.io/myorg/myapp:v1.2.3 ``` **Example with Private Registry:** @@ -350,11 +349,11 @@ image: ghcr.io/myorg/myapp:v1.2.3 type: web name: private-app runtime: image -image: myregistry.com/myapp:latest -registryCredential: - username: my-username - password: - sync: false # User provides in Dashboard +image: + url: registry.example.com/myapp:latest # Replace with your registry host + creds: + fromRegistryCreds: + name: my-registry-credential ``` **Use Cases:** diff --git a/skills/render-deploy/references/service-types.md b/skills/render-deploy/references/service-types.md index b3a0834..a0a3786 100644 --- a/skills/render-deploy/references/service-types.md +++ b/skills/render-deploy/references/service-types.md @@ -1,449 +1,37 @@ -# Render Service Types + +## Render service types -Detailed explanation of each service type available on Render. Choose the right service type based on your application's needs. +Use this guidance when selecting or comparing Render service types, or when a task's architecture depends on the distinction between them. A task that is already unambiguously scoped to one service type does not need this entire overview. -## Web Services (`type: web`) +On Render, a service represents code deployed for a particular execution model. Render runs that service on one or more instances, and the service's compute plan determines the CPU and memory available to each instance. -### Purpose +Before choosing a service type, fetch the current service-types reference: -Web services are HTTP servers that handle incoming requests from the internet. They're publicly accessible via HTTPS URLs. +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/service-types.md) or its [HTML version](https://render.com/docs/service-types). -### Use Cases +If neither version can be retrieved, use the bundled overview below only for basic service-type selection. State that current platform details could not be verified, and do not guess about changeable capabilities such as supported runtimes, plans, scaling, networking, disks, health checks, deployment behavior, availability, or limits. -- **REST APIs**: JSON APIs for mobile apps or frontend applications -- **GraphQL servers**: GraphQL endpoints for client queries -- **Web applications**: Server-rendered websites (Django, Rails, Express) -- **Full-stack frameworks**: Next.js, Nuxt.js, Remix, SvelteKit -- **WebSocket servers**: Real-time communication servers -- **SSR applications**: Server-side rendered React, Vue, or Angular apps +Render provides six public service types for running code: -### Key Characteristics +- **Web service:** A continuously running server that receives public HTTP traffic and also has an internal hostname for private-network traffic. Use it for dynamic websites, APIs, and other internet-facing server applications. +- **Static site:** Built HTML, CSS, JavaScript, and other static assets served publicly from Render's global CDN. Use it only when the deployed application does not require server-side runtime logic. +- **Private service:** A continuously running server that receives traffic only over Render's private network. Use it for internal HTTP, TCP, gRPC, or other server processes that need an internal hostname but no public URL. +- **Background worker:** A continuously running process that does not receive incoming traffic or expose a public or internal hostname. Use it for queue consumers and other processes that pull or poll for work. +- **Cron job:** A command or process that starts on a schedule, performs a bounded unit of work, and exits. Use it for straightforward recurring tasks rather than an always-running process. +- **Workflow:** A collection of on-demand tasks executed across distributed compute, with Render handling task queuing, orchestration, and provisioning. Use it when the workload benefits from independently invoked tasks, retries, composition, or parallel execution instead of a continuously running worker process. -- **Public URL**: Automatically assigned `https://[service-name].onrender.com` -- **Port binding required**: Must bind to `0.0.0.0:$PORT` -- **Health checks**: Render pings your service to verify it's running -- **HTTPS**: Automatic SSL/TLS certificates -- **Load balancing**: Traffic distributed across multiple instances -- **Custom domains**: Support for your own domain names +Choose based on how the code executes and receives work: -### Required Configuration +- Public incoming traffic that requires server-side logic belongs on a web service. Public static assets with no runtime server belong on a static site. +- An application that needs both public and private ingress remains a web service; use its internal hostname for traffic from other Render services. +- A process that receives private-network requests belongs on a private service. A process that only initiates connections and pulls work belongs on a background worker. +- A simple scheduled command that exits belongs on a cron job. An always-running queue consumer belongs on a background worker. On-demand or distributed tasks for which Render should manage queuing and per-run compute belong in a workflow. -```yaml -type: web -name: my-api -runtime: node -buildCommand: npm ci -startCommand: npm start -``` +Cron jobs and Workflows use invocation-based execution models. The ordinary instance-count and autoscaling model used by continuously running services does not apply to them. -### Best Practices +Render Postgres and Render Key Value are fully managed datastores, not general-purpose compute service types for running application code. Use Render Postgres for relational data and Render Key Value for use cases such as shared caching and job queues. An attached persistent disk is a storage feature of certain compute services, not a service type of its own. -1. **Bind to environment PORT**: -```javascript -const PORT = process.env.PORT || 3000; -app.listen(PORT, '0.0.0.0'); -``` +After selecting a type, fetch the product article linked from the service-types reference before relying on details such as supported runtimes and sources, plans, scaling, networking, disks, health checks, deployment behavior, scheduling semantics, availability, or limits. These capabilities are not uniform across service types and can change independently. -2. **Add health check endpoint**: -```javascript -app.get('/health', (req, res) => { - res.status(200).json({ status: 'ok' }); -}); -``` - -3. **Use appropriate timeouts**: Web requests should complete within 30 seconds - -4. **Implement graceful shutdown**: Handle SIGTERM signals properly - ---- - -## Worker Services (`type: worker`) - -### Purpose - -Worker services run background tasks without handling HTTP requests. They're not publicly accessible. - -### Use Cases - -- **Queue processors**: Redis queue, BullMQ, Celery, Sidekiq -- **Background jobs**: Email sending, image processing, data exports -- **Event consumers**: Message queue consumers (Kafka, RabbitMQ, etc.) -- **Data pipeline workers**: ETL processes, data transformation -- **Scheduled background tasks**: Continuous processes (not cron) -- **WebSocket backend**: Dedicated WebSocket handler services - -### Key Characteristics - -- **No public URL**: Not accessible from internet -- **No port binding**: Doesn't need to listen on a port -- **No health checks**: Render monitors process health differently -- **Long-running**: Can run indefinitely -- **Private communication**: Access via internal networking -- **Restart on crash**: Automatically restarted if process dies - -### Required Configuration - -```yaml -type: worker -name: queue-processor -runtime: python -buildCommand: pip install -r requirements.txt -startCommand: celery -A tasks worker --loglevel=info -``` - -### Best Practices - -1. **Connect to message queue**: -```python -import redis -r = redis.from_url(os.environ['REDIS_URL']) -``` - -2. **Implement retry logic**: Handle failures gracefully - -3. **Monitor queue depth**: Track pending jobs - -4. **Log processing status**: Make debugging easier - -5. **Graceful shutdown**: Finish current jobs before exiting - -### Common Patterns - -**Node.js with BullMQ:** -```yaml -type: worker -name: job-processor -runtime: node -buildCommand: npm ci -startCommand: node worker.js -envVars: - - key: REDIS_URL - fromDatabase: - name: redis - property: connectionString -``` - -**Python with Celery:** -```yaml -type: worker -name: celery-worker -runtime: python -buildCommand: pip install -r requirements.txt -startCommand: celery -A app.celery worker -envVars: - - key: REDIS_URL - fromDatabase: - name: redis - property: connectionString -``` - ---- - -## Cron Jobs (`type: cron`) - -### Purpose - -Cron jobs run scheduled tasks on a repeating schedule. They execute, complete, and shut down. - -### Use Cases - -- **Database backups**: Regular automated backups -- **Report generation**: Daily/weekly reports -- **Data cleanup**: Delete old records periodically -- **Cache warming**: Pre-populate caches -- **Email digests**: Send scheduled email summaries -- **Data synchronization**: Sync between systems -- **Batch processing**: Process accumulated data - -### Key Characteristics - -- **Scheduled execution**: Runs on cron schedule -- **Automatic shutdown**: Shuts down after completing -- **No persistent port**: Doesn't maintain listening port -- **No health checks**: Task either completes or fails -- **UTC timezone**: All schedules in UTC -- **Maximum runtime**: Jobs timeout after configured limit - -### Required Configuration - -```yaml -type: cron -name: daily-backup -runtime: node -schedule: "0 2 * * *" # Daily at 2 AM UTC -buildCommand: npm ci -startCommand: node scripts/backup.js -``` - -### Schedule Format - -Standard cron syntax: `minute hour day month weekday` - -**Common schedules:** - -| Schedule | Description | -|----------|-------------| -| `*/5 * * * *` | Every 5 minutes | -| `0 * * * *` | Every hour | -| `0 0 * * *` | Daily at midnight UTC | -| `0 9 * * 1-5` | Weekdays at 9 AM UTC | -| `0 0 1 * *` | First day of each month | -| `0 9 * * 1` | Every Monday at 9 AM UTC | - -### Best Practices - -1. **Handle failures gracefully**: Jobs should be idempotent - -2. **Log completion status**: Track success/failure - -3. **Set appropriate timeouts**: Match expected job duration - -4. **Use UTC times**: All schedules are UTC-based - -5. **Test thoroughly**: Test with different data scenarios - -### Example Use Cases - -**Daily Database Backup:** -```yaml -type: cron -name: db-backup -runtime: python -schedule: "0 1 * * *" # 1 AM UTC daily -buildCommand: pip install -r requirements.txt -startCommand: python scripts/backup.py -envVars: - - key: DATABASE_URL - fromDatabase: - name: postgres - property: connectionString - - key: S3_BUCKET - value: my-backups -``` - -**Hourly Cache Refresh:** -```yaml -type: cron -name: cache-refresh -runtime: node -schedule: "0 * * * *" # Top of every hour -buildCommand: npm ci -startCommand: node scripts/refresh-cache.js -``` - ---- - -## Static Sites (`type: web` + `runtime: static`) - -### Purpose - -Serve static HTML, CSS, and JavaScript files via CDN. No backend runtime. - -### Use Cases - -- **Single Page Applications (SPAs)**: React, Vue, Angular apps -- **Static site generators**: Gatsby, Next.js (static export), Hugo -- **Documentation sites**: MkDocs, Docusaurus, VitePress -- **Landing pages**: Marketing sites -- **Portfolio sites**: Personal websites -- **JAMstack sites**: Static sites with API integration - -### Key Characteristics - -- **CDN delivery**: Global edge caching -- **No backend runtime**: Only serves built files -- **Build output only**: Serves contents of build directory -- **Routing support**: Rewrite rules for SPA routing -- **Custom headers**: Cache control, security headers -- **Fast deployment**: Quick to build and deploy - -### Required Configuration - -```yaml -type: web -name: frontend -runtime: static -buildCommand: npm ci && npm run build -staticPublishPath: ./dist # or ./build, ./out, ./public -``` - -### Routing for SPAs - -Single Page Applications need rewrite rules to handle client-side routing: - -```yaml -type: web -name: react-app -runtime: static -buildCommand: npm ci && npm run build -staticPublishPath: ./build -routes: - - type: rewrite - source: /* - destination: /index.html -``` - -### Custom Headers - -Add cache control and security headers: - -```yaml -type: web -name: static-site -runtime: static -buildCommand: npm ci && npm run build -staticPublishPath: ./dist -headers: - # Cache static assets - - path: /static/* - name: Cache-Control - value: public, max-age=31536000, immutable - - # Security headers - - path: /* - name: X-Frame-Options - value: DENY - - path: /* - name: X-Content-Type-Options - value: nosniff -``` - -### Build Filters - -For monorepos, only build when frontend files change: - -```yaml -type: web -name: frontend -runtime: static -buildCommand: npm ci && npm run build -staticPublishPath: ./dist -buildFilter: - paths: - - frontend/** - ignoredPaths: - - frontend/**/*.test.js - - frontend/README.md -``` - -### Best Practices - -1. **Optimize build output**: Minify, compress, tree-shake - -2. **Use proper cache headers**: Long cache for hashed assets - -3. **Add security headers**: Protect against common attacks - -4. **Configure SPA routing**: Add rewrite rules for client routing - -5. **Handle 404s**: Create custom 404.html page - ---- - -## Private Services (`type: pserv`) - -### Purpose - -Services that receive traffic only from other Render services on the same private network. They aren't exposed to the public internet. - -### Use Cases - -- **Internal APIs**: Services accessed only by other services -- **Database proxies**: Connection pools, read replicas -- **Microservices**: Service mesh architectures -- **Admin tools**: Internal dashboards -- **Cache layers**: Internal caching services -- **Message brokers**: Internal message queues - -### Key Characteristics - -- **No public URL**: Only accessible via internal DNS -- **Internal networking**: Fast, low-latency connections -- **Port binding required**: Must bind to `0.0.0.0:$PORT` -- **Private hostname**: Each service has a unique internal hostname -- **Private-network scope**: The connecting service must be in the same workspace and region -- **No public ingress**: Can't be accessed from the public internet - -### Required Configuration - -```yaml -type: pserv -name: internal-api -runtime: node -buildCommand: npm ci -startCommand: npm start -``` - -### Internal Addresses - -Render gives each web service and private service a unique hostname on the private network. The hostname is stable and maps to instance IPs which can change between deploys. Free web services can't receive private traffic it. - -Services can communicate over the private network when they belong to the same workspace and region. Find the internal address in the service's **Connect** menu under **Internal**. Private services also show it as the **Service Address**. - -An internal address has the form `internal-hostname:port`. Add the protocol when the client requires one, for example `http://internal-hostname:port`. - -In a Blueprint, use `fromService` to inject the address into another service: - -```yaml -services: - - type: web - name: frontend - runtime: node - envVars: - - key: API_URL - fromService: - name: internal-api - type: pserv - property: hostport -``` - -For web services and private services, `host` provides the internal hostname and `hostport` provides the hostname and listening port as `host:port`. - -### Best Practices - -1. **Use internal addresses**: Use the hostname from the Dashboard or inject it with a Blueprint service reference. - -2. **Fast communication**: Low latency between services - -3. **Simplify architecture**: No need for external load balancers - ---- - -## Comparison Table - -| Feature | Web | Worker | Cron | Static | Private | -|---------|-----|--------|------|--------|---------| -| Public URL | ✅ Yes | ❌ No | ❌ No | ✅ Yes | ❌ No | -| Port Binding | ✅ Required | ❌ Not needed | ❌ Not needed | ❌ N/A | ✅ Required | -| Health Checks | ✅ Yes | ❌ No | ❌ No | ❌ N/A | ✅ Yes | -| Runtime | ✅ Yes | ✅ Yes | ✅ Yes | ❌ No | ✅ Yes | -| Persistent | ✅ Yes | ✅ Yes | ❌ No | ✅ Yes | ✅ Yes | -| Scaling | ✅ Yes | ✅ Yes | ❌ No | ✅ Yes | ✅ Yes | -| Use Case | HTTP servers | Background jobs | Scheduled tasks | Static files | Internal services | - -## Choosing the Right Service Type - -**Use Web Service when:** -- Your app handles HTTP requests -- Users need to access it via URL -- You need load balancing and scaling - -**Use Worker Service when:** -- Processing background jobs -- Consuming from message queues -- Running long-lived processes without HTTP - -**Use Cron Job when:** -- Running scheduled tasks -- Processing doesn't need to be always-on -- Tasks run periodically (hourly, daily, weekly) - -**Use Static Site when:** -- Serving pre-built HTML/CSS/JS -- No backend processing needed -- Want CDN caching and fast delivery - -**Use Private Service when:** -- Service only accessed by other services -- Want internal-only communication -- Building microservice architectures +Human-facing service names do not always map directly to configuration identifiers or structure. When creating or editing a Blueprint, fetch the current Blueprint specification and use its service-type schema instead of inferring fields or values from this overview. In particular, do not assume that every Dashboard service type has a same-named Blueprint `type` or that managed datastores are declared like compute services. + diff --git a/skills/render-disks/SKILL.md b/skills/render-disks/SKILL.md index 852ab0f..aa4d890 100644 --- a/skills/render-disks/SKILL.md +++ b/skills/render-disks/SKILL.md @@ -18,7 +18,9 @@ metadata: # Render Persistent Disks -Persistent disks are high-performance SSDs you attach to a Render service to preserve filesystem changes across deploys and restarts. Without a disk, services have an **ephemeral filesystem**—all local file changes are lost on every deploy. +Persistent disks preserve files written beneath a service's configured mount path across deploys and restarts. + +Before designing, configuring, resizing, transferring data to, snapshotting, restoring, or troubleshooting a disk, read `references/persistent-disks.md`. ## When to Use @@ -26,126 +28,45 @@ Persistent disks are high-performance SSDs you attach to a Render service to pre - Running a **self-managed database** (MySQL, MongoDB, ClickHouse) on Render - Deploying **stateful infrastructure** (Elasticsearch, Kafka, RabbitMQ, Mattermost) - Understanding **why scaling is blocked** or **zero-downtime deploys are disabled** -- **Restoring data** from an automatic disk snapshot +- **Restoring data** from a disk snapshot For managed databases, prefer **Render Postgres** (render-postgres) or **Key Value** (render-keyvalue) over self-managed alternatives on disk. -## Critical Constraints - -These constraints affect architecture decisions. Understand them **before** attaching a disk: - -| Constraint | Impact | -|------------|--------| -| **Single instance only** | Cannot scale horizontally (`numInstances` must be 1, autoscaling not available) | -| **No zero-downtime deploys** | Old instance stops before new instance starts (brief downtime on each deploy) | -| **Runtime access only** | Disk is not available during `buildCommand` or `preDeployCommand` (those run on separate compute) | -| **Not accessible from other services** | Only the attached service can read/write the disk | -| **Not available on cron jobs** | Attach to a web service, private service, or background worker instead | -| **Not available on one-off jobs** | One-off jobs run on separate compute without disk access | -| **Can increase size, cannot decrease** | Start small and grow as needed | - -## Setup +## Core Decisions -### Dashboard +- Render's default filesystem is ephemeral. Only files written beneath a disk's mount path persist across deploys and restarts. +- A disk-backed service is single-instance: it cannot use horizontal scaling or zero-downtime deploys. +- If file storage must be shared by scaled instances, use external object storage such as S3 or R2. Use Render Postgres for relational data and Render Key Value for managed cache or queue state. +- Choose the smallest current disk size that accommodates observed usage because capacity can increase but cannot decrease. For a small upload service, 1–5 GB is a reasonable starting range when supported by the current limits. -1. Go to your service's **Disks** page -2. Set the **mount path** (absolute path where persistent data is stored) -3. Choose a **size** in GB -4. Click **Add disk** — triggers a new deploy +## Blueprint Setup -### Blueprint +For a native Node.js upload service, mount a subdirectory such as `/opt/render/project/src/uploads`, not the source root itself, and configure the application to write uploads there: ```yaml services: - type: web - name: cms + name: uploads runtime: node - plan: starter - region: oregon - buildCommand: npm ci && npm run build + buildCommand: npm ci startCommand: npm start disk: - name: cms-data - mountPath: /var/data - sizeGB: 10 + name: uploads-data + mountPath: /opt/render/project/src/uploads + sizeGB: 5 ``` -## Mount Path - -Only files written **under the mount path** are preserved. Everything else remains ephemeral. - -| Runtime | Source code path | Example mount path | -|---------|------------------|--------------------| -| Node.js, Python, Ruby, Elixir, Rust | `/opt/render/project/src` | `/opt/render/project/src/uploads` | -| Go | `/opt/render/project/go/src/github.com//` | `.../data` | -| Docker | Dockerfile's `WORKDIR` (commonly `/app`) | `/app/storage` | - -### Disallowed mount paths - -Cannot mount at: `/`, `/opt`, `/opt/render`, `/opt/render/project`, `/opt/render/project/src`, `/home`, `/home/render`, `/etc`, `/etc/secrets`. +Fetch the current disk documentation and Blueprint specification through `references/persistent-disks.md` before finalizing the mount path or size. -Subdirectories of these paths are fine (e.g. `/opt/render/project/src/uploads`). +## Database Backups and File Recovery -## Snapshots - -- Render creates an **automatic snapshot every 24 hours** -- Snapshots are available for **at least 7 days** -- Restore from the service's **Disks** page in the Dashboard -- **Full restore only** — you cannot restore individual files -- **Destructive** — all changes after the snapshot are lost - -**Do not restore snapshots for custom database recovery.** Use database-native backup tools (mysqldump, mongodump) instead—disk snapshots may capture a corrupted database state. - -## File Transfers - -### SCP (via SSH) - -```bash -# Download from service -scp -s YOUR_SERVICE@ssh.YOUR_REGION.render.com:/mount/path/file ./local-file - -# Upload to service -scp -s ./local-file YOUR_SERVICE@ssh.YOUR_REGION.render.com:/mount/path/file -``` - -Requires SSH access enabled for the service. - -### Magic-Wormhole - -Available on all native runtimes (install manually on Docker): - -```bash -# On the service shell -wormhole send /mount/path/file - -# On your local machine -wormhole receive -``` - -## Common Patterns - -| Pattern | Service type | Mount path | Notes | -|---------|-------------|------------|-------| -| WordPress / Ghost / CMS | Web Service | `/var/data` or `/app/content` | Media uploads, SQLite | -| Self-managed MySQL | Private Service | `/var/lib/mysql` | Use mysqldump for backups, not disk snapshots | -| File upload API | Web Service | `/opt/render/project/src/uploads` | Single instance constraint | -| Elasticsearch | Private Service | `/usr/share/elasticsearch/data` | Stateful search infrastructure | - -## Common Mistakes - -| Mistake | Fix | -|---------|-----| -| Expecting horizontal scaling with a disk | Not possible — disk services are single-instance only | -| Mounting at a disallowed path | Use a subdirectory (e.g. `/opt/render/project/src/uploads` not `/opt/render/project/src`) | -| Reading disk during build or pre-deploy | These run on separate compute — move logic to the start command | -| Restoring disk snapshot for a database | Use database-native backups instead | -| Starting with a large disk size | Start small — you can increase but never decrease | +Do not use a disk snapshot to recover a self-managed database such as MySQL: a filesystem snapshot can restore an inconsistent or corrupted database state. Use database-native backups such as `mysqldump` and test their restore procedure. Move backup files off the service with a currently supported transfer method such as SCP with SSH or Magic-Wormhole. Snapshot restores replace the entire disk and permanently discard changes made after the selected snapshot. ## References | Document | Contents | |----------|----------| -| `references/sizing-and-snapshots.md` | Sizing guidance, snapshot lifecycle, restore procedures, cost patterns | +| `references/persistent-disks.md` | Current disk constraints, configuration, sizing, snapshots, restores, and transfers | ## Related Skills @@ -153,3 +74,16 @@ wormhole receive - **render-private-services** — Internal services with disks (Elasticsearch, MySQL) - **render-blueprints** — `disk` field reference in `render.yaml` - **render-postgres** — Managed database alternative (no disk management needed) + + +## Current documentation retrieval + +Whenever this skill directs you to consult current Render documentation: + +1. Retrieve the linked Markdown document directly with an available URL-fetching tool or HTTP client, such as `curl`. Do not substitute web-search summaries for the document. +2. Confirm that retrieval succeeded and returned the expected document, then read its contents. Saving a file or printing its path is not sufficient. +3. If the request fails or your tool cannot read the Markdown response, open and read the linked HTML version instead. +4. If neither version can be retrieved, disclose that the current reference is unavailable and follow any topic-specific fallback in the skill. Use bundled guidance only for stable constraints, and do not guess at changeable platform details. + +When a task requires multiple references, apply this workflow to each one and distinguish the documents you verified from those that remain unavailable. + diff --git a/skills/render-disks/references/persistent-disks.md b/skills/render-disks/references/persistent-disks.md new file mode 100644 index 0000000..bfba5ae --- /dev/null +++ b/skills/render-disks/references/persistent-disks.md @@ -0,0 +1,44 @@ + +## Persistent disks + +Use this guidance only for service-attached persistent disks and for architecture or configuration decisions directly affected by them. Do not apply it to Render Postgres or Key Value storage, object storage, build caches, or ordinary ephemeral filesystem tasks. + +By default, a Render service's filesystem is ephemeral. Files created or changed at runtime are lost when the service is redeployed or restarted. Use a persistent disk only when a supported service must retain local filesystem data across those events. + +Before designing, configuring, or troubleshooting a persistent disk, fetch the current documentation: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/disks.md) or its [HTML version](https://render.com/docs/disks). + +Read the relevant sections before relying on details that can change, including supported service types, size limits and pricing, mount-path restrictions, snapshot cadence and retention, transfer methods, and current scaling or deployment limitations. If the document cannot be fetched, do not guess those details from memory. + +A persistent disk belongs to one service and is mounted at one absolute path. Only files written under that mount path persist; the rest of the service filesystem remains ephemeral. Make sure the application writes every intended durable file beneath the configured mount path. A disk is not shared storage, and another service cannot access it. + +Under the documented generally available behavior, a disk-backed service runs as a single instance and cannot use autoscaling or zero-downtime deploys. During a deploy, Render stops the existing instance before starting its replacement, so expect a short interruption. If the workload needs horizontal scaling, shared state, or stronger availability, use an external or managed datastore instead of a service-attached disk. + +The disk is available only to the running service. Builds, pre-deploy commands, and one-off jobs run on separate compute and cannot access it. Do not design a build step, pre-deploy command, or one-off job that depends on files stored on the mounted disk. + +The documented supported service types are paid web services, private services, and background workers. For other workload types, use an appropriate external datastore or reconsider the service architecture rather than assuming a disk can be attached. + +Disk capacity can be increased but not decreased. Confirm current limits and pricing in the fetched documentation, and choose capacity using observed usage plus reasonable headroom. + +Treat attaching, resizing, or restoring a disk as a stateful mutation. After attaching, verify that the service deploys successfully and that reads and writes use the mounted path. + +Snapshots are a disaster-recovery mechanism, not a substitute for application-consistent database backups. A snapshot restore replaces the entire disk; it cannot restore individual files, and it discards changes made after that snapshot. Do not use a disk snapshot to recover a custom database, because a filesystem-level snapshot can restore the database into an inconsistent or corrupted state. Use the database engine's native backup and restore tools instead. Check the current documentation before promising a particular snapshot schedule, retention period, or restore procedure. + +Mount paths must be absolute and must satisfy Render's current restrictions. Fetch the documentation instead of reproducing its forbidden-path list or runtime-specific path suggestions from memory. When declaring a disk in a Blueprint, also fetch the current Blueprint specification and follow its disk schema rather than relying on remembered syntax. + + +## Storage-specific guidance + +- Persistent disk data is encrypted at rest. +- Expect the service to restart when restoring a snapshot, in addition to the destructive replacement of disk contents described above. +- Disk billing is based on provisioned capacity rather than used capacity. Confirm the current rate and billing behavior in the fetched documentation before estimating cost. + +Prefer a managed or external store when the workload does not require single-service local filesystem persistence: + +| Need | Prefer | +|------|--------| +| Managed relational database | Render Postgres | +| Managed cache or queue | Render Key Value | +| Large or shared file storage | External object storage | +| Temporary build artifacts | The default ephemeral build filesystem | diff --git a/skills/render-disks/references/sizing-and-snapshots.md b/skills/render-disks/references/sizing-and-snapshots.md deleted file mode 100644 index 40f29c6..0000000 --- a/skills/render-disks/references/sizing-and-snapshots.md +++ /dev/null @@ -1,57 +0,0 @@ -# Disk Sizing and Snapshots - -## Sizing Guidance - -| Use case | Suggested starting size | Notes | -|----------|------------------------|-------| -| File uploads (small app) | 1-5 GB | Grow as needed | -| CMS media (WordPress, Ghost) | 5-10 GB | Depends on media volume | -| Self-managed database (MySQL, MongoDB) | 10-50 GB | Match expected data volume | -| Infrastructure (Elasticsearch, Kafka) | 20-100 GB | Plan for index/log growth | - -**Key rule:** Start small. You can increase disk size at any time without downtime. You **cannot** decrease disk size. - -Increasing disk size: -1. Dashboard > service > Disks > edit size -2. Additional storage becomes available within seconds -3. No deploy or restart needed - -## Snapshot Lifecycle - -| Property | Value | -|----------|-------| -| Frequency | Every 24 hours (automatic) | -| Retention | At least 7 days | -| Scope | Full disk contents | -| Encryption | Encrypted at rest | -| Restore type | Full restore only (no partial/file-level restore) | - -## Restore Procedure - -1. Go to Dashboard > service > Disks -2. Select the snapshot to restore -3. Confirm the restore - -**Warnings:** -- All changes after the snapshot are **permanently lost** -- The service restarts during restore -- Restore is **not suitable for database recovery** — use database-native tools - -## Cost Patterns - -Persistent disks are billed based on provisioned size, not used size. Billing starts when the disk is created and continues until it's removed. - -Minimize cost by: -- Starting with the smallest viable size -- Not provisioning "just in case" capacity -- Using managed services (Postgres, Key Value) instead of self-managed databases on disk where possible - -## When NOT to Use a Disk - -| Scenario | Better alternative | -|----------|--------------------| -| Relational database | **Render Postgres** (managed backups, PITR, replicas) | -| Cache or queue | **Render Key Value** (managed, no disk management) | -| Large file storage (S3-like) | **External object storage** (AWS S3, Cloudflare R2) | -| Temporary build artifacts | Ephemeral filesystem (default, no disk needed) | -| Shared storage across services | External storage service (disks are single-service only) | diff --git a/skills/render-docker/SKILL.md b/skills/render-docker/SKILL.md index 94ed9ea..1b549c4 100644 --- a/skills/render-docker/SKILL.md +++ b/skills/render-docker/SKILL.md @@ -31,11 +31,13 @@ Render uses **BuildKit** for Docker builds. All compute service types that suppo For full Blueprint authoring, see **render-blueprints**. For end-to-end deploy flows, see **render-deploy**. +Before deploying a built or prebuilt image, read `references/deployments.md` for current trigger, lifecycle, health-check, and signal behavior. + ## Render Docker Builds - **BuildKit** is used for Docker builds on Render. - **`runtime: docker`**: Render builds an image from your repo using `dockerfilePath`, `dockerContext`, and optional `dockerCommand` (overrides image `CMD`). -- **`runtime: image`**: Render pulls **`image.url`**; no repo-based image build. Pair with **`registryCredential`** when the registry is private. +- **`runtime: image`**: Render pulls **`image.url`**; no repo-based image build. Set **`image.creds.fromRegistryCreds.name`** when the registry is private. ## Blueprint Configuration @@ -45,7 +47,8 @@ For full Blueprint authoring, see **render-blueprints**. For end-to-end deploy f | `dockerContext` | Build context directory (what is sent to the daemon) | | `dockerCommand` | Overrides the container `CMD` after the image is built | | `image.url` | Image reference for `runtime: image` (registry/repo:tag or digest) | -| `registryCredential` | Auth for private pulls; often `fromRegistryCreds` → Dashboard-stored credential | +| `image.creds` | Dashboard-stored credential reference for a private prebuilt image | +| `registryCredential` | Dashboard-stored credential reference for private base images used by `runtime: docker` | Example sketch (values illustrative): @@ -64,7 +67,7 @@ services: value: 10000 ``` -For `runtime: image`, set `image.url` and, if needed, `registryCredential` per **Registry Configuration** below. +For `runtime: image`, set `image.url` and, if needed, `image.creds` per **Registry Configuration** below. ## Multi-Stage Builds @@ -90,11 +93,12 @@ Treat anything sensitive as **runtime** or **BuildKit secret mount**, not as a b Private **base images** (for `runtime: docker`) or **prebuilt images** (`runtime: image`) need authentication: - Store credentials in the Render Dashboard under **Registry Credentials**. -- In Blueprint, reference them with **`registryCredential.fromRegistryCreds.name`** (match the Dashboard name). +- For `runtime: docker`, reference private base-image credentials with **`registryCredential.fromRegistryCreds.name`**. +- For `runtime: image`, reference private prebuilt-image credentials with **`image.creds.fromRegistryCreds.name`**. Supports common registries (Docker Hub, GHCR, ECR, Google Artifact Registry, and others). Step-by-step per provider: `references/registry-setup.md`. -**Prebuilt image services** do **not** auto-deploy when the tag moves in the registry; trigger a **manual redeploy** or use a **deploy hook** when you publish a new image. +Prebuilt-image services do not automatically deploy when a mutable registry tag moves. After publishing a new image, trigger a manual deploy through the Dashboard or a supported API or deploy-hook flow. Prefer immutable tags or digests so each deploy identifies an explicit artifact; follow `references/deployments.md` for the complete trigger and verification workflow. ## Layer Caching @@ -105,7 +109,7 @@ Supports common registries (Docker Hub, GHCR, ECR, Google Artifact Registry, and - Render builds **linux/amd64**. Avoid assumptions about other architectures in production images. - **Port binding** matches native services: bind HTTP to **`0.0.0.0:$PORT`** (Render sets `PORT`). -- **Health checks** behave like non-Docker web services (`healthCheckPath`, etc.). +- **Health checks** use the same platform behavior described in `references/deployments.md`. - **Secret files** from Render appear under **`/etc/secrets/`** — do not rely on repo-root secret paths inside the container unless you copy or mount them explicitly in the image. ## `.dockerignore` and Start Commands @@ -120,9 +124,23 @@ Supports common registries (Docker Hub, GHCR, ECR, Google Artifact Registry, and | `references/dockerfile-patterns.md` | Multi-stage templates (Node, Python, Go, Ruby, Rust, static sites) | | `references/registry-setup.md` | Docker Hub, GHCR, ECR, Artifact Registry + Blueprint wiring | | `references/optimization-guide.md` | Layer order, `.dockerignore`, BuildKit cache mounts, debugging | +| `references/deployments.md` | Deploy triggers, lifecycle, health checks, shutdown, and verification | ## Related Skills - **render-deploy** — Deploy flows, Blueprint vs Dashboard, operational steps - **render-blueprints** — Full `render.yaml` schema, wiring, and validation - **render-web-services** — Web service behavior, health checks, and HTTP edge cases + + +## Current documentation retrieval + +Whenever this skill directs you to consult current Render documentation: + +1. Retrieve the linked Markdown document directly with an available URL-fetching tool or HTTP client, such as `curl`. Do not substitute web-search summaries for the document. +2. Confirm that retrieval succeeded and returned the expected document, then read its contents. Saving a file or printing its path is not sufficient. +3. If the request fails or your tool cannot read the Markdown response, open and read the linked HTML version instead. +4. If neither version can be retrieved, disclose that the current reference is unavailable and follow any topic-specific fallback in the skill. Use bundled guidance only for stable constraints, and do not guess at changeable platform details. + +When a task requires multiple references, apply this workflow to each one and distinguish the documents you verified from those that remain unavailable. + diff --git a/skills/render-docker/references/deployments.md b/skills/render-docker/references/deployments.md new file mode 100644 index 0000000..5ca9905 --- /dev/null +++ b/skills/render-docker/references/deployments.md @@ -0,0 +1,50 @@ + +## Deployments and health checks + +A Render deploy is asynchronous. A successful trigger means only that Render accepted or queued the deploy; it does not mean the new version is live. Before triggering a deploy, confirm the workspace, service, intended source commit or image, and current live deploy. Capture the new deploy ID, monitor it to a terminal state, and do not report success until its status is `live` and the deployed workload has been verified. + +Before configuring or troubleshooting deployments and health checks, fetch the current Render references: + +- [deploys.md](https://render.com/docs/deploys.md) (HTML: ) +- [health-checks.md](https://render.com/docs/health-checks.md) (HTML: ) + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read both references. + +Read the relevant sections of both documents. Confirm current service-type support, command timeouts, health-check thresholds, rollout behavior, and configuration syntax rather than relying on remembered values. + +Automatic deployment behavior depends on the service's source and settings. A service linked to a branch through a connected Git provider can deploy on each commit, wait for supported CI checks, or require manual triggers. Services that pull a prebuilt image and services linked by a public Git repository URL require manual deploys; moving a mutable image tag does not itself trigger one. When manually deploying a historical commit, verify whether that trigger method changes automatic-deploy settings. If automatic deploys remain enabled, a later branch update can replace the selected commit. + +The normal lifecycle is build command, optional pre-deploy command, then start command and readiness checks. If a command fails or times out, the deploy fails and later steps do not run. A pre-deploy command runs after the build on a separate instance before the new version is deployed. Neither the build nor pre-deploy instance can access an attached persistent disk, and pre-deploy filesystem changes do not carry into the running service. Use pre-deploy for release tasks such as database migrations, not for producing runtime artifacts. Pre-deploy commands are supported for paid web services, private services, and background workers. + +Render normally deploys services without downtime by starting the new version before retiring the current one. Web and private services continue routing traffic to the current instances until the new instances are ready. Multi-instance services roll out one instance at a time; if a replacement does not become healthy, Render cancels the rollout and retains or restores the previous version. Attaching a persistent disk disables zero-downtime deploys, so plan explicitly for an interruption. + +A workflow deployment has a different completion model. It builds and caches the image used by future task runs and includes a task-registration step, but it does not execute those tasks. After a workflow deploy succeeds, verify that the expected task definitions are registered. Trigger and monitor a task run separately only when execution is intended. For workflow-specific deployment behavior, fetch the current workflow overview: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/workflows.md) or its [HTML version](https://render.com/docs/workflows). + +Health checks apply to web services and private services. Both use TCP socket checks by default. Only web services support a configured HTTP health-check path. Render sends an HTTP `GET`; any `2xx` or `3xx` response received within five seconds succeeds, while other status codes, timeouts, and connection failures fail. Private services support TCP checks only. + +For a new deploy, all new instances must pass their checks at the same time within the current readiness window, documented as 15 minutes, before Render routes traffic to them. For a running service, consecutive failures currently remove an instance from routing after 15 seconds and restart it after 60 seconds. Treat these thresholds as platform behavior, not user-tunable health-check interval settings, and verify them in the fetched reference before relying on exact timing. + +Design an HTTP health endpoint to represent readiness for production traffic. Keep it fast and side-effect free. Check critical dependencies only when losing that dependency should make the entire instance unavailable; otherwise a transient dependency failure can unnecessarily remove healthy application capacity. Verify the configured path, response status, response time, listening port, and `0.0.0.0` binding when checks fail. + +After traffic moves, Render gives the previous instance a drain period, then sends `SIGTERM`. The application should stop accepting new work, finish or safely abandon in-flight work, close connections, and exit within its shutdown delay. Ensure the actual application process receives the signal: container entrypoints and shell wrappers should use `exec` or explicitly forward signals. Render sends `SIGKILL` if the process remains running after the delay. The documented default shutdown delay is 30 seconds and the usual maximum is 300 seconds, but support varies by service configuration; confirm the current reference and Blueprint or API validation before setting `maxShutdownDelaySeconds`. + +A service restart is a special deploy of the same commit and user-defined environment-variable values as the current running instance. It does not incorporate configuration changes saved after that deploy. Use a standard deploy when pending configuration must take effect. + +Only one deploy runs at a time for a service. A workspace's overlapping-deploy policy determines whether a new trigger waits or cancels the in-progress deploy. Do not assume the policy or wait for every intermediate revision: inspect the workspace setting and identify the deploy that actually became live. + +Treat rollback as a new deploy based on a retained previous build artifact, not as restoration of the entire service to an earlier point in time. It does not reverse database migrations, messages, external writes, or other side effects from the release, so confirm that the previous application version remains compatible with current external state. Disks and their data are not rolled back, some settings continue using current configuration, mutable image tags can resolve to a different image, and eligible artifacts are retained only for a limited period. Before rolling back, fetch the current rollback reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/rollbacks.md) or its [HTML version](https://render.com/docs/rollbacks). + +Read which configuration comes from the target deploy and which remains current. After the rollback is created, inspect the service's resulting automatic-deploy setting instead of assuming whether it remains enabled, and deliberately restore the intended setting after the underlying issue is resolved. + +Deploy hooks are secret credentials that authorize deploys. Never print, commit, or expose their full URLs. Before using one, fetch the current deploy-hook reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/deploy-hooks.md) or its [HTML version](https://render.com/docs/deploy-hooks). + +Distinguish an immediately started deploy from a queued one, and continue monitoring the resulting deploy rather than treating the HTTP response as completion. + +After a deploy becomes live, verify the behavior appropriate to the service type: make a request to a web or private service, confirm a worker is processing work, confirm a cron job or workflow invocation completes, and inspect recent runtime logs for new errors. If a deploy fails, diagnose the first failed lifecycle stage before retrying. + diff --git a/skills/render-docker/references/registry-setup.md b/skills/render-docker/references/registry-setup.md index 01b1af7..894185e 100644 --- a/skills/render-docker/references/registry-setup.md +++ b/skills/render-docker/references/registry-setup.md @@ -1,6 +1,6 @@ # Private registry setup for Render -Render pulls private images when you attach **Registry Credentials** from the Dashboard and reference them in Blueprint YAML via **`registryCredential.fromRegistryCreds`**. +Render pulls private images when you attach **Registry Credentials** from the Dashboard. In Blueprint YAML, prebuilt images use **`image.creds.fromRegistryCreds`**, while Dockerfile builds with private base images use **`registryCredential.fromRegistryCreds`**. ## Dashboard: Registry Credentials @@ -17,12 +17,18 @@ services: runtime: image image: url: docker.io/myorg/api:v1.2.3 - registryCredential: - fromRegistryCreds: - name: my-dockerhub-cred + creds: + fromRegistryCreds: + name: my-dockerhub-cred ``` -Use the same `registryCredential` block for **`runtime: docker`** when the **base image** in your Dockerfile is private. +For **`runtime: docker`** with a private base image, put the credential at the service level instead: + +```yaml +registryCredential: + fromRegistryCreds: + name: my-dockerhub-cred +``` --- @@ -61,7 +67,7 @@ Use the same `registryCredential` block for **`runtime: docker`** when the **bas ## Blueprint: `runtime: image` - Set **`runtime: image`** and **`image.url`** to the full reference (tag or digest). -- Add **`registryCredential`** when the registry is private. +- Add **`image.creds.fromRegistryCreds.name`** when the registry is private. Immutable deploys: @@ -74,9 +80,4 @@ image: ## Auto-deploy and prebuilt images -Services that **only pull** a prebuilt image (**`runtime: image`**) **do not** auto-deploy when a mutable tag like **`latest`** is updated upstream. After publishing a new image you must: - -- Trigger a **manual redeploy** in the Dashboard, or -- Call a **deploy hook** / API flow your team uses for CD. - -Combine **immutable tags or digests** with your release pipeline so each deploy points at an explicit artifact. +Follow [deployments.md](deployments.md) for current trigger and mutable-tag behavior. Combine **immutable tags or digests** with your release pipeline so each deploy points at an explicit artifact. diff --git a/skills/render-domains/SKILL.md b/skills/render-domains/SKILL.md index 3e40810..5dcd756 100644 --- a/skills/render-domains/SKILL.md +++ b/skills/render-domains/SKILL.md @@ -29,12 +29,9 @@ Render automatically provisions and renews TLS certificates (via Let's Encrypt a - Choosing between **apex** (`example.com`) and **www** (`www.example.com`) - **Disabling the `onrender.com` subdomain** after adding a custom domain -## Domain Limits +## Domain Limits and Cost -| Workspace tier | Custom domain limit | -|---------------|---------------------| -| Hobby | 2 custom domains (across all services) | -| Professional+ | Unlimited | +Workspace plans include a limited number of custom domains. Adding domains beyond the included allowance incurs an additional cost. Confirm current allowances and charges at [Render pricing](https://render.com/pricing) or in the Dashboard. ## Setup Steps diff --git a/skills/render-env-vars/SKILL.md b/skills/render-env-vars/SKILL.md index 6276f45..1f18314 100644 --- a/skills/render-env-vars/SKILL.md +++ b/skills/render-env-vars/SKILL.md @@ -15,15 +15,9 @@ metadata: # Environment Variables on Render -Render exposes configuration to services as **environment variables**. Values are always **strings** at the platform layer—applications must parse numbers, booleans, and structured data explicitly. +Before inspecting or changing environment variables, secrets, secret files, or environment groups, read `references/environment-variables.md` for the current documentation, source-of-truth, safety, and mutation workflow. -There are **three** primary ways to set variables: - -1. **Render Dashboard** — per-service UI, bulk import from `.env`, save/redeploy options -2. **Blueprint** — `envVars` (and related keys) in `render.yaml` -3. **MCP / API** — e.g. `update_environment_variables` on a service - -Deep wiring patterns, full platform variable tables, and language-specific notes live under `references/`. +Blueprint wiring examples and language-specific application notes live under `references/`. ## When to Use This Skill @@ -37,111 +31,47 @@ Use this skill when users want to: For full Blueprint authoring, pair with **render-blueprints**. For first-time deploys, **render-deploy**. For web service behavior and ports, **render-web-services**. -## Setting Variables - -### Dashboard - -- Add variables **individually** (name + value) or **in bulk** by pasting/uploading a `.env`-style file. -- **Save options** typically include: - - **Save and rebuild & deploy** — picks up build-time changes - - **Deploy only** — runtime change without a full rebuild (when applicable) - - **Save only** — persist without triggering a deploy - -Use Dashboard edits when iterating quickly or when the repo should not carry certain values. - -### Blueprint (`render.yaml`) - -Declare `envVars` on each service. Values can be literals, generated secrets, sync-disabled prompts, or references to databases, other services, or env groups. See **Blueprint Wiring** below and `references/wiring-reference.md` for exhaustive patterns and YAML. - -### MCP / API - -Automation tools can set variables on existing services (e.g. `update_environment_variables`). Useful for CI, rotation, or keeping Dashboard state in sync with external secret stores—without committing secrets to Git. - -## Secret Management - -- **`sync: false`** — Render prompts in the Dashboard for the value **only on initial Blueprint setup** when the resource is first created. On **Blueprint updates**, `sync: false` is **ignored** (values are not re-prompted from the file alone). These vars are **excluded from preview environments** and are **invalid inside environment groups**. -- **`generateValue: true`** — Render generates a **base64-encoded 256-bit** random value at provision time. Use for passwords, signing keys, or tokens that do not need human-chosen values. -- **Never commit real secrets** in `render.yaml` as plain `value:` entries. Prefer Dashboard, secret manager integration, `generateValue`, or `sync: false` with Dashboard entry. - -### Secret files - -- Store sensitive file content as **secret files** (not inline env strings). They appear as **plaintext files** under **`/etc/secrets/`**. -- **Combined limit**: **1 MB** total secret file payload per service or per linked env group (as applicable to your setup). -- **Docker**: secret files are available under **`/etc/secrets/`** on the running instance. - -## Environment Groups - -**Environment groups** are named collections of variables linked to **multiple services**. - -- **Precedence**: **Service-level** variables **override** variables from linked groups with the same name. -- **Multiple groups** on one service: the group that was **most recently created** wins for overlapping keys. This ordering is **not documented as stable**—avoid relying on it; use distinct names or consolidate groups. -- Groups can be **scoped to a project environment** so staging and production differ without duplicating every service definition. - ## Blueprint Wiring (Summary) -Full syntax, examples, and edge cases: `references/wiring-reference.md`. Authoritative Blueprint docs: **render-blueprints** skill. - -| Mechanism | Role | -|-----------|------| -| `value` | Hardcoded string (non-secret config only) | -| `generateValue: true` | Platform-generated secret | -| `sync: false` | Dashboard prompt on **initial** create only | -| `fromDatabase` | Inject DB fields (`connectionString`, `host`, `port`, `user`, `password`, `database`) | -| `fromService` | Key Value: `type: keyvalue` + properties; private/web: `host`, `hostport`, or `envVarKey` | -| `fromGroup` | Link all vars from a named group | +After reading `references/environment-variables.md`, use `references/wiring-reference.md` for task-specific `fromDatabase`, `fromService`, and `fromGroup` examples. Consult **render-blueprints** for the complete Blueprint workflow. ## Platform-Injected Variables -Render sets **read-only** variables your app can read at runtime (and some at build). A concise list: - -| Variable | Typical meaning | -|----------|-----------------| -| `RENDER` | `"true"` when running on Render | -| `RENDER_SERVICE_TYPE` | Service kind (e.g. web, worker) | -| `RENDER_SERVICE_ID` | Service identifier | -| `RENDER_SERVICE_NAME` | Human-readable service name | -| `RENDER_INSTANCE_ID` | Current instance | -| `RENDER_EXTERNAL_URL` | Public URL (when applicable) | -| `RENDER_EXTERNAL_HOSTNAME` | Public hostname | -| `RENDER_DISCOVERY_SERVICE` | Service discovery hostname (private network) | -| `RENDER_GIT_COMMIT` | Deployed commit SHA | -| `RENDER_GIT_BRANCH` | Branch for this deploy | -| `PORT` | HTTP port to bind (**default `10000`**) | -| `IS_PULL_REQUEST` | Preview deploy indicator | -| `RENDER_CPU_COUNT` | vCPU count for the instance | -| `RENDER_WEB_CONCURRENCY` | Suggested worker/process count hint | - -Build vs runtime availability, language version env vars, and **WEB_CONCURRENCY** defaults: `references/platform-variables.md`. +Use the current default-variable reference fetched through `references/environment-variables.md` instead of relying on a fixed catalog. Language-specific application notes remain in `references/platform-variables.md`. ## Runtime-Specific Defaults -Render and buildpacks may set defaults (verify in your service’s **Environment** tab): - -| Runtime | Notable defaults | -|---------|------------------| -| **Node.js** | `NODE_ENV=production` | -| **Python** | `PYTHON_VERSION` (pinned by build); Gunicorn-oriented images often set `GUNICORN_CMD_ARGS` to bind **`0.0.0.0:10000`** | -| **Ruby** | `RAILS_ENV=production`, `RAILS_LOG_TO_STDOUT=true` | -| **Go** | `GO111MODULE=on` (legacy modules flag; still seen on older stacks) | -| **Rust** | `ROCKET_PORT=10000` (Rocket convention) | - Always bind HTTP servers to **`0.0.0.0`** and **`PORT`** (or the stack’s documented port env) unless using a static site or custom Docker entrypoint. +- When diagnosing a port-binding failure, first establish whether the service uses a native runtime or Docker and inspect its actual start command; the applicable defaults differ. +- For a web service, `PORT` defaults to **`10000`**. Prefer reading `$PORT` in the start command rather than hardcoding that number or setting `PORT` merely to match an arbitrary hardcoded port. +- Native Python services currently receive `GUNICORN_CMD_ARGS` with a default bind to **`0.0.0.0:10000`**. A custom Gunicorn start command should bind to **`0.0.0.0:$PORT`** so the process and Render's health checks use the same port. + ## Common Issues -1. **Everything is a string** — `DEBUG=false` is truthy in many parsers; use explicit comparison or typed config loaders. -2. **`WEB_CONCURRENCY`** — Default behavior changed for services **created after December 8, 2025**. Compare with older services when debugging worker counts; see `references/platform-variables.md`. -3. **Undocumented `RENDER_*` variables** — Names and semantics may change; do not depend on undocumented injection for critical logic. -4. **Blueprint vs Dashboard drift** — Editing only `render.yaml` does not retroactively apply `sync: false` prompts on update; merge strategy for env keys is easy to misunderstand—test in a scratch service. -5. **Secret file paths** — Code must read **`/etc/secrets/`**; wrong paths or missing mounts usually show as file-not-found at runtime. +`WEB_CONCURRENCY` defaults differ for some older and newer services. When debugging worker counts, compare service creation date and explicit overrides, then confirm current behavior using `references/environment-variables.md` and `references/platform-variables.md`. ## References -- `references/wiring-reference.md` — Complete Blueprint `envVar` wiring, YAML examples, precedence, edge cases -- `references/platform-variables.md` — Injected variables (build vs runtime), language versions, concurrency, reading vars from code +- `references/environment-variables.md` — Current configuration docs, secret handling, groups, platform variables, and mutation safety +- `references/wiring-reference.md` — Blueprint cross-resource wiring examples and workspace edge cases +- `references/platform-variables.md` — Concurrency, native-runtime versus Docker behavior, and application parsing notes ## Related Skills - **render-blueprints** — Full Blueprint authoring, validation, multi-service layouts - **render-deploy** — First deploy, repo requirements, MCP vs YAML - **render-web-services** — Ports, health checks, scaling behavior tied to env-driven servers + + +## Current documentation retrieval + +Whenever this skill directs you to consult current Render documentation: + +1. Retrieve the linked Markdown document directly with an available URL-fetching tool or HTTP client, such as `curl`. Do not substitute web-search summaries for the document. +2. Confirm that retrieval succeeded and returned the expected document, then read its contents. Saving a file or printing its path is not sufficient. +3. If the request fails or your tool cannot read the Markdown response, open and read the linked HTML version instead. +4. If neither version can be retrieved, disclose that the current reference is unavailable and follow any topic-specific fallback in the skill. Use bundled guidance only for stable constraints, and do not guess at changeable platform details. + +When a task requires multiple references, apply this workflow to each one and distinguish the documents you verified from those that remain unavailable. + diff --git a/skills/render-env-vars/references/environment-variables.md b/skills/render-env-vars/references/environment-variables.md new file mode 100644 index 0000000..e9de03c --- /dev/null +++ b/skills/render-env-vars/references/environment-variables.md @@ -0,0 +1,38 @@ + +## Environment variables and secrets + +Render environment-variable values are strings. Applications must explicitly parse values that represent booleans, numbers, lists, or structured data; for example, the string `"false"` is truthy in many languages. + +Environment variables can be managed through the Render Dashboard, Blueprints, environment groups, and supported API, MCP, or CLI operations. Before changing a service, determine which mechanism is intended to be the source of truth. Do not make parallel Dashboard and infrastructure-as-code edits without explaining how future syncs or deploys will reconcile them. + +Never commit secret values to application source, `render.yaml`, checked-in `.env` files, fixtures, examples, or logs. Keep local secret-bearing `.env` files out of version control. Do not print or repeat secret values returned by the user, Render, or another provider. Use Render's supported secret mechanisms or an external secret manager appropriate to the user's workflow. + +Before configuring environment variables, secret files, or environment groups, fetch the current Render configuration reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/configure-environment-variables.md) or its [HTML version](https://render.com/docs/configure-environment-variables). + +Read the sections relevant to the configuration surface being used. Dashboard save options can rebuild and deploy, deploy the existing build, or save without deploying; do not assume a changed value is active until the applicable deploy occurs. + +For Blueprint-managed variables, also consult the current Blueprint YAML reference before writing syntax or predicting update behavior. In particular: + +- Use literal `value` entries only for non-sensitive configuration. +- `generateValue: true` creates a platform-generated secret when the variable does not already exist. +- `sync: false` prompts for a value only during initial Blueprint creation. It is ignored for existing services during later Blueprint updates, is not included in preview environments, and is not valid in environment groups. +- Use current `fromDatabase`, `fromService`, and `fromGroup` syntax instead of hardcoding connection strings or copying shared values. + +Blueprint syncs preserve existing service environment variables that are omitted from the Blueprint; omission does not delete them. Values defined with `fromDatabase` or `fromService` refresh on each Blueprint sync, not immediately when the referenced property or variable changes. + +Environment groups provide shared variables and secret files to linked services. A variable defined directly on a service takes precedence over the same key from a linked group. Precedence between multiple linked groups with the same key is not guaranteed; avoid collisions instead of depending on group creation order. Respect project-environment scoping when linking groups to services. + +Use secret files for credentials or configuration that must be read from the filesystem rather than an environment variable. Confirm current size and runtime-path rules in the fetched reference. Treat secret-file contents with the same precautions as other credentials. + +Render also injects documented default environment variables. Do not maintain a memorized catalog. Fetch the current default-variable reference when a task depends on a variable's name, availability, build/runtime scope, or semantics: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/environment-variables.md) or its [HTML version](https://render.com/docs/environment-variables). + +Depend only on documented platform variables. Other `RENDER_*` variables are internal and can change without notice. + +Treat environment-variable changes as service configuration mutations. Confirm the target workspace and service, inspect the existing keys without exposing their values, and preserve variables outside the user's requested scope. Before using an API, MCP, or CLI operation, check whether it patches individual keys or replaces the complete collection. After the applicable deploy, verify that required keys are present and that the service starts successfully without logging secret values. + +If the current references or live configuration cannot be inspected, do not guess at secret behavior, precedence, or replacement semantics. Preserve existing configuration where possible and explain what must be confirmed before making the change. + diff --git a/skills/render-env-vars/references/platform-variables.md b/skills/render-env-vars/references/platform-variables.md index 2b24803..3bfd78a 100644 --- a/skills/render-env-vars/references/platform-variables.md +++ b/skills/render-env-vars/references/platform-variables.md @@ -1,86 +1,17 @@ -# Render-injected and runtime environment variables +# Runtime-specific environment-variable notes -Render injects **platform variables** into builds and/or running services. Treat undocumented names as **unstable**. Always read **`PORT`** for HTTP listeners on native/web services unless your stack documents otherwise. +Read [environment-variables.md](environment-variables.md) and fetch the current default-variable reference before depending on a Render-injected variable's name, availability, build/runtime scope, or semantics. Do not use this file as a platform-variable catalog. -## Build-time vs runtime +## Worker concurrency -Availability can vary by **service type**, **language**, and **Docker vs native**. When in doubt, print `env` in a one-off shell (Dashboard **Shell**) or log at process start. The table below uses: +Services created after December 8, 2025 use updated default `WEB_CONCURRENCY` behavior compared with older services. When debugging unexpected worker counts, compare the service creation date, explicit `WEB_CONCURRENCY` overrides, and the currently documented concurrency and CPU variables. -- **Build** — available during `buildCommand` / image build steps Render controls -- **Runtime** — available to `startCommand` / container CMD +Treat platform-provided concurrency values as starting points. Tune worker counts with both CPU and memory constraints in mind, and validate them under representative load. -| Variable | Build | Runtime | Notes | -|----------|:-----:|:-------:|-------| -| `RENDER` | Often | Yes | `"true"` on Render | -| `RENDER_SERVICE_TYPE` | Often | Yes | e.g. `web`, `worker`, `static` | -| `RENDER_SERVICE_ID` | Often | Yes | Stable service UUID | -| `RENDER_SERVICE_NAME` | Often | Yes | Configured service name | -| `RENDER_INSTANCE_ID` | No | Yes | Per-running-instance id | -| `RENDER_EXTERNAL_URL` | Varies | Yes | Public URL when service has one | -| `RENDER_EXTERNAL_HOSTNAME` | Varies | Yes | Public hostname | -| `RENDER_DISCOVERY_SERVICE` | Varies | Yes | Private service discovery hostname | -| `RENDER_GIT_COMMIT` | Yes | Yes | SHA of deployed revision | -| `RENDER_GIT_BRANCH` | Yes | Yes | Branch for this deploy | -| `PORT` | Sometimes | Yes | **Default `10000`**; must bind `0.0.0.0` for inbound HTTP | -| `IS_PULL_REQUEST` | Varies | Yes | Set for preview deploys from PRs | -| `RENDER_CPU_COUNT` | Rare | Yes | vCPUs allocated to the instance | -| `RENDER_WEB_CONCURRENCY` | Rare | Yes | Hint for process/worker count (see below) | -| `NODE_VERSION` | Yes | If set | Native Node builds | -| `PYTHON_VERSION` | Yes | If set | Native Python builds | -| `RUBY_VERSION` | Yes | If set | Native Ruby builds | -| `GO_VERSION` | Yes | If set | Native Go builds | -| `RUST_VERSION` | Yes | If set | Native Rust builds | -| `ELIXIR_VERSION` | Yes | If set | Native Elixir builds | -| `ERLANG_VERSION` | Yes | If set | Often paired with Elixir | +## Native runtimes and Docker -Dockerfile-based services only see variables you set or that the platform injects at the relevant phase; **language version** env vars apply primarily to **Render native** build pipelines. +Language-version environment variables primarily apply to Render native build pipelines. Docker-based services should encode toolchain versions in the image or its build configuration. Confirm the supported version-selection mechanism in the current runtime documentation before changing it. -## `WEB_CONCURRENCY` and `RENDER_WEB_CONCURRENCY` +## Application parsing -- Many stacks read **`WEB_CONCURRENCY`** (Gunicorn, Unicorn, Puma integrations, etc.) to choose worker count. -- Render also exposes **`RENDER_WEB_CONCURRENCY`** as a **suggested** concurrency aligned with instance size. Some buildpacks or docs map between them; confirm in your service’s **Environment** tab. -- **Services created after December 8, 2025** use updated **default `WEB_CONCURRENCY`** behavior compared to older services. When debugging “too many/few workers,” compare **service creation date**, explicit **`WEB_CONCURRENCY`** overrides, and **`RENDER_CPU_COUNT`**. - -## `RENDER_CPU_COUNT` - -- Integer string (e.g. `"2"`) reflecting **allocated vCPUs** for the current instance type. -- Use for auto-tuning worker pools **in addition to** memory limits, not as a substitute for load testing. - -## Per-language defaults (implications) - -| Language / stack | Common injected or buildpack defaults | Implication | -|------------------|--------------------------------------|-------------| -| **Node.js** | `NODE_ENV=production` | DevDependencies may be omitted; assert logging and error handlers match prod | -| **Python** | `PYTHON_VERSION`, `GUNICORN_CMD_ARGS` → bind `0.0.0.0:10000` | Must match `PORT`; custom ASGI/WSGI commands should also bind `0.0.0.0:$PORT` | -| **Ruby** | `RAILS_ENV=production`, `RAILS_LOG_TO_STDOUT=true` | Logs go to stdout; ensure 12-factor logging | -| **Go** | `GO111MODULE=on` (legacy) | Modern Go may not need it; Dockerfile users set their own | -| **Rust / Rocket** | `ROCKET_PORT=10000` | Align with `PORT` or override consistently | -| **Elixir** | `ELIXIR_VERSION`, `ERLANG_VERSION`, `PORT` | Release must read `PORT` for Phoenix if not using defaults | - -## Language version variables - -These pin or document the toolchain Render uses for **native** builds: - -| Variable | Purpose | -|----------|---------| -| `NODE_VERSION` | Node.js major/minor selection | -| `PYTHON_VERSION` | Python 3.x selection | -| `RUBY_VERSION` | Ruby version | -| `GO_VERSION` | Go toolchain | -| `RUST_VERSION` | Rust toolchain | -| `ELIXIR_VERSION` | Elixir | -| `ERLANG_VERSION` | OTP / Erlang | - -Docker builds should encode versions in the **image** or **build args** instead of relying on these. - -## Reading environment variables from application code - -| Language | API | -|----------|-----| -| **JavaScript / Node.js** | `process.env.MY_VAR` | -| **Python** | `os.environ["MY_VAR"]` or `os.getenv("MY_VAR")` | -| **Ruby** | `ENV["MY_VAR"]` | -| **Go** | `os.Getenv("MY_VAR")` | -| **Elixir** | `System.get_env("MY_VAR")` | - -Remember: all values arrive as **strings**. Parse integers with explicit error handling; treat `"false"` and `""` carefully in boolean logic. +Environment-variable values arrive as strings. Parse integers with explicit error handling, and handle values such as `"false"` and the empty string deliberately in boolean logic. diff --git a/skills/render-env-vars/references/wiring-reference.md b/skills/render-env-vars/references/wiring-reference.md index a2bc76b..8186240 100644 --- a/skills/render-env-vars/references/wiring-reference.md +++ b/skills/render-env-vars/references/wiring-reference.md @@ -1,53 +1,6 @@ # Blueprint environment variable wiring -This reference covers every supported pattern for `envVars` entries in `render.yaml`. Pair with the **render-blueprints** skill for service structure, previews, and validation. - -## Field summary - -| Field | Meaning | -|-------|---------| -| `key` | Environment variable name | -| `value` | Hardcoded string (avoid secrets) | -| `generateValue: true` | Platform generates a **base64 256-bit** random string | -| `sync: false` | Dashboard prompt on **initial Blueprint create only**; ignored on updates; not for previews or env groups | -| `fromDatabase` | Pull fields from a Postgres (or other supported) database resource | -| `fromService` | Pull connection details from another Render service | -| `fromGroup` | Import all variables from an environment group by name | - -## `value` — hardcoded string - -```yaml -envVars: - - key: LOG_LEVEL - value: info - - key: APP_ENV - value: production -``` - -Use only for non-sensitive configuration. Never commit API keys or passwords this way. - -## `generateValue` — random secret - -```yaml -envVars: - - key: SESSION_SECRET - generateValue: true -``` - -Render creates a **base64-encoded 256-bit** value at provision time. Rotating usually requires a manual Dashboard edit or API update depending on your workflow. - -## `sync: false` — Dashboard-supplied on first create - -```yaml -envVars: - - key: STRIPE_SECRET_KEY - sync: false -``` - -- Prompt appears in the Dashboard when the Blueprint **first** creates the service. -- **Updates** to `render.yaml` do **not** re-trigger the prompt for existing services. -- **Invalid** in environment group definitions. -- **Excluded** from preview environment behavior for protected values (treat as operator-managed). +Read [environment-variables.md](environment-variables.md) first for current syntax discovery, secret handling, precedence, and mutation safety. This reference retains task-specific cross-resource wiring examples. Pair it with the **render-blueprints** skill for service structure, previews, and validation. ## `fromDatabase` — database properties @@ -56,6 +9,7 @@ Reference a database defined in the same Blueprint (name must match the resource Available **properties** (use the subset your app needs): - `connectionString` +- `connectionPoolString` (when managed PgBouncer is enabled) - `host` - `port` - `user` @@ -76,6 +30,10 @@ services: fromDatabase: name: mydb property: connectionString + - key: DATABASE_POOL_URL + fromDatabase: + name: mydb + property: connectionPoolString - key: PGHOST fromDatabase: name: mydb @@ -98,9 +56,9 @@ services: property: database ``` -## `fromService` — Key Value (Redis-style) +## `fromService` — Key Value -Use `type: keyvalue` with one of: `connectionString`, `host`, `port`, `hostport`. +Use `type: keyvalue` with one of: `connectionString`, `host`, or `port`. If an application needs `host:port`, combine the separate `host` and `port` values. ```yaml services: @@ -126,11 +84,6 @@ services: name: cache type: keyvalue property: port - - key: REDIS_HOSTPORT - fromService: - name: cache - type: keyvalue - property: hostport ``` ## `fromService` — private service or web service @@ -146,7 +99,7 @@ Alternatively, reference a **specific env var** exposed by the other service wit services: - type: pserv name: internal-api - env: docker + runtime: docker # ... - type: web @@ -188,19 +141,9 @@ services: value: only-on-app ``` -Individual keys from the group appear as if they were defined on the service. **Service-level** keys override **group** keys with the same name. - -## Precedence - -1. **Service-level** `envVars` entries **override** any variable with the same name coming from linked **environment groups**. -2. **Multiple groups** on one service: overlapping keys resolve using the **most recently created** group—this is **not guaranteed stable** across account operations. Prefer **non-overlapping** keys per group or a **single** group per concern. - ## Edge cases - **`fromService` / `fromDatabase` outside the Blueprint file** — You may reference resources that are **not** declared in `render.yaml` **only if** they **already exist** in the same Render **workspace** (same team/account context) and names match. Otherwise provision fails at apply time. -- **`sync: false` in groups** — Not allowed; use Dashboard or service-level entries. -- **Preview environments** — Sensitive patterns (`sync: false`, some generated rotations) may behave differently; verify preview env docs in **render-blueprints**. -- **Secret files** — Declared separately from `envVars`; paths are always `/etc/secrets/` at runtime. ## Minimal multi-pattern example diff --git a/skills/render-keyvalue/SKILL.md b/skills/render-keyvalue/SKILL.md index bf7dbf6..b8ed6bc 100644 --- a/skills/render-keyvalue/SKILL.md +++ b/skills/render-keyvalue/SKILL.md @@ -3,7 +3,7 @@ name: render-keyvalue description: >- Provisions and configures Render Key Value (Redis-compatible Valkey 8) instances for caching, session storage, and job queues. Use when the user - needs Redis, Key Value, Valkey, a cache, session store, job queue backend, + needs Key Value, uses Redis or Valkey, or needs a cache, session store, or job queue backend, or needs to configure maxmemory policy, ipAllowList, connection strings, or internal vs external access. Trigger terms: Key Value, Redis, Valkey, cache, session store, REDIS_URL, @@ -31,6 +31,8 @@ Render Key Value provides low-latency, Redis-compatible in-memory storage runnin For background worker setup and queue framework patterns, see **render-background-workers**. For Blueprint authoring, see **render-blueprints**. +Before configuring or troubleshooting an internal Key Value connection, read `references/private-networking.md`. + ## Key Concepts ### Valkey 8 (not Redis) @@ -43,7 +45,7 @@ Every instance has two URLs: | URL type | When to use | Auth required | |----------|-------------|---------------| -| **Internal** (`redis://red-xxx:6379`) | From Render services in the same region | No (by default) | +| **Internal** (`redis://red-xxx:6379`) | From Render services in the same workspace and region | No (by default) | | **External** (`rediss://red-xxx:6379`) | From outside Render (local dev, CI) | Always | **Always prefer the internal URL** for production services—lower latency, no TLS overhead, communicates over the private network. @@ -132,12 +134,9 @@ Available `fromService` properties for Key Value: - **Free instances:** No disk persistence. Data is lost on restart or upgrade. - **Upgrading from Free:** All data is lost during the upgrade because Free instances have no disk. -## Instance Types and Upgrades +## Compute Plans and Changes -- Instance type determines **RAM** and **connection limit** -- You can **upgrade** to a larger type (brief downtime, ~1-2 minutes) -- You **cannot downgrade** to a smaller type -- For instances larger than 10 GB RAM, contact Render support +The compute plan determines available memory and connection limits. Use `references/compute-plans.md` for current Plan IDs and Key Value-specific change guidance. ## Connection Examples @@ -157,6 +156,8 @@ See `references/connection-examples.md` for client code in Node.js (ioredis, nod | Document | Contents | |----------|----------| +| `references/compute-plans.md` | Current Plan IDs, specifications, availability, and Key Value plan changes | +| `references/private-networking.md` | Current private-network scope, internal addressing, isolation, and troubleshooting | | `references/connection-examples.md` | Client code for Node.js, Python, Ruby, Go | | `references/troubleshooting.md` | Auth errors, connection refused, memory full, migration from Redis 6 | @@ -166,3 +167,16 @@ See `references/connection-examples.md` for client code in Node.js (ioredis, nod - **render-blueprints** — Full `render.yaml` schema, `fromService` patterns - **render-networking** — Private network, internal URLs - **render-env-vars** — Wiring `REDIS_URL` and other connection vars + + +## Current documentation retrieval + +Whenever this skill directs you to consult current Render documentation: + +1. Retrieve the linked Markdown document directly with an available URL-fetching tool or HTTP client, such as `curl`. Do not substitute web-search summaries for the document. +2. Confirm that retrieval succeeded and returned the expected document, then read its contents. Saving a file or printing its path is not sufficient. +3. If the request fails or your tool cannot read the Markdown response, open and read the linked HTML version instead. +4. If neither version can be retrieved, disclose that the current reference is unavailable and follow any topic-specific fallback in the skill. Use bundled guidance only for stable constraints, and do not guess at changeable platform details. + +When a task requires multiple references, apply this workflow to each one and distinguish the documents you verified from those that remain unavailable. + diff --git a/skills/render-keyvalue/references/compute-plans.md b/skills/render-keyvalue/references/compute-plans.md new file mode 100644 index 0000000..4453df6 --- /dev/null +++ b/skills/render-keyvalue/references/compute-plans.md @@ -0,0 +1,29 @@ + +## Compute plans + +A compute plan determines the CPU and RAM available to each instance of a Render service. Use **compute plan**, not the former term **instance type**. Do not confuse a service's compute plan with its workspace plan, which controls account-level features and limits. + +Compute plans differ by service type: + +- Web services, private services, background workers, and cron jobs use CPU-and-memory plan IDs such as `0.5c-512mb` and `1c-2g`. +- Render Postgres has its own plan catalog and connection limits. +- Render Key Value uses memory-based plan IDs such as `256mb` and `1g`. +- Workflow tasks select a compute plan in application code; a Workflow service does not set a Blueprint `plan`. +- Static sites do not have compute plans. + +Legacy plan names such as `starter`, `standard`, and `pro` remain valid in Render tooling, including Blueprints and API requests. For new configuration, prefer the current plan ID when the selected configuration surface accepts it. Before passing a plan to an API, MCP tool, or CLI command, inspect that operation's current schema or help and use one of its accepted values; the compute-plan reference describes the product catalog, not every tool version's input contract. Do not rename an existing legacy plan merely for consistency unless the user asks for that change. + +Do not rely on a memorized plan catalog. When a task depends on current plan IDs, specifications, defaults, availability, or pricing, fetch the canonical compute-plan reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/compute-plans.md) or its [HTML version](https://render.com/docs/compute-plans). + +Read the section for the relevant service type. If the document cannot be fetched, do not guess at current plan details. Preserve an existing valid plan where possible, or explain that the plan must be confirmed in the Render Dashboard or current documentation. + +When estimating capacity or cost, remember that every instance of a scaled service uses the selected compute plan and is billed accordingly. Changing the compute plan for Render Postgres, Render Key Value, or a service with an attached persistent disk requires brief downtime; other services normally apply the change with a zero-downtime deploy. + + +## Key Value plan changes + +- A Key Value compute plan determines available memory and connection limits. +- Changing the compute plan causes brief downtime. +- Key Value compute plans can be increased but not decreased. To move to a smaller plan, create a new instance and migrate the data. diff --git a/skills/render-keyvalue/references/connection-examples.md b/skills/render-keyvalue/references/connection-examples.md index 0c962a4..c9e9838 100644 --- a/skills/render-keyvalue/references/connection-examples.md +++ b/skills/render-keyvalue/references/connection-examples.md @@ -1,6 +1,6 @@ # Key Value Connection Examples -All examples use the internal URL via the `REDIS_URL` environment variable. Wire `REDIS_URL` in your Blueprint with `fromService`: +Read [private-networking.md](private-networking.md) first for current internal-connection requirements. All examples use the internal URL via the `REDIS_URL` environment variable. Wire `REDIS_URL` in your Blueprint with `fromService`: ```yaml envVars: diff --git a/skills/render-keyvalue/references/private-networking.md b/skills/render-keyvalue/references/private-networking.md new file mode 100644 index 0000000..d68d6be --- /dev/null +++ b/skills/render-keyvalue/references/private-networking.md @@ -0,0 +1,25 @@ + +## Private networking + +Render services can communicate over a private network without traversing the public internet. Private-network peers must belong to the same workspace and run in the same region. An isolated project environment can additionally block traffic both to and from resources outside that environment, so workspace and region matching alone do not guarantee connectivity. + +Before designing, configuring, or troubleshooting private-network communication, fetch the current Render private-network reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/private-network.md) or its [HTML version](https://render.com/docs/private-network). + +Read the relevant sections. Confirm current service-type capabilities, port restrictions, environment-isolation behavior, discovery-hostname guidance, and plan requirements instead of relying on a memorized catalog. + +Web services and private services have internal hostnames and can receive private-network traffic. A private service must bind at least one port; use a background worker instead when a workload does not need to accept inbound connections. Render Postgres and Key Value instances provide internal connection URLs. Workflows, background workers, and cron jobs can initiate private-network connections but do not have an internal address for receiving them. Static sites are not on the private network. Free web services can initiate private-network connections but cannot receive them. + +Prefer the internal address or URL shown under **Connect > Internal** in the Render Dashboard. Include the protocol when the client or server requires one; an address such as `service:10000` does not by itself establish whether to use HTTP, HTTPS, or another protocol. A process that receives traffic must listen on the intended port and on an interface reachable outside its own container, such as `0.0.0.0`, rather than only on loopback. + +For Blueprint-managed connections, fetch the current Blueprint specification and use supported service or database references instead of copying a generated hostname, port, credential, or connection string. Web and private services currently expose `host`, `port`, and `hostport` properties. A Blueprint can obtain another service's discovery hostname by referencing that service's `RENDER_DISCOVERY_SERVICE` environment variable with `fromService.envVarKey`; the discovery hostname is not a service property. The fetched specification is authoritative for the syntax and supported references. + +A service can expose at most 75 ports on the private network. Ports `18012`, `18013`, and `19099` are unavailable for private-network communication. Port `10000` is not generally blocked: for a web service, private traffic to port `10000` routes to its primary HTTP server even when that server binds to another port. In that case, both port `10000` and the actual primary HTTP port route to the same server. + +Use a service's normal internal hostname for ordinary service-to-service traffic. For advanced per-instance communication, each web or private service has a discovery hostname, conventionally formed by appending `-discovery` to its internal hostname, that resolves to all active instance IP addresses. A service receives its own discovery hostname in `RENDER_DISCOVERY_SERVICE`. Use DNS APIs that honor the system resolver configuration, and do not persist resolved instance IPs because they can change between deploys. Prefer hostname-based communication unless per-instance addressing or custom load balancing is specifically required. + +When a private-network connection fails, verify the workspace, region, project-environment isolation settings, whether the destination service type accepts inbound traffic, the internal hostname or URL, protocol, port, listening interface, current deploy health, and DNS resolution. Do not substitute a public URL or expose a private service merely to bypass a private-network configuration problem. + +AWS PrivateLink is a separate Pro-or-higher feature for connecting a Render private network to compatible AWS-hosted systems. Fetch its current documentation before proposing or configuring it; do not treat ordinary Render service-to-service networking and PrivateLink as interchangeable. + diff --git a/skills/render-keyvalue/references/troubleshooting.md b/skills/render-keyvalue/references/troubleshooting.md index 62017bb..7f95afa 100644 --- a/skills/render-keyvalue/references/troubleshooting.md +++ b/skills/render-keyvalue/references/troubleshooting.md @@ -13,10 +13,12 @@ This only applies to external connections. Internal connections from Render serv ## Connection refused (internal URL) -**Cause:** Service and Key Value instance are in different regions, or the Key Value instance is not yet available. +Read [private-networking.md](private-networking.md) for the complete private-connectivity checklist. + +**Cause:** The resources do not share the required private-network scope, project-environment isolation blocks the connection, or the Key Value instance is not yet available. **Fix:** -- Verify both resources are in the **same region** (e.g. both in `oregon`) +- Verify both resources are in the **same workspace and region** and are not separated by environment isolation - Check the instance status in Dashboard — it should show "Available" - Ensure you're using the **internal** URL (starts with `redis://`), not the external URL @@ -37,7 +39,7 @@ Get the authenticated URL from Dashboard > Connect menu. **Cause:** Instance memory is full and `maxmemoryPolicy` is `noeviction`. **Fix options:** -- **Upgrade** to a larger instance type (Dashboard > Key Value Instance > Update) +- **Upgrade** to a larger compute plan (Dashboard > Key Value Instance > Update) - **Add TTLs** to keys that don't need to persist forever - **Switch policy** to `allkeys-lru` if data loss is acceptable (cache use case) - **Review data patterns** — are you storing more than intended? @@ -60,6 +62,6 @@ Instances created before February 2025 run Redis 6. They continue to operate but No action is required unless you need Valkey 8-specific features. Migration to a new instance requires creating a new Key Value and updating connection strings. -## Cannot downgrade instance type +## Cannot downgrade a compute plan -Instance type changes are **upgrade-only**. You cannot move to a smaller instance. If you need less capacity, create a new smaller instance and migrate your data. +Compute-plan changes are **upgrade-only**. You cannot move to a smaller plan. If you need less capacity, create a new smaller instance and migrate your data. diff --git a/skills/render-mcp/SKILL.md b/skills/render-mcp/SKILL.md index bf0d5ea..ecb43ab 100644 --- a/skills/render-mcp/SKILL.md +++ b/skills/render-mcp/SKILL.md @@ -2,8 +2,8 @@ name: render-mcp description: >- Connects and configures the Render MCP server for AI coding tools—setup per - tool (Cursor, Claude Code, Codex), authentication, workspace selection, tool - catalog, and troubleshooting. Use when MCP is not configured, list_services() + tool (Cursor, Claude Code, Codex), authentication, workspace selection, + capability discovery, and troubleshooting. Use when MCP is not configured, list_services() fails, the user asks about Render MCP setup, or an action skill needs MCP but it's not connected yet. Trigger terms: MCP, Render MCP, list_services, MCP setup, MCP server, @@ -18,10 +18,12 @@ metadata: # Render MCP Server -The Render MCP server lets AI coding tools manage Render services, databases, deploys, logs, and metrics directly. This skill covers **setup**, **authentication**, **workspace selection**, the **tool catalog**, and **troubleshooting**. +The Render MCP server lets AI coding tools manage Render resources directly. This skill covers **setup**, **authentication**, **workspace selection**, **capability discovery**, and **troubleshooting**. Action skills (render-deploy, render-debug, render-monitor) use MCP tools for their workflows. If MCP is not connected, set it up using this skill first. +Before configuring, troubleshooting, or using Render MCP, read `references/render-access.md` for the current server, authentication, workspace, capability-discovery, and fallback workflow. + ## When to Use - `list_services()` fails or MCP tools are unavailable @@ -30,29 +32,15 @@ Action skills (render-deploy, render-debug, render-monitor) use MCP tools for th - Switching workspaces or troubleshooting auth errors - Discovering which MCP tools exist and what they do -## Connection Details - -| Property | Value | -|----------|-------| -| URL | `https://mcp.render.com/mcp` | -| Transport | HTTP (streamable) | -| Auth | OAuth when installed via the Render plugin (pre-registered client id); bearer token (API key) for manual setup | -| API key page | `https://dashboard.render.com/u/*/settings#api-keys` (manual setup) | -| Docs | `https://render.com/docs/mcp-server` | - -## Setup by Tool - -### Render plugin (recommended) +## Current Setup and Capabilities -The Render plugin for Cursor, Codex, and Claude Code bundles this MCP server with a pre-registered OAuth client id, so no API key is needed. After installing or updating the plugin, reload the tool (restart Cursor or Claude Code, or start a new Codex thread) so it loads the plugin-provided MCP server, then complete the Render OAuth prompt the first time MCP tools are used. Verify with `list_services()`. +Follow `references/render-access.md` to fetch the current MCP documentation, configure the client, verify read-only access, select the intended workspace, and inspect the tools actually available. Do not rely on a memorized tool catalog. -The manual, API-key setups below are for tools without the plugin or for custom MCP configurations. +If the user has not identified their AI tool, ask which tool they use before giving client-specific setup instructions. Prefer the official Render plugin or connector and its browser-based OAuth flow when available. For a manual API-key setup, create a key at `https://dashboard.render.com/u/settings#api-keys` and use the hosted endpoint `https://mcp.render.com/mcp`. -### Cursor +### Manual client setup -1. Get an API key from the [Render Dashboard](https://dashboard.render.com/u/*/settings#api-keys) - -2. Add to `~/.cursor/mcp.json`: +For Cursor, add this configuration to `~/.cursor/mcp.json`, restart Cursor, and verify the connection with `list_services()`: ```json { @@ -67,142 +55,19 @@ The manual, API-key setups below are for tools without the plugin or for custom } ``` -3. Restart Cursor, then verify with `list_services()` - -### Claude Code - -1. Get an API key from the [Render Dashboard](https://dashboard.render.com/u/*/settings#api-keys) - -2. Add the MCP server: +For Claude Code, add the server with: ```bash claude mcp add --transport http render https://mcp.render.com/mcp --header "Authorization: Bearer " ``` -3. Restart Claude Code, then verify with `list_services()` - -### Codex - -1. Get an API key from the [Render Dashboard](https://dashboard.render.com/u/*/settings#api-keys) - -2. Set the key in your shell: - -```bash -export RENDER_API_KEY="" -``` - -3. Add the MCP server: - -```bash -codex mcp add render --url https://mcp.render.com/mcp --bearer-token-env-var RENDER_API_KEY -``` - -4. Restart Codex, then verify with `list_services()` - -### Other Tools - -For tools not listed above, use the generic HTTP MCP configuration: - -- **URL:** `https://mcp.render.com/mcp` -- **Auth header:** `Authorization: Bearer ` -- **Transport:** HTTP (streamable HTTP, not SSE) - -See [Render MCP docs](https://render.com/docs/mcp-server) for tool-specific instructions. - -## Workspace Selection - -After MCP is connected, set the active workspace: - -``` -Set my Render workspace to [WORKSPACE_NAME] -``` - -Or programmatically: - -``` -get_selected_workspace() # Check current -list_workspaces() # List available -``` - -All MCP operations run against the active workspace. - -## Tool Catalog - -### Service management - -| Tool | Purpose | -|------|---------| -| `list_services()` | List all services and datastores | -| `get_service(serviceId)` | Get service details | -| `create_web_service(...)` | Create a web service from Git repo | -| `create_static_site(...)` | Create a static site from Git repo | -| `update_service(serviceId, ...)` | Update service configuration | -| `restart_service(serviceId)` | Restart a service | - -### Deploys - -| Tool | Purpose | -|------|---------| -| `list_deploys(serviceId, limit)` | List deploys for a service | -| `trigger_deploy(serviceId)` | Trigger a new deploy | - -### Logs - -| Tool | Purpose | -|------|---------| -| `list_logs(resource, level, type, text, statusCode, limit)` | Query logs with filters | - -Key filters: `level` (error, warn, info), `type` (build, deploy), `text` (search string), `statusCode` (HTTP codes). - -### Metrics +Restart Claude Code and verify with `list_services()`. To replace a stale manual configuration, run `claude mcp remove render` before adding it again. -| Tool | Purpose | -|------|---------| -| `get_metrics(resourceId, metricTypes, ...)` | Get service or database metrics | +For Codex, follow the current OAuth or API-key configuration fetched through `references/render-access.md`. If the configuration obtains its bearer token from `RENDER_API_KEY`, that variable must be available in the environment where Codex starts; restart Codex after changing it. -Metric types: `cpu_usage`, `memory_usage`, `cpu_limit`, `memory_limit`, `http_latency`, `http_request_count`, `active_connections`. +### Empty results and workspace selection -Optional: `httpLatencyQuantile` (0.5, 0.95, 0.99), `httpPath` (filter by endpoint). - -### Databases - -| Tool | Purpose | -|------|---------| -| `list_postgres_instances()` | List Postgres databases | -| `get_postgres(postgresId)` | Get database details | -| `query_render_postgres(postgresId, sql)` | Run SQL query | - -### Key Value - -| Tool | Purpose | -|------|---------| -| `list_key_value()` | List Key Value instances | -| `get_key_value(keyValueId)` | Get Key Value details | - -### Environment Variables - -| Tool | Purpose | -|------|---------| -| `update_environment_variables(serviceId, envVars)` | Set env vars on a service | - -### Workspace - -| Tool | Purpose | -|------|---------| -| `list_workspaces()` | List available workspaces | -| `get_selected_workspace()` | Get the active workspace | - -## Common Mistakes - -| Mistake | Fix | -|---------|-----| -| Wrong URL (using SSE endpoint) | Use `https://mcp.render.com/mcp` (not `/sse`) | -| Plugin installed but MCP tools unavailable | Reload the tool (restart, or start a new thread) so it loads the plugin's MCP server | -| OAuth prompt does not appear | Reinstall or update the Render plugin, then reload the tool | -| Expired or invalid API key | Generate a new key from Dashboard > Account Settings > API Keys | -| Wrong workspace selected | Run `list_workspaces()` and switch to the correct one | -| Using MCP to create image-backed services | Not supported — use Dashboard or API for prebuilt Docker images | -| Missing `Bearer` prefix in auth header | Header must be `Authorization: Bearer ` | +MCP operations run against the active workspace. If `list_services()` connects successfully but returns no services, first call `get_selected_workspace()`, then `list_workspaces()` if the wrong workspace might be selected. Also verify that the credential or `RENDER_API_KEY` belongs to an account with access to the intended workspace. Do not diagnose the server URL as the primary problem when the MCP call itself succeeds. ## Troubleshooting @@ -212,6 +77,7 @@ See `references/troubleshooting.md` for connection errors, auth failures, timeou | Document | Contents | |----------|----------| +| `references/render-access.md` | Current MCP and CLI access, authentication, workspace, capability-discovery, and authorization workflow | | `references/troubleshooting.md` | Connection errors, auth failures, tool-specific issues, timeout handling | ## Related Skills @@ -220,3 +86,16 @@ See `references/troubleshooting.md` for connection errors, auth failures, timeou - **render-debug** — Debug failures using MCP logs and metrics - **render-monitor** — Monitor health using MCP metrics - **render-cli** — CLI alternative when MCP is unavailable + + +## Current documentation retrieval + +Whenever this skill directs you to consult current Render documentation: + +1. Retrieve the linked Markdown document directly with an available URL-fetching tool or HTTP client, such as `curl`. Do not substitute web-search summaries for the document. +2. Confirm that retrieval succeeded and returned the expected document, then read its contents. Saving a file or printing its path is not sufficient. +3. If the request fails or your tool cannot read the Markdown response, open and read the linked HTML version instead. +4. If neither version can be retrieved, disclose that the current reference is unavailable and follow any topic-specific fallback in the skill. Use bundled guidance only for stable constraints, and do not guess at changeable platform details. + +When a task requires multiple references, apply this workflow to each one and distinguish the documents you verified from those that remain unavailable. + diff --git a/skills/render-mcp/references/render-access.md b/skills/render-mcp/references/render-access.md new file mode 100644 index 0000000..864c854 --- /dev/null +++ b/skills/render-mcp/references/render-access.md @@ -0,0 +1,50 @@ + +## Accessing Render + +Prefer the hosted Render MCP server for structured access to Render resources when its tools are available. Use the Render CLI when MCP is unavailable or does not support the required operation, and use the Render Dashboard or API for capabilities exposed by neither. Do not assume that a remembered MCP tool or CLI command is still available; inspect the tools in the current environment or consult the current documentation. + +The hosted Render MCP server uses streamable HTTP at: + +```text +https://mcp.render.com/mcp +``` + +Official Render plugins and connectors can authenticate MCP with browser-based OAuth. Manual and non-interactive configurations can use a Render API key as a bearer token. Never write an API key or OAuth token into a repository, skill, command output, chat response, or log. Prefer the client's supported secret storage or environment-variable mechanism. If a client requires a credential in local configuration, keep that file out of version control and restrict access to it. + +Treat MCP responses as potentially sensitive even when the server attempts to minimize credential exposure. Request connection strings, credentials, secret environment variables, or other sensitive fields only when the task requires them. Do not repeat sensitive values in the response or persist them in files or logs. + +Before configuring or troubleshooting MCP, fetch the current setup and capability reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/mcp-server.md) or its [HTML version](https://render.com/docs/mcp-server). + +Read the relevant client setup, supported-actions, and limitations sections. Prefer the hosted server unless the user's environment requires a local MCP server. After installing, updating, or reconfiguring an MCP integration, reload the client as required and verify the connection with a read-only operation such as listing services. + +Most MCP operations and Render CLI commands that access Render resources are scoped to an active workspace. Check the selected workspace before reading or changing resources. If no workspace is selected—or if the intended workspace is ambiguous—list the available workspaces and have the user identify the correct one. Do not silently switch workspace context or infer it from a resource name. Commands for authentication, help, CLI configuration, and workspace discovery or selection do not require an already selected workspace. + +For interactive CLI use, authenticate with `render login`. For automation, use a securely stored `RENDER_API_KEY`; an API key takes precedence over a saved CLI token. Verify CLI access and the active workspace with read-only commands before operating on resources: + +```bash +render whoami --output json +render workspace current --output json +``` + +For CLI installation, authentication, workspace setup, and usage patterns, fetch the current CLI overview: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/cli.md) or its [HTML version](https://render.com/docs/cli). + +For exact command syntax and flags, prefer the help text from the installed CLI because it matches the version being used: + +```bash +render help +``` + +The published CLI command reference is generated automatically from the CLI's help text. Use it to browse the full command surface or when the CLI is not installed: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/cli-reference.md) or its [HTML version](https://render.com/docs/cli-reference). + +When an agent or automation invokes the CLI, select a non-interactive output format such as `--output json`, `--output yaml`, or `--output text` so results can be inspected reliably. The global `--confirm` flag skips confirmation prompts; use it for a mutating command only after that mutation is authorized. It is an execution convenience, not permission to perform the action. + +Authentication establishes access; it does not establish user authorization for every available action. Use read-only discovery to resolve workspace, resource identity, and current state before a mutation. Perform changes only when they are within the user's requested scope, and retain normal approval requirements for consequential operations such as creation, configuration changes, deploys, restarts, scaling, or deletion. + +When authentication or connectivity fails, report which access path failed, preserve the underlying error without exposing credentials, and either use an available supported fallback or explain what the user must configure before the task can continue. + diff --git a/skills/render-mcp/references/troubleshooting.md b/skills/render-mcp/references/troubleshooting.md index 5c90a0f..dc53e38 100644 --- a/skills/render-mcp/references/troubleshooting.md +++ b/skills/render-mcp/references/troubleshooting.md @@ -6,25 +6,19 @@ **Cause:** MCP server not configured in the AI tool. -**Fix:** Follow the setup instructions in the main SKILL.md. If you use the Render plugin, reinstall or update it and reload the tool so it loads the plugin's MCP server. For manual clients, add the config and restart the tool. +**Fix:** Follow the current setup and verification workflow in [render-access.md](render-access.md). ### "Connection refused" or timeout **Cause:** Network issue or incorrect URL. -**Fix:** -- Verify the URL is exactly `https://mcp.render.com/mcp` -- Check internet connectivity -- Some corporate firewalls block MCP connections — try from a different network +**Fix:** Confirm the current endpoint and transport using [render-access.md](render-access.md), check internet connectivity, and account for corporate firewalls that might block MCP connections. ### "Transport error" or "SSE not supported" **Cause:** Using the wrong transport or URL. -**Fix:** -- Use HTTP transport (streamable HTTP), not SSE -- URL should be `https://mcp.render.com/mcp`, not `https://mcp.render.com/sse` -- For Claude Code: use `--transport http` flag +**Fix:** Reconfigure the client from the current MCP documentation fetched through [render-access.md](render-access.md). ## Authentication Errors @@ -32,24 +26,17 @@ **Cause:** Missing or expired OAuth authorization (plugin setup), or a missing, invalid, or expired API key (manual setup). -**Fix:** -1. Plugin setup: reinstall or update the Render plugin, then complete the Render OAuth prompt after reloading the tool. -2. Manual setup: generate a new API key (`https://dashboard.render.com/u/*/settings#api-keys`) and update it in your tool's MCP config. -3. Restart the tool. -4. Verify with `list_services()`. +**Fix:** For OAuth, reconnect the Render plugin or connector and complete authorization again. For manual setup, create a new key at `https://dashboard.render.com/u/settings#api-keys`, replace the configured bearer token, restart the client, and verify with `list_services()`. In Claude Code, run `claude mcp remove render`, then re-add it with the manual setup command in `SKILL.md`. ### "Forbidden" or 403 **Cause:** OAuth authorization or API key doesn't have access to the requested resource, or wrong workspace. -**Fix:** -- Check the active workspace with `get_selected_workspace()` -- Switch workspaces if needed with `list_workspaces()` -- Ensure the API key belongs to an account with access to the workspace +**Fix:** Verify the intended workspace and confirm that the authenticated account has access to it, following [render-access.md](render-access.md). ## Tool-Specific Issues -> Installed the Render plugin? It provides the MCP server over OAuth — complete the Render OAuth prompt and reload the tool after installing or updating the plugin. The manual notes below apply to hand-configured MCP clients. +Use the current client-specific setup instructions fetched through [render-access.md](render-access.md). Also check these local failure modes: ### Cursor @@ -60,37 +47,26 @@ ### Claude Code -- Added via CLI: `claude mcp add --transport http render https://mcp.render.com/mcp --header "Authorization: Bearer "` -- To update: `claude mcp remove render` then re-add -- To list: `claude mcp list` +- Confirm the configured server appears in the client's MCP server list. +- Replace a stale manual setup with `claude mcp remove render`, then re-add it with the manual setup command in `SKILL.md`. ### Codex -- Requires `RENDER_API_KEY` env var to be set in the shell where Codex runs -- Added via: `codex mcp add render --url https://mcp.render.com/mcp --bearer-token-env-var RENDER_API_KEY` -- If the env var is not set when Codex starts, MCP auth fails +- If the MCP configuration uses `RENDER_API_KEY`, it must be set in the shell or environment where Codex starts. +- Restart Codex after changing its MCP configuration or credential environment. ## Workspace Issues ### "No workspace selected" -**Fix:** Run `list_workspaces()` to see available workspaces, then ask the user to select one. +**Fix:** Follow the workspace-selection workflow in [render-access.md](render-access.md). ### Operations return empty results **Cause:** Active workspace has no services, or wrong workspace is selected. -**Fix:** Verify with `get_selected_workspace()` and switch if needed. +**Fix:** Call `get_selected_workspace()` to inspect the active workspace and `list_workspaces()` to find the intended one. Verify credential access before concluding that no resources exist. ## MCP vs CLI Fallback -If MCP cannot be configured (network restrictions, unsupported tool), use the Render CLI as a fallback. See **render-cli** for setup and usage. - -| Capability | MCP | CLI | -|-----------|-----|-----| -| List services | `list_services()` | `render services -o json` | -| View logs | `list_logs(...)` | `render logs -r SVC` | -| Deploy | `trigger_deploy(serviceId)` | `render deploys create SVC --wait` | -| Metrics | `get_metrics(...)` | Not available | -| SQL queries | `query_render_postgres(...)` | `render psql DB -c "SQL"` | -| SSH | Not available | `render ssh SVC` | +Use the supported fallback selection in [render-access.md](render-access.md), then inspect the current CLI or MCP capability surface instead of relying on a fixed comparison table. diff --git a/skills/render-migrate-from-heroku/SKILL.md b/skills/render-migrate-from-heroku/SKILL.md index db18910..179e59c 100644 --- a/skills/render-migrate-from-heroku/SKILL.md +++ b/skills/render-migrate-from-heroku/SKILL.md @@ -11,21 +11,31 @@ metadata: # Heroku to Render Migration -Migrate from Heroku to Render by reading local project files first, then optionally enriching with live Heroku data via MCP. +Migrate from Heroku to Render using the user's supplied inventory or local project files, then optionally enrich missing details with live Heroku data via MCP. ## Prerequisites Check Before starting, verify what's available: -1. **Local project files** (required) — confirm the current directory contains a Heroku app (look for `Procfile`, `app.json`, `package.json`, `requirements.txt`, `Gemfile`, `go.mod`, or similar) +1. **App inventory** (required) — use complete details supplied by the user, or inspect local project files such as `Procfile`, `app.json`, `package.json`, `requirements.txt`, `Gemfile`, or `go.mod` 2. **Render MCP** (recommended) — check if `list_services` tool is available. Required for MCP Direct Creation (Step 3B) and automated verification (Step 6). Not required for the Blueprint path — the Render CLI and Dashboard handle generation, validation, and deployment. 3. **Heroku MCP** (optional) — check if `list_apps` tool is available -If Render MCP is missing and the user needs it, guide them through setup using the [MCP setup guide](references/mcp-setup.md). If Heroku MCP is missing, note that config var values and add-on plan details will need to be provided manually. +Do not require local files or MCP when the user has already supplied enough information for the requested plan, Blueprint, or migration instructions. If Render MCP is missing and the user actually needs live Render access, use the Render access workflow in [references/render-access.md](references/render-access.md); the [MCP setup guide](references/mcp-setup.md) adds Heroku-specific setup. If Heroku MCP is missing, use supplied values or ask only for missing config-var names and add-on details. ## Migration Workflow -Execute steps in order. Present findings to the user and get confirmation before creating any resources. +For an end-to-end migration, execute the applicable steps in order. Present findings to the user and get confirmation before creating any resources. + +Before mapping Heroku process types to Render service types, read [references/service-types.md](references/service-types.md). + +### Choose the narrow workflow + +- **Complete inventory + Blueprint request:** read `references/service-mapping.md`, `references/blueprint-example.md`, and `references/blueprints.md`; generate the complete Blueprint directly. Do not call live tools merely to rediscover values the user supplied. +- **Single-service migration:** gather the missing inventory, present the plan, and use MCP Direct Creation only after the user asks to create the service and confirms the plan. +- **Data-migration question:** read `references/service-mapping.md` and `references/data-migration.md`; provide the applicable procedure without performing live operations unless requested. + +Use the exact Heroku plan row in `references/service-mapping.md`, including its mapped Render plan and disk allocation. These migration mappings intentionally use legacy Render plan names where appropriate; do not substitute a remembered current Plan ID. ### Step 1: Inventory Heroku App @@ -91,7 +101,7 @@ Processes: release: [command] → Append to build command Add-ons: Heroku Postgres ([plan-slug], [disk-size]) → Render Postgres ([mapped-plan], diskSizeGB: [size]) - Heroku Redis ([plan-slug]) → Render Key Value ([mapped-plan]) + Heroku Key-Value Store ([plan-slug]) → Render Key Value ([mapped-plan]) Config vars: 14 total (list names, not values) ``` @@ -105,7 +115,7 @@ Before creating anything, run through the [pre-flight checklist](references/pref - Git remote exists and is HTTPS format - Database size (large DBs need assisted migration) -Look up each Heroku dyno size and add-on plan in the [service mapping](references/service-mapping.md) to determine correct Render plans and cost estimates. Present the migration plan table from the [pre-flight checklist](references/preflight-checklist.md) and wait for user confirmation before creating any resources. +Look up each Heroku dyno size and add-on plan in the [service mapping](references/service-mapping.md) to determine the correct Render plans. Present the migration plan table from the [pre-flight checklist](references/preflight-checklist.md), flag resources that incur charges, direct the user to [Render pricing](https://render.com/pricing) for current details, and wait for confirmation before creating anything. ### Determine Creation Method @@ -128,11 +138,11 @@ If unsure, use Blueprint. Most Heroku apps have at least a database, so Blueprin ### Step 3A: Generate Blueprint (Multi-Service) -This step has three mandatory sub-steps. Complete all three in order. +This path has three stages. Always complete authoring; perform local validation and provide the apply flow when those actions are in scope. #### 3A-i. Write render.yaml -Generate a `render.yaml` file and write it to the repo root. See the [Blueprint example](references/blueprint-example.md) for a complete example, the [Blueprint docs](https://render.com/docs/blueprint-spec#projects-and-environments) for usage guidance, and the [Blueprint YAML JSON schema](https://render.com/schema/render.yaml.json) for the full field reference. +Generate a complete `render.yaml`. Write it to the repository root when operating in the user's repository; otherwise present the complete file in the response. Before authoring it, read the current specification-fetch, validation, repository-sync, and safety workflow in [references/blueprints.md](references/blueprints.md). Then use the [Blueprint example](references/blueprint-example.md) for the migration-specific structure. **IMPORTANT: Always use the `projects`/`environments` pattern.** The YAML must start with a `projects:` key — never use flat top-level `services:` or `databases:` keys. This groups all migrated resources into a single Render project. @@ -148,13 +158,13 @@ Generate the YAML following the full template, rules, and patterns in the [Bluep #### 3A-ii. Validate the Blueprint -This step is mandatory. First, check if the Render CLI is installed: +When a `render.yaml` file has been written locally, validate it before presenting it as ready to deploy. First, check if the Render CLI is installed: ```bash render --version ``` -If not installed, offer to install it: +If not installed, offer to install it when deployment-ready local validation is in scope: - macOS: `brew install render` - Linux/macOS: `curl -fsSL https://raw.githubusercontent.com/render-oss/cli/main/bin/install.sh | sh` @@ -165,11 +175,11 @@ Once the CLI is available, run the validation command and show the output to the render blueprints validate render.yaml ``` -If validation fails, fix the errors in the YAML and re-validate. Repeat until validation passes. **Do not proceed to the next step until the Blueprint validates successfully.** +If validation fails, fix the errors in the YAML and re-validate. Repeat until validation passes. When the user requested only an example or no local file exists, provide the validation command without attempting installation or claiming that validation ran. #### 3A-iii. Provide the deploy URL -After validation passes: +When the user wants to apply the Blueprint, after validation passes: 1. Instruct user to commit and push: `git add render.yaml && git commit -m "Add Render migration Blueprint" && git push` 2. Get the repo URL by running `git remote get-url origin`. If the URL is SSH format (e.g., `git@github.com:user/repo.git`), convert it to HTTPS (`https://github.com/user/repo`). Then construct the deeplink: `https://dashboard.render.com/blueprint/new?repo=` @@ -179,13 +189,7 @@ After validation passes: ### Step 3B: MCP Direct Creation (Single-Service) -Before creating resources via MCP, verify the active workspace: - -``` -get_selected_workspace() -``` - -If the workspace is wrong, list available workspaces with `list_workspaces()` and ask the user to select the correct one. Resources will be created in whichever workspace is active. +Before creating resources via MCP, follow [references/render-access.md](references/render-access.md) and verify that the active workspace is the one the user intends. For single-service migrations without databases, create via MCP tools: @@ -202,6 +206,8 @@ Present the creation result (service URL, ID) when complete. ### Step 4: Migrate Environment Variables +Before inspecting or applying configuration, read [references/environment-variables.md](references/environment-variables.md) and preserve the migration-specific filtering and confirmation steps below. + #### Gather config vars Use the first available source: @@ -224,16 +230,16 @@ Present filtered list to user — **do not write without confirmation**. **Blueprint path (Step 3A):** Env vars are already embedded in the `render.yaml` on each service (non-secret values inline, secrets marked `sync: false` for the user to fill in during Blueprint apply). No separate MCP call is needed — skip to Step 5. -**MCP path (Step 3B):** Call Render `update_environment_variables` with confirmed vars (supports bulk set, merges by default). +**MCP path (Step 3B):** Inspect the current `update_environment_variables` operation, confirm whether it patches or replaces the collection, and apply only the confirmed variables while preserving unrelated keys. ### Step 5: Data Migration -Follow the [data migration guide](references/data-migration.md) to migrate Postgres and Redis data. The guide covers sub-steps 5a through 5e in detail. Summary of the flow: +Follow the [data migration guide](references/data-migration.md) to migrate Postgres and Key Value data. The guide covers sub-steps 5a through 5e in detail. Summary of the flow: 1. **Pre-migration checks** — confirm Render resources are provisioned via `list_postgres_instances()` and `list_key_value()`, check source DB size, verify Render CLI (`render --version`), `pg_dump`, and `pg_restore` are installed 2. **Gather connection strings** — Heroku Postgres via `pg_credentials` (MCP) or user CLI paste. For Key Value, construct a Dashboard deeplink from the ID. 3. **Postgres migration** — two approaches based on size: **under 2 GB** uses `render psql` (no Render connection string needed); **2-50 GB** uses `pg_dump -Fc` + `pg_restore` with external connection string from Dashboard (faster, compressed, parallel restore). -4. **Key Value / Redis** — usually skip (ephemeral cache). If persistent data, use `redis-cli` dump/restore with Dashboard-provided Render URL. +4. **Key Value** — usually skip (ephemeral cache). If persistent data, use `redis-cli` dump/restore with Dashboard-provided Render URL. 5. **Data validation** — verify schema and row counts via `query_render_postgres`, compare against Heroku source if MCP is available. ### Step 6: Verify Migration @@ -298,7 +304,7 @@ Instruct user to: If the migration fails at any point: - **Services created but not working**: Services can be deleted from the Render dashboard (MCP server intentionally does not support deletion). Heroku app is untouched until maintenance mode is enabled. -- **Env vars wrong**: Call `update_environment_variables` with `replace: true` to overwrite, or fix individual vars. +- **Env vars wrong**: Follow [references/environment-variables.md](references/environment-variables.md), inspect the current update operation's patch-or-replace behavior, and correct only the intended keys. - **Database migration failed**: Render Postgres can be deleted and recreated. Heroku database is read-only during dump (no data loss). If `maintenance_off` is called on Heroku, the original app is fully operational again. - **DNS already changed**: Revert CNAME to Heroku and disable maintenance mode on Heroku. @@ -310,3 +316,16 @@ Key principle: **Heroku stays fully functional until the user explicitly cuts ov - Env var migration partially fails: show which succeeded/failed - Heroku auth errors: instruct `heroku login` or check `HEROKU_API_KEY` - Render auth errors: check Render API key in MCP config + + +## Current documentation retrieval + +Whenever this skill directs you to consult current Render documentation: + +1. Retrieve the linked Markdown document directly with an available URL-fetching tool or HTTP client, such as `curl`. Do not substitute web-search summaries for the document. +2. Confirm that retrieval succeeded and returned the expected document, then read its contents. Saving a file or printing its path is not sufficient. +3. If the request fails or your tool cannot read the Markdown response, open and read the linked HTML version instead. +4. If neither version can be retrieved, disclose that the current reference is unavailable and follow any topic-specific fallback in the skill. Use bundled guidance only for stable constraints, and do not guess at changeable platform details. + +When a task requires multiple references, apply this workflow to each one and distinguish the documents you verified from those that remain unavailable. + diff --git a/skills/render-migrate-from-heroku/references/blueprint-example.md b/skills/render-migrate-from-heroku/references/blueprint-example.md index fc6b993..d97fb0f 100644 --- a/skills/render-migrate-from-heroku/references/blueprint-example.md +++ b/skills/render-migrate-from-heroku/references/blueprint-example.md @@ -1,8 +1,8 @@ # Blueprint Example: Heroku Migration with Project/Environment Pattern -This example shows a complete `render.yaml` for migrating a typical Heroku app with a web dyno, worker dyno, Heroku Scheduler (clock), Postgres, and Redis. It uses the `projects`/`environments` pattern to group all resources in a single Render project. +This example shows a complete `render.yaml` for migrating a typical Heroku app with a web dyno, worker dyno, Heroku Scheduler (clock), Postgres, and Key Value. It uses the `projects`/`environments` pattern to group all resources in a single Render project. -References: [Blueprint docs](https://render.com/docs/blueprint-spec#projects-and-environments) | [Blueprint YAML JSON schema](https://render.com/schema/render.yaml.json) +For current Blueprint syntax and validation, first read [blueprints.md](blueprints.md). This document adds migration-specific structure and rules. ## Full Example @@ -90,13 +90,12 @@ projects: - key: STRIPE_API_KEY sync: false - # Key Value (from Heroku Data for Redis) + # Key Value (from Heroku Key-Value Store) - type: keyvalue name: acme-app-cache plan: starter - ipAllowList: - - source: 0.0.0.0/0 - description: everywhere + maxmemoryPolicy: noeviction + ipAllowList: [] # Internal access only; temporarily allow the migration host for a Key Value import databases: # Postgres (from Heroku Postgres) @@ -119,7 +118,7 @@ Use `fromDatabase` and `fromService` instead of hardcoding connection strings: name: acme-app-db property: connectionString -# Key Value (Redis) connection string +# Key Value connection string - key: REDIS_URL fromService: type: keyvalue @@ -175,7 +174,7 @@ Set every `plan:` field by looking up the Heroku dyno size or add-on plan in the - **Ruby app:** Change to `runtime: ruby`, update commands (e.g., `bundle install`, `bundle exec puma`) - **No worker:** Remove the `type: worker` service block - **No cron:** Remove the `type: cron` service block -- **No Redis:** Remove the `type: keyvalue` service block and any `REDIS_URL` env var references +- **No Key Value:** Remove the `type: keyvalue` service block and any `REDIS_URL` env var references - **No Postgres:** Remove the `databases` section and any `DATABASE_URL` env var references - **Static site:** Replace `type: web` with `runtime: static` and add `staticPublishPath` - **EU region:** Change `region: oregon` to `region: frankfurt` (maps from Heroku `eu` region) diff --git a/skills/render-migrate-from-heroku/references/blueprints.md b/skills/render-migrate-from-heroku/references/blueprints.md new file mode 100644 index 0000000..35a7b23 --- /dev/null +++ b/skills/render-migrate-from-heroku/references/blueprints.md @@ -0,0 +1,31 @@ + +## Render Blueprints + +A Render Blueprint is a declarative YAML definition of interconnected Render services, databases, and environment groups. The file is usually named `render.yaml` and stored at the root of a Git repository, although its path can be customized when the Blueprint is created. + +Blueprint creation and sync read the file from the linked remote Git repository. Local edits are not available to Render until they are committed and pushed to that repository. + +Do not rely on remembered Blueprint fields, allowed values, defaults, or update behavior. Before creating or modifying a Blueprint, use the documentation-retrieval workflow in the root `SKILL.md` to retrieve and read the [Markdown reference](https://render.com/docs/blueprint-spec.md) or its [HTML version](https://render.com/docs/blueprint-spec). + +If neither version can be retrieved, use the current JSON Schema and Render validation where possible. Use the bundled guidance only for stable workflow and safety constraints, and do not guess at unfamiliar or potentially changed syntax. + +Read the sections relevant to every resource and field being changed. In particular, confirm required fields, service-type support, immutable fields, defaults for new resources, behavior for existing resources, and whether omitting or emptying a field preserves or removes existing configuration. Do not treat an example Blueprint as a complete specification. + +Use the public JSON Schema for editor or programmatic validation: + +```text +https://render.com/schema/render.yaml.json +``` + +When Render CLI v2.7.0 or later is available, validate the finished file: + +```bash +render blueprints validate render.yaml +``` + +Fix validation errors before presenting the Blueprint as ready to deploy. Validation does not apply, sync, or deploy the Blueprint. Schema validation checks structure; Render CLI or API validation can also catch platform-aware errors. If copied examples, the schema, and Render validation disagree, prefer the configuration accepted by current Render validation and call out the discrepancy. + +Blueprint resource names are used to associate definitions with existing resources. Before reusing or changing a name, verify that the Blueprint will manage the intended resource. Do not define the same resource in more than one location, such as both a root-level list and a project environment or `ungrouped`. + +Treat edits to an existing Blueprint as infrastructure changes, not ordinary text edits. Review the proposed diff for replacements, removals, immutable-field changes, and destructive declarative behavior before applying or recommending a sync. Never hardcode secret values in a Blueprint; consult the current environment-variable sections of the specification for supported secret mechanisms and their limitations. + diff --git a/skills/render-migrate-from-heroku/references/buildpack-mapping.md b/skills/render-migrate-from-heroku/references/buildpack-mapping.md index 7b552e3..7d426cc 100644 --- a/skills/render-migrate-from-heroku/references/buildpack-mapping.md +++ b/skills/render-migrate-from-heroku/references/buildpack-mapping.md @@ -121,10 +121,11 @@ Do not assume or fabricate specific runtime versions for Render. Instead, carry | `runtime.txt` | `python-3.11.6` | Set `PYTHON_VERSION=3.11.6` env var | | `runtime.txt` | `ruby-3.2.2` | Render auto-detects from `ruby-3.2.2` in `Gemfile` | | `.node-version` or `engines` in `package.json` | `18.17.0` | Set `NODE_VERSION=18.17.0` env var | -| `.go-version` or `go.mod` | `1.21` | Render auto-detects from `go.mod` | +| `.go-version` or `go.mod` | `1.21` | Native Render Go uses the latest stable Go 1.x; use Docker if this version must be pinned | **Rules:** - If the Heroku app pins a version via `runtime.txt` or similar, include the equivalent env var in the Blueprint +- Go is an exception: native Render Go does not honor a pinned runtime version from `go.mod` or `.go-version` - If no version is pinned, do not specify one — Render uses its own defaults - **Never state what Render's default version is** — it changes over time and any claim may be wrong diff --git a/skills/render-migrate-from-heroku/references/data-migration.md b/skills/render-migrate-from-heroku/references/data-migration.md index d8d7c33..e1c13fc 100644 --- a/skills/render-migrate-from-heroku/references/data-migration.md +++ b/skills/render-migrate-from-heroku/references/data-migration.md @@ -1,27 +1,16 @@ # Data Migration Guide -Detailed steps for migrating Postgres and Redis data from Heroku to Render. The Render CLI's [`render psql`](https://render.com/docs/cli) handles the Postgres restore without requiring the Render database connection string. +Detailed steps for migrating Postgres and Key Value data from Heroku to Render. Small Postgres migrations can restore through the Render CLI without a Render connection string; larger migrations use `pg_restore` with the database's external connection string. ## 5a. Pre-migration checks Before generating any migration commands, verify readiness: -1. **Render Postgres is provisioned** — call `list_postgres_instances()` to find the Postgres ID and confirm the database exists. Note the ID for `render psql` in Step 5c. -2. **Render Key Value is provisioned** (if Redis data needs migrating) — call `list_key_value()` to find the Key Value ID and confirm the instance exists. Note the ID for the Dashboard deeplink in Step 5d. +1. **Render Postgres is provisioned** — use a Postgres ID the user already supplied, or call `list_postgres_instances()` when live discovery is requested and needed. Note the ID for `render psql` or the Dashboard link in Step 5c. +2. **Render Key Value is provisioned** (if Key Value data needs migrating) — use a Key Value ID the user already supplied, or call `list_key_value()` when live discovery is requested and needed. Note the ID for the Dashboard deeplink in Step 5d. 3. **Check source database size** — use Heroku MCP `pg_info` (look for `Data Size`), or ask the user to run `heroku pg:info -a ` and paste the output. 4. **Compare disk sizes** — warn if Heroku `Data Size` exceeds the `diskSizeGB` configured on the Render side. If it does, the user needs to increase `diskSizeGB` before restoring. -5. **Render CLI** — confirm the Render CLI is installed and authenticated (required for `render psql` restore): - - ```bash - render --version - render whoami - ``` - - If not installed, offer to install it: - - macOS: `brew install render` - - Linux/macOS: `curl -fsSL https://raw.githubusercontent.com/render-oss/cli/main/bin/install.sh | sh` - - If not authenticated, run `render login` to authorize via the Dashboard. +5. **Render CLI** — required only for the under-2-GB `render psql` route. Follow [render-access.md](render-access.md) to install or authenticate it and verify the intended workspace. The traditional `pg_restore` route instead requires the Render external connection string and PostgreSQL client tools. 6. **`pg_dump` and `pg_restore`** — check that the user has PostgreSQL client tools installed locally: @@ -32,7 +21,7 @@ Before generating any migration commands, verify readiness: Both are needed: `pg_dump` for all approaches, `pg_restore` for the traditional approach (databases over 2 GB). If not installed, suggest installing PostgreSQL client tools (e.g., `brew install libpq` on macOS, `apt install postgresql-client` on Linux). -7. **Redis tools** (if migrating Redis data) — check for `redis-cli`: +7. **Key Value tools** (if migrating Key Value data) — check for `redis-cli`: ```bash redis-cli --version @@ -40,7 +29,7 @@ Before generating any migration commands, verify readiness: ## 5b. Gather connection strings -Collect the connection strings needed for the migration. The **Render Postgres** connection string is **not needed** — the Render CLI's `render psql` command connects directly using the Postgres ID from Step 5a. Only the Heroku source URLs and the Render Key Value URL (if applicable) are needed. +Collect the connection strings needed for the chosen route. The under-2-GB `render psql` route connects by Postgres ID and does not need a Render Postgres connection string. The traditional 2–50-GB route requires the Render external connection string. A Render Key Value URL is needed only when Key Value data is being migrated. **Heroku Postgres:** @@ -54,7 +43,7 @@ pg_credentials(app: "") If Heroku MCP is not available, ask the user to run `heroku pg:credentials:url DATABASE -a ` and paste the connection URL. -**Render Key Value** (if migrating Redis data): +**Render Key Value** (if migrating Key Value data): The Render MCP does not return Key Value connection strings. Use the Key Value ID from Step 5a to construct a Dashboard deeplink and ask the user to copy the external connection URL: @@ -64,7 +53,17 @@ Dashboard link: https://dashboard.render.com/d/ → store as RENDER_REDIS_URL ``` -**Heroku Redis** (if migrating Redis data): +If the Blueprint configures `ipAllowList: []` for internal-only access, temporarily allow the migration machine's public IPv4 address before running the import: + +```yaml +ipAllowList: + - source: /32 + description: temporary Key Value migration access +``` + +Remove that entry and restore `ipAllowList: []` after validating the migration. + +**Heroku Key-Value Store** (if migrating Key Value data): If Heroku MCP is available: @@ -138,23 +137,23 @@ Replace `` with the actual Heroku connection string from Step 5b, Remind the user to schedule a maintenance window. The app will be unavailable on Heroku from maintenance mode until DNS cutover to Render. -## 5d. Key Value / Redis migration +## 5d. Key Value migration -Most Heroku Redis instances are used as ephemeral caches and do not need data migration. Ask the user before proceeding: +Most Heroku Key-Value Store instances are used as ephemeral caches and do not need data migration. Ask the user before proceeding: - **Ephemeral cache** (most common) — skip migration. The app will repopulate the cache after deployment on Render. No action needed. -- **Persistent data** — if the user confirms Redis holds persistent data (e.g., session store, queues, application state), generate migration commands using the connection strings from Step 5b: +- **Persistent data** — if the user confirms Key Value holds persistent data (e.g., session store, queues, application state), generate migration commands using the connection strings from Step 5b: ```bash - # Dump from Heroku Redis + # Dump from Heroku Key-Value Store redis-cli -u --rdb heroku_dump.rdb # Restore to Render Key Value (requires redis-cli 5.0+) redis-cli -u --pipe < heroku_dump.rdb ``` - Replace `` with the Heroku Redis URL and `` with the Render Key Value External Access URL, both from Step 5b. Present ready-to-run commands with the real values. + Replace `` with the Heroku Key-Value Store URL and `` with the Render Key Value External Access URL, both from Step 5b. Present ready-to-run commands with the real values. - Note: RDB dump/restore may not be supported on all Heroku Redis plans. If it fails, the alternative is per-key `DUMP`/`RESTORE` or having the application re-seed the data. + Note: RDB dump/restore may not be supported on all Heroku Key-Value Store plans. If it fails, the alternative is per-key `DUMP`/`RESTORE` or having the application re-seed the data. ## 5e. Data validation diff --git a/skills/render-migrate-from-heroku/references/environment-variables.md b/skills/render-migrate-from-heroku/references/environment-variables.md new file mode 100644 index 0000000..e9de03c --- /dev/null +++ b/skills/render-migrate-from-heroku/references/environment-variables.md @@ -0,0 +1,38 @@ + +## Environment variables and secrets + +Render environment-variable values are strings. Applications must explicitly parse values that represent booleans, numbers, lists, or structured data; for example, the string `"false"` is truthy in many languages. + +Environment variables can be managed through the Render Dashboard, Blueprints, environment groups, and supported API, MCP, or CLI operations. Before changing a service, determine which mechanism is intended to be the source of truth. Do not make parallel Dashboard and infrastructure-as-code edits without explaining how future syncs or deploys will reconcile them. + +Never commit secret values to application source, `render.yaml`, checked-in `.env` files, fixtures, examples, or logs. Keep local secret-bearing `.env` files out of version control. Do not print or repeat secret values returned by the user, Render, or another provider. Use Render's supported secret mechanisms or an external secret manager appropriate to the user's workflow. + +Before configuring environment variables, secret files, or environment groups, fetch the current Render configuration reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/configure-environment-variables.md) or its [HTML version](https://render.com/docs/configure-environment-variables). + +Read the sections relevant to the configuration surface being used. Dashboard save options can rebuild and deploy, deploy the existing build, or save without deploying; do not assume a changed value is active until the applicable deploy occurs. + +For Blueprint-managed variables, also consult the current Blueprint YAML reference before writing syntax or predicting update behavior. In particular: + +- Use literal `value` entries only for non-sensitive configuration. +- `generateValue: true` creates a platform-generated secret when the variable does not already exist. +- `sync: false` prompts for a value only during initial Blueprint creation. It is ignored for existing services during later Blueprint updates, is not included in preview environments, and is not valid in environment groups. +- Use current `fromDatabase`, `fromService`, and `fromGroup` syntax instead of hardcoding connection strings or copying shared values. + +Blueprint syncs preserve existing service environment variables that are omitted from the Blueprint; omission does not delete them. Values defined with `fromDatabase` or `fromService` refresh on each Blueprint sync, not immediately when the referenced property or variable changes. + +Environment groups provide shared variables and secret files to linked services. A variable defined directly on a service takes precedence over the same key from a linked group. Precedence between multiple linked groups with the same key is not guaranteed; avoid collisions instead of depending on group creation order. Respect project-environment scoping when linking groups to services. + +Use secret files for credentials or configuration that must be read from the filesystem rather than an environment variable. Confirm current size and runtime-path rules in the fetched reference. Treat secret-file contents with the same precautions as other credentials. + +Render also injects documented default environment variables. Do not maintain a memorized catalog. Fetch the current default-variable reference when a task depends on a variable's name, availability, build/runtime scope, or semantics: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/environment-variables.md) or its [HTML version](https://render.com/docs/environment-variables). + +Depend only on documented platform variables. Other `RENDER_*` variables are internal and can change without notice. + +Treat environment-variable changes as service configuration mutations. Confirm the target workspace and service, inspect the existing keys without exposing their values, and preserve variables outside the user's requested scope. Before using an API, MCP, or CLI operation, check whether it patches individual keys or replaces the complete collection. After the applicable deploy, verify that required keys are present and that the service starts successfully without logging secret values. + +If the current references or live configuration cannot be inspected, do not guess at secret behavior, precedence, or replacement semantics. Preserve existing configuration where possible and explain what must be confirmed before making the change. + diff --git a/skills/render-migrate-from-heroku/references/mcp-setup.md b/skills/render-migrate-from-heroku/references/mcp-setup.md index 12077de..0a100cf 100644 --- a/skills/render-migrate-from-heroku/references/mcp-setup.md +++ b/skills/render-migrate-from-heroku/references/mcp-setup.md @@ -4,76 +4,7 @@ The Render MCP server is recommended for direct service creation and automated v ## Render MCP Server (Recommended) -Hosted at `https://mcp.render.com/mcp` (recommended, auto-updates). The Render plugin (Cursor, Codex, Claude Code) connects to this server over OAuth with a pre-registered client id — no API key needed. Manual MCP clients can still use a Render API key from [Account Settings](https://dashboard.render.com/u/*/settings#api-keys). - -Alternative: run locally via Docker or binary (see [Render MCP docs](https://render.com/docs/mcp-server)). -Source: [render-mcp-server](https://github.com/render-oss/render-mcp-server) - -**Detecting the user's tool:** Infer the AI tool from this skill's install path (`~/.cursor/skills/` = Cursor, `~/.claude/skills/` = Claude Code, `~/.codex/skills/` = Codex). If the path doesn't match a known tool, ask the user which tool they're using, then follow the matching section below. - -### Render plugin (recommended) - -If the Render plugin is installed for your tool, it already declares this MCP server with a pre-registered OAuth client id. Reload the tool (restart Cursor or Claude Code, or start a new Codex thread), complete the Render OAuth prompt when asked, then retry `list_services()`. The manual, API-key setups below are for tools without the plugin. - -### Cursor - -1. Get a Render API key: -``` -https://dashboard.render.com/u/*/settings#api-keys -``` - -2. Add this to `~/.cursor/mcp.json` (replace ``): -```json -{ - "mcpServers": { - "render": { - "url": "https://mcp.render.com/mcp", - "headers": { - "Authorization": "Bearer " - } - } - } -} -``` - -3. Restart Cursor, then retry `list_services()`. - -### Claude Code - -1. Get a Render API key: -``` -https://dashboard.render.com/u/*/settings#api-keys -``` - -2. Add the MCP server with Claude Code (replace ``): -```bash -claude mcp add --transport http render https://mcp.render.com/mcp --header "Authorization: Bearer " -``` - -3. Restart Claude Code, then retry `list_services()`. - -### Codex - -1. Get a Render API key: -``` -https://dashboard.render.com/u/*/settings#api-keys -``` - -2. Set it in your shell: -```bash -export RENDER_API_KEY="" -``` - -3. Add the MCP server with the Codex CLI: -```bash -codex mcp add render --url https://mcp.render.com/mcp --bearer-token-env-var RENDER_API_KEY -``` - -4. Restart Codex, then retry `list_services()`. - -### Other Tools - -If using another AI tool, direct the user to the [Render MCP docs](https://render.com/docs/mcp-server) for that tool's setup steps and install method. +Follow [render-access.md](render-access.md) for the current hosted server, client setup, authentication, workspace selection, capability discovery, and fallback workflow. Verify Render access with a read-only operation before starting the migration. ## Heroku MCP Server (Optional) @@ -103,4 +34,4 @@ After configuring, test your connections: - Ask: "List my Render services" — should return services via Render MCP (required) - Ask: "List my Heroku apps" — should return apps via Heroku MCP (optional) -If Render MCP fails, reinstall or update the Render plugin and reload the tool (plugin setup), or check your API key and restart your MCP client (manual setup). If Heroku MCP is not configured, the migration skill still works — it reads local project files and asks you to provide config var values manually. +If Render MCP fails, troubleshoot it through [render-access.md](render-access.md). If Heroku MCP is not configured, the migration skill still works—it reads local project files and asks you to provide config var values manually. diff --git a/skills/render-migrate-from-heroku/references/preflight-checklist.md b/skills/render-migrate-from-heroku/references/preflight-checklist.md index aad7008..19c00c7 100644 --- a/skills/render-migrate-from-heroku/references/preflight-checklist.md +++ b/skills/render-migrate-from-heroku/references/preflight-checklist.md @@ -39,18 +39,20 @@ MIGRATION PLAN — [app-name] ───────────────────────────────── CREATE (include only items that apply): ✅ Web service ([runtime], [mapped-plan]) — startCommand: [cmd] - Heroku: [dyno-size] ($X/mo) → Render: [mapped-plan] ($Y/mo) + Heroku: [dyno-size] → Render: [mapped-plan] ✅ Background worker ([runtime], [mapped-plan]) — startCommand: [cmd] - Heroku: [dyno-size] ($X/mo) → Render: [mapped-plan] ($Y/mo) + Heroku: [dyno-size] → Render: [mapped-plan] ✅ Cron job ([mapped-plan]) — schedule: [cron expr] — command: [cmd] ✅ Postgres ([mapped-plan], diskSizeGB: [size]) - Heroku: [plan-slug] ($X/mo) → Render: [mapped-plan] ($Y/mo + storage) + Heroku: [plan-slug] → Render: [mapped-plan] + separately billed storage ✅ Key Value ([mapped-plan]) - Heroku: [plan-slug] ($X/mo) → Render: [mapped-plan] ($Y/mo) + Heroku: [plan-slug] → Render: [mapped-plan] -ESTIMATED MONTHLY COST: - Heroku: $[total]/mo → Render: $[total]/mo - (Render storage billed separately at $0.30/GB/mo in 5 GB increments; cannot be scaled down once provisioned) +COST REVIEW: + Render compute, database storage, HA, Key Value, cron jobs, bandwidth, and + custom domains can incur charges. Confirm current details at + https://render.com/pricing before proceeding. Database storage cannot be + scaled down once provisioned. METHOD: [Blueprint | MCP Direct Creation] @@ -64,6 +66,6 @@ DATABASE: [size] — pg_dump/render psql required Proceed? (y/n) ``` -Use the pricing columns in the [service mapping](service-mapping.md) to calculate costs. Sum up the Render $/mo for each service, database, and Key Value store. For Postgres, note that storage is billed separately. +Do not calculate costs from hard-coded rates. Identify the resources and add-ons that incur charges, then have the user confirm current details at [Render pricing](https://render.com/pricing). Call out that Postgres storage and HA are billed separately from the primary instance. Wait for user confirmation before creating any resources. diff --git a/skills/render-migrate-from-heroku/references/render-access.md b/skills/render-migrate-from-heroku/references/render-access.md new file mode 100644 index 0000000..864c854 --- /dev/null +++ b/skills/render-migrate-from-heroku/references/render-access.md @@ -0,0 +1,50 @@ + +## Accessing Render + +Prefer the hosted Render MCP server for structured access to Render resources when its tools are available. Use the Render CLI when MCP is unavailable or does not support the required operation, and use the Render Dashboard or API for capabilities exposed by neither. Do not assume that a remembered MCP tool or CLI command is still available; inspect the tools in the current environment or consult the current documentation. + +The hosted Render MCP server uses streamable HTTP at: + +```text +https://mcp.render.com/mcp +``` + +Official Render plugins and connectors can authenticate MCP with browser-based OAuth. Manual and non-interactive configurations can use a Render API key as a bearer token. Never write an API key or OAuth token into a repository, skill, command output, chat response, or log. Prefer the client's supported secret storage or environment-variable mechanism. If a client requires a credential in local configuration, keep that file out of version control and restrict access to it. + +Treat MCP responses as potentially sensitive even when the server attempts to minimize credential exposure. Request connection strings, credentials, secret environment variables, or other sensitive fields only when the task requires them. Do not repeat sensitive values in the response or persist them in files or logs. + +Before configuring or troubleshooting MCP, fetch the current setup and capability reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/mcp-server.md) or its [HTML version](https://render.com/docs/mcp-server). + +Read the relevant client setup, supported-actions, and limitations sections. Prefer the hosted server unless the user's environment requires a local MCP server. After installing, updating, or reconfiguring an MCP integration, reload the client as required and verify the connection with a read-only operation such as listing services. + +Most MCP operations and Render CLI commands that access Render resources are scoped to an active workspace. Check the selected workspace before reading or changing resources. If no workspace is selected—or if the intended workspace is ambiguous—list the available workspaces and have the user identify the correct one. Do not silently switch workspace context or infer it from a resource name. Commands for authentication, help, CLI configuration, and workspace discovery or selection do not require an already selected workspace. + +For interactive CLI use, authenticate with `render login`. For automation, use a securely stored `RENDER_API_KEY`; an API key takes precedence over a saved CLI token. Verify CLI access and the active workspace with read-only commands before operating on resources: + +```bash +render whoami --output json +render workspace current --output json +``` + +For CLI installation, authentication, workspace setup, and usage patterns, fetch the current CLI overview: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/cli.md) or its [HTML version](https://render.com/docs/cli). + +For exact command syntax and flags, prefer the help text from the installed CLI because it matches the version being used: + +```bash +render help +``` + +The published CLI command reference is generated automatically from the CLI's help text. Use it to browse the full command surface or when the CLI is not installed: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/cli-reference.md) or its [HTML version](https://render.com/docs/cli-reference). + +When an agent or automation invokes the CLI, select a non-interactive output format such as `--output json`, `--output yaml`, or `--output text` so results can be inspected reliably. The global `--confirm` flag skips confirmation prompts; use it for a mutating command only after that mutation is authorized. It is an execution convenience, not permission to perform the action. + +Authentication establishes access; it does not establish user authorization for every available action. Use read-only discovery to resolve workspace, resource identity, and current state before a mutation. Perform changes only when they are within the user's requested scope, and retain normal approval requirements for consequential operations such as creation, configuration changes, deploys, restarts, scaling, or deletion. + +When authentication or connectivity fails, report which access path failed, preserve the underlying error without exposing credentials, and either use an available supported fallback or explain what the user must configure before the task can continue. + diff --git a/skills/render-migrate-from-heroku/references/service-mapping.md b/skills/render-migrate-from-heroku/references/service-mapping.md index e2b3618..f5cb9a1 100644 --- a/skills/render-migrate-from-heroku/references/service-mapping.md +++ b/skills/render-migrate-from-heroku/references/service-mapping.md @@ -6,28 +6,28 @@ Look up the Heroku plan from `ps_list` (dyno size) or `list_addons` (add-on plan ## Compute (Dynos → Services) -Match by RAM to avoid out-of-memory issues. Worker and cron dynos use the same size mapping as web dynos. - -| Heroku dyno | Heroku RAM | Heroku $/mo | Render `plan` value | Render RAM | Render $/mo | -|---|---|---|---|---|---| -| Eco | 512 MB | $5 | `starter` | 512 MB | $7 | -| Basic | 512 MB | $7 | `starter` | 512 MB | $7 | -| Standard-1X | 512 MB | $25 | `starter` | 512 MB | $7 | -| Standard-2X | 1 GB | $50 | `standard` | 2 GB | $25 | -| Performance-M | 2.5 GB | $250 | `pro` | 4 GB | $85 | -| Performance-L | 14 GB | $500 | `pro max` | 16 GB | $225 | -| Performance-L-RAM | 30 GB | $500 | `pro ultra` | 32 GB | $450 | -| Performance-XL | 62 GB | $750 | Custom | 64 GB | ~$712 | -| Performance-2XL | 126 GB | $1,500 | Custom | 128 GB | ~$1,426 | +Match web and worker dynos by RAM to avoid out-of-memory issues. See the cron-specific guidance below before mapping a scheduled Heroku process. + +| Heroku dyno | Heroku RAM | Render `plan` value | Render RAM | +|---|---|---|---| +| Eco | 512 MB | `starter` | 512 MB | +| Basic | 512 MB | `starter` | 512 MB | +| Standard-1X | 512 MB | `starter` | 512 MB | +| Standard-2X | 1 GB | `standard` | 2 GB | +| Performance-M | 2.5 GB | `pro` | 4 GB | +| Performance-L | 14 GB | `pro max` | 16 GB | +| Performance-L-RAM | 30 GB | `pro ultra` | 32 GB | +| Performance-XL | 62 GB | Custom | 64 GB | +| Performance-2XL | 126 GB | Custom | 128 GB | **Fallback default:** `starter` (when Heroku dyno size is unknown) **Notes:** - Worker dynos on Heroku can be any size (Standard-1X, Performance-M, etc.) — use the same mapping based on the dyno size reported by `ps_list` -- Cron jobs use the same mapping — Render cron plans match web/worker plans -- Performance-L-RAM has 4 CPU (half of Pro Ultra's 8 CPU). For non-enterprise customers, default to `pro ultra`. Enterprise customers may negotiate custom pricing (~$356) with Render for a closer CPU match. -- For Performance-XL and Performance-2XL, instruct the user to [contact Render](https://render.com/contact) for custom sizing. The estimates above (~$712, ~$1,426) are based on proportional custom pricing and may vary. -- Enterprise contracts change per-dyno pricing — the "units per dyno" multiplier varies (e.g., Performance-M = 8 units, Performance-L = 16 units of a Standard-1X). Heroku prices above reflect pay-as-you-go rates. +- **Cron jobs:** Render cron jobs support `starter`, `standard`, `pro`, and `pro plus` only (up to 4 CPU / 8 GB RAM). Use the table for cron jobs through Performance-M. For Performance-L and larger Heroku cron dynos, there is no equivalent Render cron plan; reduce or split the job, move the scheduled work to a background worker, or contact Render about the workload. +- Performance-L-RAM has 4 CPU (half of Pro Ultra's 8 CPU). For non-enterprise customers, default to `pro ultra`; contact Render if custom sizing is required. +- For Performance-XL and Performance-2XL, instruct the user to [contact Render](https://render.com/contact) for custom sizing. +- Confirm current plan charges at [Render pricing](https://render.com/pricing); do not estimate costs from proportional sizing. ## Postgres (Heroku Postgres → Render Postgres) @@ -38,45 +38,45 @@ Render has three Postgres tiers: - **Pro** — balanced CPU-to-RAM ratio (1:4), for production workloads - **Accelerated** — memory-optimized CPU-to-RAM ratio (1:8), for high-performance and memory-intensive workloads -Map Heroku Essential → Render Basic. For Standard and Premium, both map to the **same Render plan per tier** — Standard as a single instance, Premium with HA enabled (doubling the Render cost). Tiers 0 and 2 map to Render Pro; tiers 3 through 9 map to Render Accelerated. +Map Heroku Essential → Render Basic. For Standard and Premium, both map to the **same Render plan per tier** — Standard as a single instance, Premium with HA enabled. HA adds a separately billed standby instance. Tiers 0 and 2 map to Render Pro; tiers 3 through 9 map to Render Accelerated. ### Essential and legacy plans → Render Basic -| Heroku plan | Heroku disk | Heroku $/mo | Render `plan` value | Render `diskSizeGB` | Render $/mo | -|---|---|---|---|---|---| -| Essential-0 | 1 GB | $5 | `basic-256mb` | 1 | $6 + storage | -| Essential-1 | 10 GB | $9 | `basic-256mb` | 10 | $6 + storage | -| Essential-2 | 32 GB | $20 | `basic-1gb` | 32 | $19 + storage | -| Mini (legacy, EOL) | 1 GB | $5 | `basic-256mb` | 1 | $6 + storage | -| Basic (legacy, EOL) | 10 GB | $9 | `basic-256mb` | 10 | $6 + storage | +| Heroku plan | Heroku disk | Render `plan` value | Render `diskSizeGB` | +|---|---|---|---| +| Essential-0 | 1 GB | `basic-256mb` | 1 | +| Essential-1 | 10 GB | `basic-256mb` | 10 | +| Essential-2 | 32 GB | `basic-1gb` | 35 | +| Mini (legacy, EOL) | 1 GB | `basic-256mb` | 1 | +| Basic (legacy, EOL) | 10 GB | `basic-256mb` | 10 | ### Standard and Premium plans → Render Pro / Accelerated -Heroku Standard and Premium share the same tier numbering (X-0 through X-9) with identical vCPU, RAM, and storage specs. The difference is that **Premium includes HA by default**. On Render, both map to the same plan — enable HA on Render to match Premium (which doubles the Render base price for a separate replica). +Heroku Standard and Premium share the same tier numbering (X-0 through X-9) with identical vCPU, RAM, and storage specs. The difference is that **Premium includes HA by default**. On Render, both map to the same plan—enable HA on Render to match Premium. The standby instance adds cost. -| Heroku tier | Heroku Standard $/mo | Heroku Premium $/mo | vCPU | RAM | Storage | Render `plan` value | Render `diskSizeGB` | Render $/mo | Render HA $/mo | -|---|---|---|---|---|---|---|---|---|---| -| X-0 | $50 | $200 | 2 | 4 GB | 64 GB | `pro-4gb` | 65 | $55 + storage | $110 + storage | -| X-2 | $200 | $350 | 2 | 8 GB | 256 GB | `pro-8gb` | 256 | $100 + storage | $200 + storage | -| X-3 | $400 | $750 | 2 | 15 GB | 512 GB | `accelerated-16gb` | 512 | $160 + storage | $320 + storage | -| X-4 | $750 | $1,200 | 4 | 30 GB | 768 GB | `accelerated-32gb` | 770 | $350 + storage | $700 + storage | -| X-5 | $1,400 | $2,500 | 8 | 61 GB | 1 TB | `accelerated-64gb` | 1024 | $750 + storage | $1,500 + storage | -| X-6 | $2,000 | $3,500 | 16 | 122 GB | 1.5 TB | `accelerated-128gb` | 1536 | $1,500 + storage | $3,000 + storage | -| X-7 | $3,500 | $6,000 | 32 | 244 GB | 2 TB | `accelerated-256gb` | 2048 | $2,500 + storage | $5,000 + storage | -| X-8 | $4,500 | $8,500 | 64 | 488 GB | 3 TB | `accelerated-512gb` | 3072 | $6,000 + storage | $12,000 + storage | -| X-9 | $5,800 | $11,000 | 96 | 768 GB | 4 TB | `accelerated-768gb` | 4096 | $9,000 + storage | $18,000 + storage | +| Heroku tier | vCPU | RAM | Storage | Render `plan` value | Render `diskSizeGB` | +|---|---|---|---|---|---| +| X-0 | 2 | 4 GB | 64 GB | `pro-4gb` | 65 | +| X-2 | 2 | 8 GB | 256 GB | `pro-8gb` | 260 | +| X-3 | 2 | 15 GB | 512 GB | `accelerated-16gb` | 515 | +| X-4 | 4 | 30 GB | 768 GB | `accelerated-32gb` | 770 | +| X-5 | 8 | 61 GB | 1 TB | `accelerated-64gb` | 1025 | +| X-6 | 16 | 122 GB | 1.5 TB | `accelerated-128gb` | 1540 | +| X-7 | 32 | 244 GB | 2 TB | `accelerated-256gb` | 2050 | +| X-8 | 64 | 488 GB | 3 TB | `accelerated-512gb` | 3075 | +| X-9 | 96 | 768 GB | 4 TB | `accelerated-768gb` | 4100 | **How to read the tier number:** The add-on plan slug from `list_addons` looks like `heroku-postgresql:standard-0` or `heroku-postgresql:premium-4` — the number after the hyphen is the tier (X-0, X-4, etc.). Both Standard-4 and Premium-4 map to the same Render plan (`accelerated-32gb`); Premium just needs HA enabled. -**HA pricing note:** Heroku Premium pricing includes HA by default. To match this on Render, enable HA in the Dashboard or Blueprint, which adds a standby replica at the same cost as the primary (effectively 2x). This significantly impacts pricing competitiveness on larger instances — present both the single-instance and HA costs to the user so they can make an informed decision. +**HA cost note:** Heroku Premium includes HA by default. To match this on Render, enable HA in the Dashboard or Blueprint. The standby is billed separately, so call out the additional cost and confirm current details at [Render pricing](https://render.com/pricing). ### Disk sizing -On Render, storage is billed separately at **$0.30/GB/month** and configured via the `diskSizeGB` field in the Blueprint. Storage is provisioned in **5 GB increments** (minimum 1 GB) and **cannot be scaled down** once provisioned. +On Render, storage is billed separately from compute and configured with `diskSizeGB` in the Blueprint. Storage is provisioned in **5 GB increments** (minimum 1 GB) and **cannot be scaled down** once provisioned. Confirm current storage charges at [Render pricing](https://render.com/pricing). **Heuristic:** Carry over the Heroku disk size as the `diskSizeGB` value. Since `diskSizeGB` must be 1 or a multiple of 5, round up to the nearest valid value. -**Disclaimer to present to the user:** Heroku bundles a fixed storage allocation with each plan (e.g., Standard-4 includes 768 GB). On Render, compute and storage are billed separately — compute is the plan price above, and storage is $0.30/GB/month in 5 GB increments. Storage cannot be scaled down once provisioned, so right-size based on actual usage rather than the Heroku allocation. Check your current disk usage with `heroku pg:info` (look for `Data Size`) — if your actual data is much smaller than the allocated disk, start with a smaller `diskSizeGB` to save on storage costs. You can always expand later from the Render Dashboard. +**Disclaimer to present to the user:** Heroku bundles a fixed storage allocation with each plan. On Render, compute and storage are billed separately. Storage cannot be scaled down once provisioned, so right-size based on actual usage rather than the Heroku allocation. Check current usage with `heroku pg:info` (look for `Data Size`). If actual data is much smaller than the allocated disk, start with a smaller `diskSizeGB`; you can expand later from the Render Dashboard. Confirm current charges at [Render pricing](https://render.com/pricing). **Fallback default:** `basic-1gb` with no `diskSizeGB` (when Heroku Postgres plan is unknown — Render uses a default disk size) @@ -85,31 +85,31 @@ On Render, storage is billed separately at **$0.30/GB/month** and configured via - For databases beyond tier X-9, contact Render support - Get actual disk usage from `pg_info` (`Data Size` field) to inform the `diskSizeGB` recommendation -## Key Value (Heroku Redis / Key-Value Store → Render Key Value) - -Heroku has rebranded Redis as "Key-Value Store" (Valkey-based). Heroku Redis plans use non-sequential numbering (0, 1, 2, 3, 5, 7, 9, 10, 12, 14). Match by the exact plan number from `list_addons`. +## Key Value (Heroku Key-Value Store → Render Key Value) -| Heroku plan | Heroku memory | Heroku connections | Heroku $/mo | Render `plan` value | Render RAM | Render connections | Render $/mo | -|---|---|---|---|---|---|---|---| -| Mini | 25 MB | 20 | $3 | `free` | 25 MB | 50 | $0 | -| Premium-0 | 50 MB | 40 | $15 | `starter` | 256 MB | 250 | $10 | -| Premium-1 | 100 MB | 80 | $30 | `starter` | 256 MB | 250 | $10 | -| Premium-2 | 250 MB | 200 | $60 | `starter` | 256 MB | 250 | $10 | -| Premium-3 | 500 MB | 400 | $120 | `standard` | 1 GB | 1,000 | $32 | -| Premium-5 | 1 GB | 1,000 | $200 | `standard` | 1 GB | 1,000 | $32 | -| Premium-7 | 7 GB | 10,000 | $750 | `pro plus` | 10 GB | 10,000 | $250 | -| Premium-9 | 10 GB | 25,000 | $1,450 | `pro max` | 20 GB | 20,000 | $550 | -| Premium-10 | 25 GB | 40,000 | $3,500 | Custom | — | — | Contact Render | -| Premium-12 | 50 GB | 65,000 | $6,500 | Custom | — | — | Contact Render | -| Premium-14 | 100 GB | 65,000 | $12,500 | Custom | — | — | Contact Render | +Heroku's Key-Value Store is Valkey-based. Its plans use non-sequential numbering (0, 1, 2, 3, 5, 7, 9, 10, 12, 14). Match by the exact plan number from `list_addons`. -**Fallback default:** `starter` (when Heroku Redis plan is unknown) +| Heroku plan | Heroku memory | Heroku connections | Render `plan` value | Render RAM | Render connections | +|---|---|---|---|---|---| +| Mini | 25 MB | 20 | `free` | 25 MB | 50 | +| Premium-0 | 50 MB | 40 | `starter` | 256 MB | 250 | +| Premium-1 | 100 MB | 80 | `starter` | 256 MB | 250 | +| Premium-2 | 250 MB | 200 | `starter` | 256 MB | 250 | +| Premium-3 | 500 MB | 400 | `standard` | 1 GB | 1,000 | +| Premium-5 | 1 GB | 1,000 | `standard` | 1 GB | 1,000 | +| Premium-7 | 7 GB | 10,000 | `pro plus` | 10 GB | 10,000 | +| Premium-9 | 10 GB | 25,000 | `pro max` | 20 GB | 20,000 | +| Premium-10 | 25 GB | 40,000 | Custom | — | — | +| Premium-12 | 50 GB | 65,000 | Custom | — | — | +| Premium-14 | 100 GB | 65,000 | Custom | — | — | + +**Fallback default:** `starter` (when the Heroku Key-Value Store plan is unknown) **Notes:** -- Redis pricing heavily favors Render — most tiers cost significantly less on Render than the Heroku equivalent. +- Confirm current Key Value charges at [Render pricing](https://render.com/pricing); do not infer savings from historical plan prices. - The add-on plan slug from `list_addons` looks like `heroku-redis:mini` or `heroku-redis:premium-0` — use the part after the colon to look up the mapping. Plans 4, 6, 8, 11, and 13 do not exist on Heroku. - Render Key Value requires `ipAllowList` in the Blueprint (use `0.0.0.0/0` for public access) -- Neither Heroku nor Render supports Redis HA. +- Neither Heroku nor Render supports Key Value high availability. - For Premium-10 and above, instruct the user to [contact Render](https://render.com/contact) for custom sizing. ## Runtime Mapping @@ -142,7 +142,7 @@ These Heroku features require manual alternatives on Render: - **Private Spaces** → Contact Render for private networking options - **Heroku Kafka** → Not supported on Render. Recommend cloud providers (Confluent Cloud, AWS MSK, etc.) - **Hirefire** → Not supported on Render. Recommend Render's native [horizontal autoscaling](https://render.com/docs/scaling) or JudoScale (which is supported). -- **Bandwidth** → Heroku allows ~2 TB/app/month (rarely enforced). Render bandwidth varies by workspace plan: 100 GB (Hobby), 500 GB (Professional), 1 TB (Organization). Additional bandwidth is billed at $0.10/GB. +- **Bandwidth** → Render workspace plans include an outbound-bandwidth allowance. Usage beyond that allowance incurs an additional cost. Confirm current allowances and charges at [Render pricing](https://render.com/pricing) or in the Dashboard. ## Environment Variables to Filter diff --git a/skills/render-migrate-from-heroku/references/service-types.md b/skills/render-migrate-from-heroku/references/service-types.md new file mode 100644 index 0000000..a0a3786 --- /dev/null +++ b/skills/render-migrate-from-heroku/references/service-types.md @@ -0,0 +1,37 @@ + +## Render service types + +Use this guidance when selecting or comparing Render service types, or when a task's architecture depends on the distinction between them. A task that is already unambiguously scoped to one service type does not need this entire overview. + +On Render, a service represents code deployed for a particular execution model. Render runs that service on one or more instances, and the service's compute plan determines the CPU and memory available to each instance. + +Before choosing a service type, fetch the current service-types reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/service-types.md) or its [HTML version](https://render.com/docs/service-types). + +If neither version can be retrieved, use the bundled overview below only for basic service-type selection. State that current platform details could not be verified, and do not guess about changeable capabilities such as supported runtimes, plans, scaling, networking, disks, health checks, deployment behavior, availability, or limits. + +Render provides six public service types for running code: + +- **Web service:** A continuously running server that receives public HTTP traffic and also has an internal hostname for private-network traffic. Use it for dynamic websites, APIs, and other internet-facing server applications. +- **Static site:** Built HTML, CSS, JavaScript, and other static assets served publicly from Render's global CDN. Use it only when the deployed application does not require server-side runtime logic. +- **Private service:** A continuously running server that receives traffic only over Render's private network. Use it for internal HTTP, TCP, gRPC, or other server processes that need an internal hostname but no public URL. +- **Background worker:** A continuously running process that does not receive incoming traffic or expose a public or internal hostname. Use it for queue consumers and other processes that pull or poll for work. +- **Cron job:** A command or process that starts on a schedule, performs a bounded unit of work, and exits. Use it for straightforward recurring tasks rather than an always-running process. +- **Workflow:** A collection of on-demand tasks executed across distributed compute, with Render handling task queuing, orchestration, and provisioning. Use it when the workload benefits from independently invoked tasks, retries, composition, or parallel execution instead of a continuously running worker process. + +Choose based on how the code executes and receives work: + +- Public incoming traffic that requires server-side logic belongs on a web service. Public static assets with no runtime server belong on a static site. +- An application that needs both public and private ingress remains a web service; use its internal hostname for traffic from other Render services. +- A process that receives private-network requests belongs on a private service. A process that only initiates connections and pulls work belongs on a background worker. +- A simple scheduled command that exits belongs on a cron job. An always-running queue consumer belongs on a background worker. On-demand or distributed tasks for which Render should manage queuing and per-run compute belong in a workflow. + +Cron jobs and Workflows use invocation-based execution models. The ordinary instance-count and autoscaling model used by continuously running services does not apply to them. + +Render Postgres and Render Key Value are fully managed datastores, not general-purpose compute service types for running application code. Use Render Postgres for relational data and Render Key Value for use cases such as shared caching and job queues. An attached persistent disk is a storage feature of certain compute services, not a service type of its own. + +After selecting a type, fetch the product article linked from the service-types reference before relying on details such as supported runtimes and sources, plans, scaling, networking, disks, health checks, deployment behavior, scheduling semantics, availability, or limits. These capabilities are not uniform across service types and can change independently. + +Human-facing service names do not always map directly to configuration identifiers or structure. When creating or editing a Blueprint, fetch the current Blueprint specification and use its service-type schema instead of inferring fields or values from this overview. In particular, do not assume that every Dashboard service type has a same-named Blueprint `type` or that managed datastores are declared like compute services. + diff --git a/skills/render-monitor/SKILL.md b/skills/render-monitor/SKILL.md index 6a8ad40..b339231 100644 --- a/skills/render-monitor/SKILL.md +++ b/skills/render-monitor/SKILL.md @@ -23,30 +23,11 @@ Activate this skill when users want to: - Investigate slow performance - Check database health -## Prerequisites +## Render Access -**MCP tools (preferred):** Test with `list_services()` - provides structured data +Before reading service state, logs, metrics, or database health, follow `references/render-access.md` to establish access and verify the intended workspace. Prefer MCP when available; the CLI can provide service status and logs, while metrics and database queries require MCP. -**CLI (fallback):** `render --version` - use if MCP tools unavailable - -**Authentication:** If you installed the Render plugin (Cursor, Codex, Claude Code), it provides OAuth for MCP — complete the OAuth prompt. For manual MCP clients, use a Render API key. For CLI, verify with `render whoami -o json`. - -**Workspace:** `get_selected_workspace()` or `render workspace current -o json` - -> **Note:** MCP tools require the Render MCP server. If unavailable, use the CLI for status and logs; metrics and database queries require MCP. - -## MCP Setup - -If `list_services()` fails, set up the Render MCP server. For detailed per-tool walkthroughs, see **render-mcp**. - -**Plugin setup:** If the Render plugin is installed, complete Render OAuth when prompted, then reload your tool and retry `list_services()`. - -**Manual MCP setup:** Add the Render MCP server to your AI tool's MCP config: -- **URL:** `https://mcp.render.com/mcp` -- **Auth header:** `Authorization: Bearer ` -- **API key:** `https://dashboard.render.com/u/*/settings#api-keys` - -After configuring, restart your tool and retry `list_services()`. Then set your workspace with `list_workspaces()` / `get_selected_workspace()`. +Before interpreting deploy or health-check state, read `references/deployments.md`. --- @@ -91,12 +72,7 @@ get_service(serviceId: "") list_deploys(serviceId: "", limit: 5) ``` -| Status | Meaning | -|--------|---------| -| `live` | Deployment successful | -| `build_in_progress` | Building | -| `build_failed` | Build failed | -| `deactivated` | Replaced by newer deploy | +Follow `references/deployments.md` to interpret asynchronous and terminal states, identify the specific deploy, and verify the workload after it becomes live. ### Check Errors @@ -304,7 +280,6 @@ render ssh | Indicator | Healthy | Warning | Critical | |-----------|---------|---------|----------| -| Deploy Status | `live` | `update_in_progress` | `build_failed` | | Error Rate | <0.1% | 0.1-1% | >1% | | p95 Latency | <500ms | 500ms-2s | >2s | | CPU Usage | <70% | 70-90% | >90% | @@ -314,10 +289,26 @@ render ssh ## References +- **Render access:** [references/render-access.md](references/render-access.md) +- **Compute plans:** [references/compute-plans.md](references/compute-plans.md) +- **Deployments:** [references/deployments.md](references/deployments.md) - **Metrics guide:** [references/metrics-guide.md](references/metrics-guide.md) ## Related Skills - **render-deploy** — Deploy new applications to Render - **render-debug** — Diagnose and fix deployment failures -- **render-mcp** — MCP server setup and tool catalog +- **render-mcp** — MCP server setup and capability discovery + + +## Current documentation retrieval + +Whenever this skill directs you to consult current Render documentation: + +1. Retrieve the linked Markdown document directly with an available URL-fetching tool or HTTP client, such as `curl`. Do not substitute web-search summaries for the document. +2. Confirm that retrieval succeeded and returned the expected document, then read its contents. Saving a file or printing its path is not sufficient. +3. If the request fails or your tool cannot read the Markdown response, open and read the linked HTML version instead. +4. If neither version can be retrieved, disclose that the current reference is unavailable and follow any topic-specific fallback in the skill. Use bundled guidance only for stable constraints, and do not guess at changeable platform details. + +When a task requires multiple references, apply this workflow to each one and distinguish the documents you verified from those that remain unavailable. + diff --git a/skills/render-monitor/references/compute-plans.md b/skills/render-monitor/references/compute-plans.md new file mode 100644 index 0000000..5d0ccc1 --- /dev/null +++ b/skills/render-monitor/references/compute-plans.md @@ -0,0 +1,23 @@ + +## Compute plans + +A compute plan determines the CPU and RAM available to each instance of a Render service. Use **compute plan**, not the former term **instance type**. Do not confuse a service's compute plan with its workspace plan, which controls account-level features and limits. + +Compute plans differ by service type: + +- Web services, private services, background workers, and cron jobs use CPU-and-memory plan IDs such as `0.5c-512mb` and `1c-2g`. +- Render Postgres has its own plan catalog and connection limits. +- Render Key Value uses memory-based plan IDs such as `256mb` and `1g`. +- Workflow tasks select a compute plan in application code; a Workflow service does not set a Blueprint `plan`. +- Static sites do not have compute plans. + +Legacy plan names such as `starter`, `standard`, and `pro` remain valid in Render tooling, including Blueprints and API requests. For new configuration, prefer the current plan ID when the selected configuration surface accepts it. Before passing a plan to an API, MCP tool, or CLI command, inspect that operation's current schema or help and use one of its accepted values; the compute-plan reference describes the product catalog, not every tool version's input contract. Do not rename an existing legacy plan merely for consistency unless the user asks for that change. + +Do not rely on a memorized plan catalog. When a task depends on current plan IDs, specifications, defaults, availability, or pricing, fetch the canonical compute-plan reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/compute-plans.md) or its [HTML version](https://render.com/docs/compute-plans). + +Read the section for the relevant service type. If the document cannot be fetched, do not guess at current plan details. Preserve an existing valid plan where possible, or explain that the plan must be confirmed in the Render Dashboard or current documentation. + +When estimating capacity or cost, remember that every instance of a scaled service uses the selected compute plan and is billed accordingly. Changing the compute plan for Render Postgres, Render Key Value, or a service with an attached persistent disk requires brief downtime; other services normally apply the change with a zero-downtime deploy. + diff --git a/skills/render-monitor/references/deployments.md b/skills/render-monitor/references/deployments.md new file mode 100644 index 0000000..5ca9905 --- /dev/null +++ b/skills/render-monitor/references/deployments.md @@ -0,0 +1,50 @@ + +## Deployments and health checks + +A Render deploy is asynchronous. A successful trigger means only that Render accepted or queued the deploy; it does not mean the new version is live. Before triggering a deploy, confirm the workspace, service, intended source commit or image, and current live deploy. Capture the new deploy ID, monitor it to a terminal state, and do not report success until its status is `live` and the deployed workload has been verified. + +Before configuring or troubleshooting deployments and health checks, fetch the current Render references: + +- [deploys.md](https://render.com/docs/deploys.md) (HTML: ) +- [health-checks.md](https://render.com/docs/health-checks.md) (HTML: ) + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read both references. + +Read the relevant sections of both documents. Confirm current service-type support, command timeouts, health-check thresholds, rollout behavior, and configuration syntax rather than relying on remembered values. + +Automatic deployment behavior depends on the service's source and settings. A service linked to a branch through a connected Git provider can deploy on each commit, wait for supported CI checks, or require manual triggers. Services that pull a prebuilt image and services linked by a public Git repository URL require manual deploys; moving a mutable image tag does not itself trigger one. When manually deploying a historical commit, verify whether that trigger method changes automatic-deploy settings. If automatic deploys remain enabled, a later branch update can replace the selected commit. + +The normal lifecycle is build command, optional pre-deploy command, then start command and readiness checks. If a command fails or times out, the deploy fails and later steps do not run. A pre-deploy command runs after the build on a separate instance before the new version is deployed. Neither the build nor pre-deploy instance can access an attached persistent disk, and pre-deploy filesystem changes do not carry into the running service. Use pre-deploy for release tasks such as database migrations, not for producing runtime artifacts. Pre-deploy commands are supported for paid web services, private services, and background workers. + +Render normally deploys services without downtime by starting the new version before retiring the current one. Web and private services continue routing traffic to the current instances until the new instances are ready. Multi-instance services roll out one instance at a time; if a replacement does not become healthy, Render cancels the rollout and retains or restores the previous version. Attaching a persistent disk disables zero-downtime deploys, so plan explicitly for an interruption. + +A workflow deployment has a different completion model. It builds and caches the image used by future task runs and includes a task-registration step, but it does not execute those tasks. After a workflow deploy succeeds, verify that the expected task definitions are registered. Trigger and monitor a task run separately only when execution is intended. For workflow-specific deployment behavior, fetch the current workflow overview: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/workflows.md) or its [HTML version](https://render.com/docs/workflows). + +Health checks apply to web services and private services. Both use TCP socket checks by default. Only web services support a configured HTTP health-check path. Render sends an HTTP `GET`; any `2xx` or `3xx` response received within five seconds succeeds, while other status codes, timeouts, and connection failures fail. Private services support TCP checks only. + +For a new deploy, all new instances must pass their checks at the same time within the current readiness window, documented as 15 minutes, before Render routes traffic to them. For a running service, consecutive failures currently remove an instance from routing after 15 seconds and restart it after 60 seconds. Treat these thresholds as platform behavior, not user-tunable health-check interval settings, and verify them in the fetched reference before relying on exact timing. + +Design an HTTP health endpoint to represent readiness for production traffic. Keep it fast and side-effect free. Check critical dependencies only when losing that dependency should make the entire instance unavailable; otherwise a transient dependency failure can unnecessarily remove healthy application capacity. Verify the configured path, response status, response time, listening port, and `0.0.0.0` binding when checks fail. + +After traffic moves, Render gives the previous instance a drain period, then sends `SIGTERM`. The application should stop accepting new work, finish or safely abandon in-flight work, close connections, and exit within its shutdown delay. Ensure the actual application process receives the signal: container entrypoints and shell wrappers should use `exec` or explicitly forward signals. Render sends `SIGKILL` if the process remains running after the delay. The documented default shutdown delay is 30 seconds and the usual maximum is 300 seconds, but support varies by service configuration; confirm the current reference and Blueprint or API validation before setting `maxShutdownDelaySeconds`. + +A service restart is a special deploy of the same commit and user-defined environment-variable values as the current running instance. It does not incorporate configuration changes saved after that deploy. Use a standard deploy when pending configuration must take effect. + +Only one deploy runs at a time for a service. A workspace's overlapping-deploy policy determines whether a new trigger waits or cancels the in-progress deploy. Do not assume the policy or wait for every intermediate revision: inspect the workspace setting and identify the deploy that actually became live. + +Treat rollback as a new deploy based on a retained previous build artifact, not as restoration of the entire service to an earlier point in time. It does not reverse database migrations, messages, external writes, or other side effects from the release, so confirm that the previous application version remains compatible with current external state. Disks and their data are not rolled back, some settings continue using current configuration, mutable image tags can resolve to a different image, and eligible artifacts are retained only for a limited period. Before rolling back, fetch the current rollback reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/rollbacks.md) or its [HTML version](https://render.com/docs/rollbacks). + +Read which configuration comes from the target deploy and which remains current. After the rollback is created, inspect the service's resulting automatic-deploy setting instead of assuming whether it remains enabled, and deliberately restore the intended setting after the underlying issue is resolved. + +Deploy hooks are secret credentials that authorize deploys. Never print, commit, or expose their full URLs. Before using one, fetch the current deploy-hook reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/deploy-hooks.md) or its [HTML version](https://render.com/docs/deploy-hooks). + +Distinguish an immediately started deploy from a queued one, and continue monitoring the resulting deploy rather than treating the HTTP response as completion. + +After a deploy becomes live, verify the behavior appropriate to the service type: make a request to a web or private service, confirm a worker is processing work, confirm a cron job or workflow invocation completes, and inspect recent runtime logs for new errors. If a deploy fails, diagnose the first failed lifecycle stage before retrying. + diff --git a/skills/render-monitor/references/metrics-guide.md b/skills/render-monitor/references/metrics-guide.md index b2d01c2..6af9a7f 100644 --- a/skills/render-monitor/references/metrics-guide.md +++ b/skills/render-monitor/references/metrics-guide.md @@ -26,18 +26,13 @@ Comprehensive guide to understanding and acting on Render service metrics. **What it measures:** Percentage of allocated CPU being used. -**Healthy ranges by plan:** -| Plan | Typical Healthy | Warning | Critical | -|------|-----------------|---------|----------| -| Free/Starter | <60% | 60-80% | >80% | -| Standard | <70% | 70-85% | >85% | -| Pro+ | <75% | 75-90% | >90% | +Interpret CPU utilization relative to the service's selected compute plan and workload. Use [compute-plans.md](compute-plans.md) when current CPU specifications matter instead of inferring them from legacy plan names. **Actions for high CPU:** 1. Profile code for inefficient operations 2. Add caching for repeated computations 3. Optimize database queries -4. Upgrade to higher plan +4. Upgrade to a larger compute plan 5. Enable autoscaling ### cpu_limit @@ -59,13 +54,7 @@ Comprehensive guide to understanding and acting on Render service metrics. **What it measures:** Memory being used by the service in bytes. -**Healthy ranges:** -| Plan | Memory Limit | Warning Threshold | Critical Threshold | -|------|-------------|-------------------|-------------------| -| Free | 512 MB | 400 MB (78%) | 460 MB (90%) | -| Starter | 512 MB | 400 MB (78%) | 460 MB (90%) | -| Standard | 2 GB | 1.6 GB (80%) | 1.8 GB (90%) | -| Pro | 4 GB | 3.2 GB (80%) | 3.6 GB (90%) | +Interpret memory relative to the resource's reported limit rather than mapping legacy plan names to memorized byte values. Use [compute-plans.md](compute-plans.md) when current memory specifications matter. **Actions for high memory:** 1. Profile for memory leaks @@ -107,7 +96,7 @@ Comprehensive guide to understanding and acting on Render service metrics. **Actions for high latency:** 1. Add database indexes -2. Implement caching (Redis/KV) +2. Implement caching with Key Value 3. Optimize N+1 queries 4. Use connection pooling 5. Add CDN for static assets @@ -161,20 +150,14 @@ Compare `instance_count` trends with `cpu_usage` and `http_request_count`: **What it measures:** Number of active database connections. -**Connection limits by plan:** -| Plan | Max Connections | Warning | Critical | -|------|----------------|---------|----------| -| Free | 97 | 75 | 90 | -| Basic | 97 | 75 | 90 | -| Standard | 200-500 | 160-400 | 180-450 | -| Pro | 500+ | 400+ | 450+ | +Connection limits vary by Postgres compute plan. Fetch the current limit through [compute-plans.md](compute-plans.md), then compare active connections with that limit. **Actions for high connections:** 1. Implement connection pooling (PgBouncer) 2. Close idle connections 3. Reduce connection timeouts 4. Fix connection leaks in code -5. Upgrade database plan +5. Upgrade the database compute plan ### Database CPU/Memory @@ -197,7 +180,7 @@ Same interpretation as service metrics, but: **Cost implications:** - Render includes bandwidth in plans -- Excessive bandwidth may incur overage charges +- Usage beyond the included allowance can incur additional cost; confirm current details at [Render pricing](https://render.com/pricing) --- diff --git a/skills/render-monitor/references/render-access.md b/skills/render-monitor/references/render-access.md new file mode 100644 index 0000000..864c854 --- /dev/null +++ b/skills/render-monitor/references/render-access.md @@ -0,0 +1,50 @@ + +## Accessing Render + +Prefer the hosted Render MCP server for structured access to Render resources when its tools are available. Use the Render CLI when MCP is unavailable or does not support the required operation, and use the Render Dashboard or API for capabilities exposed by neither. Do not assume that a remembered MCP tool or CLI command is still available; inspect the tools in the current environment or consult the current documentation. + +The hosted Render MCP server uses streamable HTTP at: + +```text +https://mcp.render.com/mcp +``` + +Official Render plugins and connectors can authenticate MCP with browser-based OAuth. Manual and non-interactive configurations can use a Render API key as a bearer token. Never write an API key or OAuth token into a repository, skill, command output, chat response, or log. Prefer the client's supported secret storage or environment-variable mechanism. If a client requires a credential in local configuration, keep that file out of version control and restrict access to it. + +Treat MCP responses as potentially sensitive even when the server attempts to minimize credential exposure. Request connection strings, credentials, secret environment variables, or other sensitive fields only when the task requires them. Do not repeat sensitive values in the response or persist them in files or logs. + +Before configuring or troubleshooting MCP, fetch the current setup and capability reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/mcp-server.md) or its [HTML version](https://render.com/docs/mcp-server). + +Read the relevant client setup, supported-actions, and limitations sections. Prefer the hosted server unless the user's environment requires a local MCP server. After installing, updating, or reconfiguring an MCP integration, reload the client as required and verify the connection with a read-only operation such as listing services. + +Most MCP operations and Render CLI commands that access Render resources are scoped to an active workspace. Check the selected workspace before reading or changing resources. If no workspace is selected—or if the intended workspace is ambiguous—list the available workspaces and have the user identify the correct one. Do not silently switch workspace context or infer it from a resource name. Commands for authentication, help, CLI configuration, and workspace discovery or selection do not require an already selected workspace. + +For interactive CLI use, authenticate with `render login`. For automation, use a securely stored `RENDER_API_KEY`; an API key takes precedence over a saved CLI token. Verify CLI access and the active workspace with read-only commands before operating on resources: + +```bash +render whoami --output json +render workspace current --output json +``` + +For CLI installation, authentication, workspace setup, and usage patterns, fetch the current CLI overview: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/cli.md) or its [HTML version](https://render.com/docs/cli). + +For exact command syntax and flags, prefer the help text from the installed CLI because it matches the version being used: + +```bash +render help +``` + +The published CLI command reference is generated automatically from the CLI's help text. Use it to browse the full command surface or when the CLI is not installed: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/cli-reference.md) or its [HTML version](https://render.com/docs/cli-reference). + +When an agent or automation invokes the CLI, select a non-interactive output format such as `--output json`, `--output yaml`, or `--output text` so results can be inspected reliably. The global `--confirm` flag skips confirmation prompts; use it for a mutating command only after that mutation is authorized. It is an execution convenience, not permission to perform the action. + +Authentication establishes access; it does not establish user authorization for every available action. Use read-only discovery to resolve workspace, resource identity, and current state before a mutation. Perform changes only when they are within the user's requested scope, and retain normal approval requirements for consequential operations such as creation, configuration changes, deploys, restarts, scaling, or deletion. + +When authentication or connectivity fails, report which access path failed, preserve the underlying error without exposing credentials, and either use an available supported fallback or explain what the user must configure before the task can continue. + diff --git a/skills/render-networking/SKILL.md b/skills/render-networking/SKILL.md index 4de8b39..cb3a08e 100644 --- a/skills/render-networking/SKILL.md +++ b/skills/render-networking/SKILL.md @@ -25,66 +25,21 @@ Render’s **private network** lets services talk to each other without exposing - **Service discovery** across multiple instances (custom load balancing, mesh-style setups) - **Port limits**, reserved ports, or **multi-port** web services (public vs private) - **Free-tier** web services and **who can send vs receive** private traffic -- **Environment isolation** (Professional+) or **AWS PrivateLink** for private egress/ingress patterns +- **Environment isolation** (with a Pro workspace or higher) or **AWS PrivateLink** for private egress/ingress patterns -For step-by-step architecture examples and Blueprint patterns, see `references/communication-patterns.md`. For failure modes and fixes, see `references/troubleshooting.md`. +Before designing, configuring, or troubleshooting private connectivity, read `references/private-networking.md`. For architecture examples and Blueprint patterns, see `references/communication-patterns.md`. -## Private Network Basics +## Private Connection Essentials -Private connectivity is available only when **all** of the following hold: - -- Services are in the **same region** -- Services are in the **same workspace** - -If either differs, private DNS and internal routing will not connect those services. - -### Who can communicate - -| Resource | Private inbound | Private outbound | Internal hostname | -|----------|-----------------|------------------|-------------------| -| **Web Service** | Yes (paid tiers; see Free tier below) | Yes | Yes | -| **Private Service** | Yes | Yes | Yes | -| **Background Worker** | No | Yes | No | -| **Cron Job** | No | Yes | No | -| **Workflow Run** | No | Yes | No | -| **Static Site** | — | — | **Not on private network** | -| **Managed Postgres** | Via internal URL (from allowed clients) | N/A (datastore) | Via internal URL | -| **Key Value** | Via internal URL (from allowed clients) | N/A (datastore) | Via internal URL | - -**Free-tier Web Services:** They may **send** private traffic to other services, but they **cannot receive** inbound private traffic. Plan upgrades or topology changes apply if a free web service must accept private connections. - -Workers, crons, and workflow runs initiate outbound connections (e.g., to internal URLs or private service hostnames) but are **not** reachable by internal hostname for inbound calls. - -## Internal Addresses - -- Open the service in the Render Dashboard → **Connect** → **Internal** tab for the canonical internal hostname, URL, and connection details. -- Clients often need an **explicit scheme** in code or config, e.g. `http://service-name:port` or `https://...` when TLS applies—do not assume a bare hostname alone is enough for every HTTP client. -- **URL shape:** `http://[internal-hostname]:[port]/path` (adjust scheme/port per service). +- If the service types or traffic direction are unclear, establish which service initiates the connection and which service receives it before proposing an address. +- Private-network peers must be in the same workspace and region. Use the destination's address from **Connect > Internal** in the Dashboard. +- Construct a complete URL when the client expects one, such as `http://[internal-hostname]:[port]/path`; a bare hostname does not supply the protocol. +- Web services and private services can receive private traffic. Background workers, cron jobs, and workflow runs can initiate outbound private connections but have no internal hostname and cannot receive them. +- In a gateway pattern, a public web service calls a private service over the private network; the private service does not need a public endpoint. ## Service Discovery -For services with **multiple instances**, Render exposes a **discovery DNS** name that resolves to **all instance IPs** for that service. The pattern is **`[hostname]-discovery`** (see Dashboard docs for the exact hostname shown for your service). - -- **`RENDER_DISCOVERY_SERVICE`** is set in environments where discovery applies; use it with the discovery hostname pattern for scripts and app code that need instance lists. -- **Use case:** Custom load balancing, health aggregation, or any logic that must fan out or pick among instances explicitly instead of a single internal hostname. - -See `references/communication-patterns.md` for discovery-oriented patterns. - -## Port Rules - -- **Maximum 75 open ports** per service. -- **Reserved ports** (do not bind your app to these for normal use): **10000** (public HTTP proxy path), **18012**, **18013**, **19099**. -- **Multi-port Web Services:** Only **one** port receives **public** HTTP traffic; that port must align with the **`PORT`** environment variable. **Additional** ports are for **private network** access only. - -When something fails to connect, verify the target is listening on the expected port and that the port is not reserved or blocked by misconfiguration. - -## Environment Isolation - -On **Professional and higher** workspaces, you can configure **per-environment** rules so private traffic does **not** cross certain environment boundaries. If private calls work in one environment but not another, check workspace **environment isolation** settings before assuming DNS or app bugs. - -## AWS PrivateLink - -**Professional+** workspaces can use **AWS PrivateLink** to extend private connectivity to or from external AWS VPCs and approved endpoints. This is separate from default service-to-service private DNS; use it when the architecture requires **private** access to Render or from Render to specific AWS resources without the public internet. +Use a service's normal internal hostname for ordinary service-to-service traffic. When an application specifically needs every active instance—for custom load balancing, per-instance metrics, or similar logic—use the service's discovery hostname, conventionally `[internal-hostname]-discovery`, which resolves to all active instance IPs. Each web or private service receives its own discovery hostname in `RENDER_DISCOVERY_SERVICE`. Do not persist the resolved IPs because they can change between deploys. ## Common Patterns @@ -98,11 +53,24 @@ Short summaries; full diagrams and Blueprint notes live in `references/communica | Document | Purpose | |----------|---------| -| `references/communication-patterns.md` | Gateway, worker→DB, mesh, URL construction, Blueprint `fromService`, discovery load balancing, private health checks | -| `references/troubleshooting.md` | DNS, ports, region/workspace, free tier, protocol, resolver, environment isolation | +| `references/private-networking.md` | Current private-network capabilities, addressing, discovery, ports, isolation, and troubleshooting | +| `references/communication-patterns.md` | Gateway, worker→DB, mesh, URL construction, and Blueprint `fromService` patterns | ## Related Skills - **render-web-services** — Public web services, `PORT`, and HTTP behavior -- **render-private-services** (planned) — Private Service–specific setup and scaling +- **render-private-services** — Private Service–specific setup and scaling - **render-blueprints** — `render.yaml`, `fromService`, and multi-service wiring + + +## Current documentation retrieval + +Whenever this skill directs you to consult current Render documentation: + +1. Retrieve the linked Markdown document directly with an available URL-fetching tool or HTTP client, such as `curl`. Do not substitute web-search summaries for the document. +2. Confirm that retrieval succeeded and returned the expected document, then read its contents. Saving a file or printing its path is not sufficient. +3. If the request fails or your tool cannot read the Markdown response, open and read the linked HTML version instead. +4. If neither version can be retrieved, disclose that the current reference is unavailable and follow any topic-specific fallback in the skill. Use bundled guidance only for stable constraints, and do not guess at changeable platform details. + +When a task requires multiple references, apply this workflow to each one and distinguish the documents you verified from those that remain unavailable. + diff --git a/skills/render-networking/references/communication-patterns.md b/skills/render-networking/references/communication-patterns.md index ccdc448..8f53119 100644 --- a/skills/render-networking/references/communication-patterns.md +++ b/skills/render-networking/references/communication-patterns.md @@ -1,6 +1,6 @@ # Private network communication patterns -Architecture examples and implementation notes for Render’s private network. Pair with the main `SKILL.md` for limits (region, workspace, free tier, ports). +Architecture examples and implementation notes for Render’s private network. Read [private-networking.md](private-networking.md) first for current platform behavior and limits. ## Gateway pattern @@ -23,7 +23,6 @@ Architecture examples and implementation notes for Render’s private network. P **Flow:** Multiple **Private Services** (and optionally internal ports on Web Services) call each other by **internal hostnames**. - Standardize on one scheme (`http` vs `https`) per hop; some clients require an explicit `http://` or `https://` prefix. -- For cross-service **health checks**, use the private hostname:port from a service that is allowed to initiate private egress (e.g., another Private Service or Web Service), not from a Static Site or from a Worker if you need the target to be another compute service’s inbound port. ## URL construction @@ -44,15 +43,10 @@ In `render.yaml`, link services for private access using **`fromService`** on th Ensure the producer service type supports private networking and that region/workspace match the consumer. -## Discovery hostname for custom load balancing +## Per-instance discovery -When a service scales to multiple instances: +Use per-instance discovery only when the application must implement custom instance selection, retries, health aggregation, or per-instance metrics. Prefer the normal internal hostname for ordinary service-to-service calls. Follow [private-networking.md](private-networking.md) for the current discovery hostname and resolver behavior. -- The **`[hostname]-discovery`** name resolves to **all** instance IPs. -- Combine with **`RENDER_DISCOVERY_SERVICE`** where provided to drive custom selection, retries, or metrics per instance. -- Useful when round-robin or sticky behavior must be implemented in application code rather than relying on a single internal A-record. +## Crossing private-network boundaries -## Cross-service health checking via private network - -- Prefer health endpoints bound to the **private** listener port when checks originate from another Render service in the same region/workspace. -- Avoid assuming public health URLs are equivalent to private reachability; firewalls, bindings, and `PORT` vs extra ports differ for multi-port web services. +When resources intentionally span regions, workspaces, or isolated project environments, either colocate them or design an explicit supported integration path such as an authenticated public endpoint or data replication. Do not expose an otherwise private service merely as a troubleshooting shortcut. diff --git a/skills/render-networking/references/private-networking.md b/skills/render-networking/references/private-networking.md new file mode 100644 index 0000000..d68d6be --- /dev/null +++ b/skills/render-networking/references/private-networking.md @@ -0,0 +1,25 @@ + +## Private networking + +Render services can communicate over a private network without traversing the public internet. Private-network peers must belong to the same workspace and run in the same region. An isolated project environment can additionally block traffic both to and from resources outside that environment, so workspace and region matching alone do not guarantee connectivity. + +Before designing, configuring, or troubleshooting private-network communication, fetch the current Render private-network reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/private-network.md) or its [HTML version](https://render.com/docs/private-network). + +Read the relevant sections. Confirm current service-type capabilities, port restrictions, environment-isolation behavior, discovery-hostname guidance, and plan requirements instead of relying on a memorized catalog. + +Web services and private services have internal hostnames and can receive private-network traffic. A private service must bind at least one port; use a background worker instead when a workload does not need to accept inbound connections. Render Postgres and Key Value instances provide internal connection URLs. Workflows, background workers, and cron jobs can initiate private-network connections but do not have an internal address for receiving them. Static sites are not on the private network. Free web services can initiate private-network connections but cannot receive them. + +Prefer the internal address or URL shown under **Connect > Internal** in the Render Dashboard. Include the protocol when the client or server requires one; an address such as `service:10000` does not by itself establish whether to use HTTP, HTTPS, or another protocol. A process that receives traffic must listen on the intended port and on an interface reachable outside its own container, such as `0.0.0.0`, rather than only on loopback. + +For Blueprint-managed connections, fetch the current Blueprint specification and use supported service or database references instead of copying a generated hostname, port, credential, or connection string. Web and private services currently expose `host`, `port`, and `hostport` properties. A Blueprint can obtain another service's discovery hostname by referencing that service's `RENDER_DISCOVERY_SERVICE` environment variable with `fromService.envVarKey`; the discovery hostname is not a service property. The fetched specification is authoritative for the syntax and supported references. + +A service can expose at most 75 ports on the private network. Ports `18012`, `18013`, and `19099` are unavailable for private-network communication. Port `10000` is not generally blocked: for a web service, private traffic to port `10000` routes to its primary HTTP server even when that server binds to another port. In that case, both port `10000` and the actual primary HTTP port route to the same server. + +Use a service's normal internal hostname for ordinary service-to-service traffic. For advanced per-instance communication, each web or private service has a discovery hostname, conventionally formed by appending `-discovery` to its internal hostname, that resolves to all active instance IP addresses. A service receives its own discovery hostname in `RENDER_DISCOVERY_SERVICE`. Use DNS APIs that honor the system resolver configuration, and do not persist resolved instance IPs because they can change between deploys. Prefer hostname-based communication unless per-instance addressing or custom load balancing is specifically required. + +When a private-network connection fails, verify the workspace, region, project-environment isolation settings, whether the destination service type accepts inbound traffic, the internal hostname or URL, protocol, port, listening interface, current deploy health, and DNS resolution. Do not substitute a public URL or expose a private service merely to bypass a private-network configuration problem. + +AWS PrivateLink is a separate Pro-or-higher feature for connecting a Render private network to compatible AWS-hosted systems. Fetch its current documentation before proposing or configuring it; do not treat ordinary Render service-to-service networking and PrivateLink as interchangeable. + diff --git a/skills/render-networking/references/troubleshooting.md b/skills/render-networking/references/troubleshooting.md deleted file mode 100644 index 8874671..0000000 --- a/skills/render-networking/references/troubleshooting.md +++ /dev/null @@ -1,49 +0,0 @@ -# Private network troubleshooting - -Common issues when private connectivity fails or behaves unexpectedly on Render. - -## DNS resolution failures - -- Confirm both services are in the **same region** and **same workspace**. Private DNS is scoped to that combination. -- Verify the **target service is running** (deploy succeeded, process up). Stopped or failed deploys will not resolve usefully for callers. -- Use the **system resolver** (see below); do not rely on ad-hoc HTTP “DNS” APIs for internal names. - -## Port conflicts and limits - -- **Reserved ports:** **10000**, **18012**, **18013**, **19099** — do not use these for your application’s primary listener. -- **75-port maximum** per service; trim listeners or consolidate if you hit the cap. -- **Multi-port Web Services:** Only the **`PORT`** port receives **public** HTTP; other open ports are **private-only**. Callers using the wrong port or expecting public routing on an extra port will fail or time out. - -## Cross-region - -Services in **different regions** **cannot** communicate over Render’s private network. Use public endpoints, data replication, or redesign placement so peers share a region. - -## Cross-workspace - -Services in **different workspaces** **cannot** communicate privately, even if regions match. Merge into one workspace or use an allowed public/integration path. - -## Protocol mismatches - -- Some HTTP clients require an explicit **`http://`** or **`https://`** prefix for internal URLs; a bare hostname may not construct a valid request URL. -- Mismatching **TLS** expectations (HTTPS client to HTTP server or vice versa) produces connection errors that look like “network” failures. - -## Free-tier limitations - -**Free Web Services** can **send** private traffic but **cannot receive** inbound private connections. If a Private Service or another Web Service cannot reach a free-tier web target privately, upgrade the target or expose traffic via a different topology (e.g., public API with auth). - -## Workers, crons, and workflows “unreachable” - -**Background Workers**, **Cron Jobs**, and **Workflow Runs** have **no internal hostname**. They **cannot** accept inbound private connections. Only **outbound** calls from them are valid; do not point other services at a “worker internal URL.” - -## DNS resolver - -- Use the **system DNS** configured in the runtime (e.g., behavior consistent with **`/etc/resolv.conf`** in Linux containers). -- Avoid replacing resolution with custom HTTP-based lookups for internal Render names; that bypasses the platform’s private DNS chain. - -## Environment isolation (Professional+) - -If private traffic **suddenly fails** between services that used to work, check whether **per-environment isolation** was enabled or tightened. Isolation can **block cross-environment** private traffic even when region and workspace match at the workspace level. - -## Static sites - -**Static Sites are not on the private network.** They cannot call or be called via internal hostnames. Use a Web Service or edge-appropriate public API for integration. diff --git a/skills/render-postgres/SKILL.md b/skills/render-postgres/SKILL.md index 0a3e41a..e66f4e5 100644 --- a/skills/render-postgres/SKILL.md +++ b/skills/render-postgres/SKILL.md @@ -32,6 +32,8 @@ Apply this skill when the user: For deploy flows and Blueprint basics, see **render-deploy** and **render-blueprints**. For private networking between services, see **render-networking**. For env var patterns, see **render-env-vars**. +Before configuring or troubleshooting an internal database connection, read `references/private-networking.md`. + ## Connection Patterns Render exposes **two connection URLs** for the same logical database: @@ -54,7 +56,7 @@ URL formats, Dashboard locations, Blueprint `fromDatabase`, pooling, and common - **Immutable after creation**: `databaseName`, database **user**, **region**, **PostgreSQL major version**. Plan these before create; changing them requires a new database and migration. - **Storage size**: **1 GB** or **multiples of 5 GB** when provisioning. -Wire apps with Blueprint `fromDatabase` using `property: connectionString` (or `host`, `port`, `user`, `password`, `database` individually). See **render-blueprints**. +Wire apps with Blueprint `fromDatabase` using `property: connectionString`, `connectionPoolString` when managed PgBouncer is enabled, or `host`, `port`, `user`, `password`, and `database` individually. See **render-blueprints**. ### Multiple logical databases @@ -71,30 +73,13 @@ Monitor disk and plan exports or cleanup before you hit hard limits. Backup and ## Connection Limits -Maximum connections depend on **instance RAM** (current-generation plans): - -| RAM | Max connections (typical) | -|-----|---------------------------| -| Under 8 GB | 100 | -| 8 GB | 200 | -| 16 GB | 300 | -| 32 GB and above | 500 | - -**Legacy** database plans may have **lower** limits; confirm in the Dashboard or API for the specific plan. - -Render does **not** provide a built-in pooler; use **application-side pooling** (framework pools, PgBouncer, pgpool, etc.). Limits are **hard**—exhausting them causes connection errors. More detail: `references/connection-guide.md` and `references/performance-tuning.md`. - -## High Availability +Connection limits depend on the database's compute plan. Use `references/compute-plans.md` to fetch the current Postgres plan catalog and connection limits instead of relying on a memorized table. -**High availability (HA)** is available when: +Render provides integrated **PgBouncer** connection pooling for paid Postgres instances. Enable it with `connectionPool: pgbouncer` in a Blueprint, then connect clients with the database's `connectionPoolString`. Keep application pool sizes aligned with the database connection limit; clients that require session-level state or dedicated long-lived connections must use the direct connection string. Enabling the managed pool restarts the database and causes a few minutes of unavailability. More detail: `references/connection-guide.md` and `references/performance-tuning.md`. -- Workspace is **Professional** or higher, **and** -- Database plan is **Pro** or higher, **and** -- **PostgreSQL 13+** +## High Availability and Compute Plans -**Instance type changes** cause **brief downtime**. With HA, downtime is typically **less** than **without HA** (often on the order of **minutes** without HA—exact duration depends on plan and operation). - -**One-way migration off legacy types**: After moving to current-generation instance types, you **cannot** move back to **legacy** instance types. +HA eligibility and plan-change behavior depend on the Postgres compute plan and version. See `references/compute-plans.md` before recommending a plan or changing an existing database. ## Read Replicas @@ -130,6 +115,8 @@ Shorthand (same tools): `list_postgres_instances()`, `get_postgres(postgresId)`, | Document | Contents | |----------|----------| +| `references/compute-plans.md` | Current Postgres Plan IDs, connection limits, downtime, HA, and legacy-plan migration | +| `references/private-networking.md` | Current private-network scope, internal addressing, isolation, and troubleshooting | | `references/connection-guide.md` | Internal vs external URLs, SSL, allow list, Blueprint wiring, pooling, multi-database URLs, troubleshooting | | `references/backup-and-recovery.md` | Snapshots, PITR, `pg_dump` / `pg_restore`, restore flows, deletion, cross-region | | `references/performance-tuning.md` | `pg_stat_statements`, indexes, bloat, `EXPLAIN ANALYZE`, metrics, scaling | @@ -140,3 +127,16 @@ Shorthand (same tools): `list_postgres_instances()`, `get_postgres(postgresId)`, - **render-blueprints** — `databases`, `fromDatabase`, `readReplicas`, immutable fields - **render-networking** — Private services, regions, and how traffic routes between resources - **render-env-vars** — Storing `DATABASE_URL` and secret wiring patterns + + +## Current documentation retrieval + +Whenever this skill directs you to consult current Render documentation: + +1. Retrieve the linked Markdown document directly with an available URL-fetching tool or HTTP client, such as `curl`. Do not substitute web-search summaries for the document. +2. Confirm that retrieval succeeded and returned the expected document, then read its contents. Saving a file or printing its path is not sufficient. +3. If the request fails or your tool cannot read the Markdown response, open and read the linked HTML version instead. +4. If neither version can be retrieved, disclose that the current reference is unavailable and follow any topic-specific fallback in the skill. Use bundled guidance only for stable constraints, and do not guess at changeable platform details. + +When a task requires multiple references, apply this workflow to each one and distinguish the documents you verified from those that remain unavailable. + diff --git a/skills/render-postgres/references/backup-and-recovery.md b/skills/render-postgres/references/backup-and-recovery.md index 86c662d..3633b41 100644 --- a/skills/render-postgres/references/backup-and-recovery.md +++ b/skills/render-postgres/references/backup-and-recovery.md @@ -33,8 +33,8 @@ Test restore procedures on a **non-production** database periodically. ## Plan and instance migration -- **Upgrading** instance type / plan is supported; expect **brief downtime** (reduced with **high availability** where enabled). -- **Downgrading** from **current-generation** plans back to **legacy** types is **not** supported after you have moved forward—plan instance families deliberately. +- **Changing** the compute plan is supported; expect **brief downtime** (reduced with **high availability** where enabled). +- After moving from a **legacy** compute plan to a current Plan ID, do not assume you can move back—choose plan families deliberately and consult `compute-plans.md`. ## Cross-region diff --git a/skills/render-postgres/references/compute-plans.md b/skills/render-postgres/references/compute-plans.md new file mode 100644 index 0000000..b0492fa --- /dev/null +++ b/skills/render-postgres/references/compute-plans.md @@ -0,0 +1,30 @@ + +## Compute plans + +A compute plan determines the CPU and RAM available to each instance of a Render service. Use **compute plan**, not the former term **instance type**. Do not confuse a service's compute plan with its workspace plan, which controls account-level features and limits. + +Compute plans differ by service type: + +- Web services, private services, background workers, and cron jobs use CPU-and-memory plan IDs such as `0.5c-512mb` and `1c-2g`. +- Render Postgres has its own plan catalog and connection limits. +- Render Key Value uses memory-based plan IDs such as `256mb` and `1g`. +- Workflow tasks select a compute plan in application code; a Workflow service does not set a Blueprint `plan`. +- Static sites do not have compute plans. + +Legacy plan names such as `starter`, `standard`, and `pro` remain valid in Render tooling, including Blueprints and API requests. For new configuration, prefer the current plan ID when the selected configuration surface accepts it. Before passing a plan to an API, MCP tool, or CLI command, inspect that operation's current schema or help and use one of its accepted values; the compute-plan reference describes the product catalog, not every tool version's input contract. Do not rename an existing legacy plan merely for consistency unless the user asks for that change. + +Do not rely on a memorized plan catalog. When a task depends on current plan IDs, specifications, defaults, availability, or pricing, fetch the canonical compute-plan reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/compute-plans.md) or its [HTML version](https://render.com/docs/compute-plans). + +Read the section for the relevant service type. If the document cannot be fetched, do not guess at current plan details. Preserve an existing valid plan where possible, or explain that the plan must be confirmed in the Render Dashboard or current documentation. + +When estimating capacity or cost, remember that every instance of a scaled service uses the selected compute plan and is billed accordingly. Changing the compute plan for Render Postgres, Render Key Value, or a service with an attached persistent disk requires brief downtime; other services normally apply the change with a zero-downtime deploy. + + +## Postgres-specific plan guidance + +- Confirm connection limits in the fetched Postgres plan table; they vary by compute plan and legacy databases can have different limits. +- Compute-plan changes cause brief downtime. High availability can reduce the interruption, but exact behavior depends on the database and operation. +- After moving from a legacy compute plan to a current Plan ID, do not assume the database can move back to a legacy plan. +- High availability requires PostgreSQL 13 or later and a compute plan with at least 1 CPU. Consult the current [PostgreSQL high availability documentation](https://render.com/docs/postgresql-high-availability.md) before enabling or changing HA. diff --git a/skills/render-postgres/references/connection-guide.md b/skills/render-postgres/references/connection-guide.md index fd70922..ed881f6 100644 --- a/skills/render-postgres/references/connection-guide.md +++ b/skills/render-postgres/references/connection-guide.md @@ -1,5 +1,7 @@ # Database connection guide (Render Managed Postgres) +Read [private-networking.md](private-networking.md) first when configuring or troubleshooting an internal connection. + ## URL formats - **Internal** (same region and workspace on Render; private network): @@ -26,18 +28,36 @@ In `render.yaml`, expose credentials to services with `fromDatabase`: - **`property: connectionString`** — single URL (ensure the app uses internal vs external appropriately at runtime if you override per environment), or +- **`property: connectionPoolString`** — the managed PgBouncer URL when integrated connection pooling is enabled, or - Individual properties: **`host`**, **`port`**, **`user`**, **`password`**, **`database`** See the **render-blueprints** skill for full examples and immutable field rules. ## Connection pooling -Render **does not** provide a managed connection pooler in front of Managed Postgres. You must use: +Render provides integrated **PgBouncer** connection pooling for paid Postgres instances. It is not available for Free Postgres. + +Enable it in a Blueprint and wire clients to its connection string: + +```yaml +services: + - type: web + name: app + envVars: + - key: DATABASE_URL + fromDatabase: + name: db + property: connectionPoolString + +databases: + - name: db + plan: basic-256mb + connectionPool: pgbouncer +``` -- **Framework connection pools** (e.g. Rails, Django, Node pg pool), or -- **External poolers** you operate (PgBouncer, pgpool, etc.) +Managed PgBouncer uses **transaction-level pooling**. Use the direct `connectionString` instead for clients that require session-level state or dedicated long-lived connections, including `LISTEN`/`NOTIFY`, temporary tables, and session-level advisory locks. -Instance **connection limits are enforced**; pooling is how you stay under them under concurrent load. +Enabling the managed pool restarts the database and causes a few minutes of unavailability. Application-side pools remain useful, but size them so total connections across all service instances stay within the database's enforced connection limit. ## Multiple logical databases diff --git a/skills/render-postgres/references/performance-tuning.md b/skills/render-postgres/references/performance-tuning.md index 31a173e..550d774 100644 --- a/skills/render-postgres/references/performance-tuning.md +++ b/skills/render-postgres/references/performance-tuning.md @@ -60,7 +60,7 @@ Run **`VACUUM ANALYZE`** (or rely on autovacuum tuning) on heavily updated table | Need | Direction | |------|-----------| -| More CPU/RAM/connections | **Vertical**: larger database **plan** / instance type | +| More CPU/RAM/connections | **Vertical**: larger database **compute plan** | | Read-heavy workload | **Read replicas** (up to 5); route read-only traffic explicitly | | Disk pressure | Autoscaling grows at ~**90%** (see main skill); **cannot shrink**—archive or migrate data | diff --git a/skills/render-postgres/references/private-networking.md b/skills/render-postgres/references/private-networking.md new file mode 100644 index 0000000..d68d6be --- /dev/null +++ b/skills/render-postgres/references/private-networking.md @@ -0,0 +1,25 @@ + +## Private networking + +Render services can communicate over a private network without traversing the public internet. Private-network peers must belong to the same workspace and run in the same region. An isolated project environment can additionally block traffic both to and from resources outside that environment, so workspace and region matching alone do not guarantee connectivity. + +Before designing, configuring, or troubleshooting private-network communication, fetch the current Render private-network reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/private-network.md) or its [HTML version](https://render.com/docs/private-network). + +Read the relevant sections. Confirm current service-type capabilities, port restrictions, environment-isolation behavior, discovery-hostname guidance, and plan requirements instead of relying on a memorized catalog. + +Web services and private services have internal hostnames and can receive private-network traffic. A private service must bind at least one port; use a background worker instead when a workload does not need to accept inbound connections. Render Postgres and Key Value instances provide internal connection URLs. Workflows, background workers, and cron jobs can initiate private-network connections but do not have an internal address for receiving them. Static sites are not on the private network. Free web services can initiate private-network connections but cannot receive them. + +Prefer the internal address or URL shown under **Connect > Internal** in the Render Dashboard. Include the protocol when the client or server requires one; an address such as `service:10000` does not by itself establish whether to use HTTP, HTTPS, or another protocol. A process that receives traffic must listen on the intended port and on an interface reachable outside its own container, such as `0.0.0.0`, rather than only on loopback. + +For Blueprint-managed connections, fetch the current Blueprint specification and use supported service or database references instead of copying a generated hostname, port, credential, or connection string. Web and private services currently expose `host`, `port`, and `hostport` properties. A Blueprint can obtain another service's discovery hostname by referencing that service's `RENDER_DISCOVERY_SERVICE` environment variable with `fromService.envVarKey`; the discovery hostname is not a service property. The fetched specification is authoritative for the syntax and supported references. + +A service can expose at most 75 ports on the private network. Ports `18012`, `18013`, and `19099` are unavailable for private-network communication. Port `10000` is not generally blocked: for a web service, private traffic to port `10000` routes to its primary HTTP server even when that server binds to another port. In that case, both port `10000` and the actual primary HTTP port route to the same server. + +Use a service's normal internal hostname for ordinary service-to-service traffic. For advanced per-instance communication, each web or private service has a discovery hostname, conventionally formed by appending `-discovery` to its internal hostname, that resolves to all active instance IP addresses. A service receives its own discovery hostname in `RENDER_DISCOVERY_SERVICE`. Use DNS APIs that honor the system resolver configuration, and do not persist resolved instance IPs because they can change between deploys. Prefer hostname-based communication unless per-instance addressing or custom load balancing is specifically required. + +When a private-network connection fails, verify the workspace, region, project-environment isolation settings, whether the destination service type accepts inbound traffic, the internal hostname or URL, protocol, port, listening interface, current deploy health, and DNS resolution. Do not substitute a public URL or expose a private service merely to bypass a private-network configuration problem. + +AWS PrivateLink is a separate Pro-or-higher feature for connecting a Render private network to compatible AWS-hosted systems. Fetch its current documentation before proposing or configuring it; do not treat ordinary Render service-to-service networking and PrivateLink as interchangeable. + diff --git a/skills/render-private-services/SKILL.md b/skills/render-private-services/SKILL.md index fbd6668..25b55f0 100644 --- a/skills/render-private-services/SKILL.md +++ b/skills/render-private-services/SKILL.md @@ -29,6 +29,10 @@ Private services are identical to web services except they have **no public URL* For public-facing HTTP services, use **render-web-services**. For services that don't receive any traffic, use **render-background-workers**. +Before configuring or troubleshooting private connectivity, read `references/private-networking.md`. +Before attaching or changing a persistent disk, read `references/persistent-disks.md`. +When choosing between a private service, web service, and worker, read `references/service-types.md`. + ## Private Service vs Background Worker | Criterion | Private Service | Background Worker | @@ -47,8 +51,8 @@ For public-facing HTTP services, use **render-web-services**. For services that - Reachable at `:` on the private network by services in the same region and workspace - Can listen on **any port** (except restricted system ports)—not limited to HTTP or port 10000 - Supports **any protocol**: HTTP, gRPC, TCP, WebSocket, custom binary protocols -- Same build/deploy lifecycle as web services (build command, start command, pre-deploy, health checks via the private network) -- Supports persistent disks, scaling, Docker runtime—same capabilities as web services +- Same build/deploy lifecycle as web services (build command, start command, pre-deploy) +- Supports persistent disks and Docker runtime. A disk-backed private service stays **single-instance** and cannot use autoscaling or zero-downtime deploys; follow `references/persistent-disks.md` for details. ## Connecting to a Private Service @@ -83,7 +87,7 @@ You can also reference a specific env var from the private service using `envVar Private services **must bind to at least one port**. If your process does not need to receive traffic, create a background worker instead. - Bind to `0.0.0.0` (not `127.0.0.1` or `localhost`) -- The `PORT` env var defaults to `10000`, but you can listen on any non-restricted port +- The `PORT` env var defaults to `10000`; confirm current restrictions in `references/private-networking.md` before choosing another port - For non-HTTP protocols (gRPC, TCP), configure your server on the desired port and tell consumers the `hostport` ## Blueprint Configuration @@ -158,7 +162,10 @@ services: | Document | Contents | |----------|----------| -| `references/patterns.md` | Microservice topology, gRPC setup, sidecar patterns, health checks for private services | +| `references/private-networking.md` | Current private-network scope, addresses, ports, discovery, isolation, and troubleshooting | +| `references/patterns.md` | Microservice topology, gRPC setup, and sidecar patterns | +| `references/persistent-disks.md` | Service-attached disk constraints, configuration, sizing, and snapshots | +| `references/service-types.md` | Service-type selection and execution models | ## Related Skills @@ -166,4 +173,17 @@ services: - **render-networking** — Private network, DNS, service discovery - **render-background-workers** — Services that don't receive traffic - **render-blueprints** — Full `render.yaml` schema, `fromService` wiring -- **render-scaling** — Instance types and autoscaling for private services +- **render-scaling** — Compute plans and autoscaling for private services + + +## Current documentation retrieval + +Whenever this skill directs you to consult current Render documentation: + +1. Retrieve the linked Markdown document directly with an available URL-fetching tool or HTTP client, such as `curl`. Do not substitute web-search summaries for the document. +2. Confirm that retrieval succeeded and returned the expected document, then read its contents. Saving a file or printing its path is not sufficient. +3. If the request fails or your tool cannot read the Markdown response, open and read the linked HTML version instead. +4. If neither version can be retrieved, disclose that the current reference is unavailable and follow any topic-specific fallback in the skill. Use bundled guidance only for stable constraints, and do not guess at changeable platform details. + +When a task requires multiple references, apply this workflow to each one and distinguish the documents you verified from those that remain unavailable. + diff --git a/skills/render-private-services/references/patterns.md b/skills/render-private-services/references/patterns.md index 5c1050f..c733f1f 100644 --- a/skills/render-private-services/references/patterns.md +++ b/skills/render-private-services/references/patterns.md @@ -1,5 +1,7 @@ # Private Service Patterns +Read [private-networking.md](private-networking.md) first for current private-network scope, address, port, protocol, and Blueprint-reference behavior. + ## Microservice Topology The most common private service pattern is a **public gateway + internal microservices**: @@ -78,35 +80,18 @@ services: plan: starter region: oregon dockerfilePath: ./collector/Dockerfile - startCommand: otelcol --config /etc/otel-config.yaml + dockerCommand: otelcol --config /etc/otel-config.yaml ``` Application services send telemetry to `otel-collector:` on the private network. -## Health Checks for Private Services - -Private services support health checks via the private network. Configure a health check path if your service exposes an HTTP endpoint: - -```yaml -services: - - type: pserv - name: internal-api - healthCheckPath: /health -``` - -For non-HTTP services (gRPC, TCP), Render checks that the process is running and the port is bound. There is no custom health check for non-HTTP protocols. - ## Port Binding - Private services **must** bind to at least one port - Bind to `0.0.0.0`, not `127.0.0.1` or `localhost` -- The `PORT` env var defaults to `10000`, but you can use any non-restricted port +- The `PORT` env var defaults to `10000`; confirm current restrictions in [private-networking.md](private-networking.md) before choosing another port - Multiple ports: your service can listen on multiple ports, but `fromService` only exposes the primary port via `property: port` -### Restricted ports - -System ports (typically 0-1023) may be restricted. Use ports >= 1024 for your services. - ## Private Service vs Web Service If you need public access **and** internal access, use a **web service**. Web services get both a public URL and an internal hostname on the private network. diff --git a/skills/render-private-services/references/persistent-disks.md b/skills/render-private-services/references/persistent-disks.md new file mode 100644 index 0000000..3ba9242 --- /dev/null +++ b/skills/render-private-services/references/persistent-disks.md @@ -0,0 +1,29 @@ + +## Persistent disks + +Use this guidance only for service-attached persistent disks and for architecture or configuration decisions directly affected by them. Do not apply it to Render Postgres or Key Value storage, object storage, build caches, or ordinary ephemeral filesystem tasks. + +By default, a Render service's filesystem is ephemeral. Files created or changed at runtime are lost when the service is redeployed or restarted. Use a persistent disk only when a supported service must retain local filesystem data across those events. + +Before designing, configuring, or troubleshooting a persistent disk, fetch the current documentation: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/disks.md) or its [HTML version](https://render.com/docs/disks). + +Read the relevant sections before relying on details that can change, including supported service types, size limits and pricing, mount-path restrictions, snapshot cadence and retention, transfer methods, and current scaling or deployment limitations. If the document cannot be fetched, do not guess those details from memory. + +A persistent disk belongs to one service and is mounted at one absolute path. Only files written under that mount path persist; the rest of the service filesystem remains ephemeral. Make sure the application writes every intended durable file beneath the configured mount path. A disk is not shared storage, and another service cannot access it. + +Under the documented generally available behavior, a disk-backed service runs as a single instance and cannot use autoscaling or zero-downtime deploys. During a deploy, Render stops the existing instance before starting its replacement, so expect a short interruption. If the workload needs horizontal scaling, shared state, or stronger availability, use an external or managed datastore instead of a service-attached disk. + +The disk is available only to the running service. Builds, pre-deploy commands, and one-off jobs run on separate compute and cannot access it. Do not design a build step, pre-deploy command, or one-off job that depends on files stored on the mounted disk. + +The documented supported service types are paid web services, private services, and background workers. For other workload types, use an appropriate external datastore or reconsider the service architecture rather than assuming a disk can be attached. + +Disk capacity can be increased but not decreased. Confirm current limits and pricing in the fetched documentation, and choose capacity using observed usage plus reasonable headroom. + +Treat attaching, resizing, or restoring a disk as a stateful mutation. After attaching, verify that the service deploys successfully and that reads and writes use the mounted path. + +Snapshots are a disaster-recovery mechanism, not a substitute for application-consistent database backups. A snapshot restore replaces the entire disk; it cannot restore individual files, and it discards changes made after that snapshot. Do not use a disk snapshot to recover a custom database, because a filesystem-level snapshot can restore the database into an inconsistent or corrupted state. Use the database engine's native backup and restore tools instead. Check the current documentation before promising a particular snapshot schedule, retention period, or restore procedure. + +Mount paths must be absolute and must satisfy Render's current restrictions. Fetch the documentation instead of reproducing its forbidden-path list or runtime-specific path suggestions from memory. When declaring a disk in a Blueprint, also fetch the current Blueprint specification and follow its disk schema rather than relying on remembered syntax. + diff --git a/skills/render-private-services/references/private-networking.md b/skills/render-private-services/references/private-networking.md new file mode 100644 index 0000000..d68d6be --- /dev/null +++ b/skills/render-private-services/references/private-networking.md @@ -0,0 +1,25 @@ + +## Private networking + +Render services can communicate over a private network without traversing the public internet. Private-network peers must belong to the same workspace and run in the same region. An isolated project environment can additionally block traffic both to and from resources outside that environment, so workspace and region matching alone do not guarantee connectivity. + +Before designing, configuring, or troubleshooting private-network communication, fetch the current Render private-network reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/private-network.md) or its [HTML version](https://render.com/docs/private-network). + +Read the relevant sections. Confirm current service-type capabilities, port restrictions, environment-isolation behavior, discovery-hostname guidance, and plan requirements instead of relying on a memorized catalog. + +Web services and private services have internal hostnames and can receive private-network traffic. A private service must bind at least one port; use a background worker instead when a workload does not need to accept inbound connections. Render Postgres and Key Value instances provide internal connection URLs. Workflows, background workers, and cron jobs can initiate private-network connections but do not have an internal address for receiving them. Static sites are not on the private network. Free web services can initiate private-network connections but cannot receive them. + +Prefer the internal address or URL shown under **Connect > Internal** in the Render Dashboard. Include the protocol when the client or server requires one; an address such as `service:10000` does not by itself establish whether to use HTTP, HTTPS, or another protocol. A process that receives traffic must listen on the intended port and on an interface reachable outside its own container, such as `0.0.0.0`, rather than only on loopback. + +For Blueprint-managed connections, fetch the current Blueprint specification and use supported service or database references instead of copying a generated hostname, port, credential, or connection string. Web and private services currently expose `host`, `port`, and `hostport` properties. A Blueprint can obtain another service's discovery hostname by referencing that service's `RENDER_DISCOVERY_SERVICE` environment variable with `fromService.envVarKey`; the discovery hostname is not a service property. The fetched specification is authoritative for the syntax and supported references. + +A service can expose at most 75 ports on the private network. Ports `18012`, `18013`, and `19099` are unavailable for private-network communication. Port `10000` is not generally blocked: for a web service, private traffic to port `10000` routes to its primary HTTP server even when that server binds to another port. In that case, both port `10000` and the actual primary HTTP port route to the same server. + +Use a service's normal internal hostname for ordinary service-to-service traffic. For advanced per-instance communication, each web or private service has a discovery hostname, conventionally formed by appending `-discovery` to its internal hostname, that resolves to all active instance IP addresses. A service receives its own discovery hostname in `RENDER_DISCOVERY_SERVICE`. Use DNS APIs that honor the system resolver configuration, and do not persist resolved instance IPs because they can change between deploys. Prefer hostname-based communication unless per-instance addressing or custom load balancing is specifically required. + +When a private-network connection fails, verify the workspace, region, project-environment isolation settings, whether the destination service type accepts inbound traffic, the internal hostname or URL, protocol, port, listening interface, current deploy health, and DNS resolution. Do not substitute a public URL or expose a private service merely to bypass a private-network configuration problem. + +AWS PrivateLink is a separate Pro-or-higher feature for connecting a Render private network to compatible AWS-hosted systems. Fetch its current documentation before proposing or configuring it; do not treat ordinary Render service-to-service networking and PrivateLink as interchangeable. + diff --git a/skills/render-private-services/references/service-types.md b/skills/render-private-services/references/service-types.md new file mode 100644 index 0000000..a0a3786 --- /dev/null +++ b/skills/render-private-services/references/service-types.md @@ -0,0 +1,37 @@ + +## Render service types + +Use this guidance when selecting or comparing Render service types, or when a task's architecture depends on the distinction between them. A task that is already unambiguously scoped to one service type does not need this entire overview. + +On Render, a service represents code deployed for a particular execution model. Render runs that service on one or more instances, and the service's compute plan determines the CPU and memory available to each instance. + +Before choosing a service type, fetch the current service-types reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/service-types.md) or its [HTML version](https://render.com/docs/service-types). + +If neither version can be retrieved, use the bundled overview below only for basic service-type selection. State that current platform details could not be verified, and do not guess about changeable capabilities such as supported runtimes, plans, scaling, networking, disks, health checks, deployment behavior, availability, or limits. + +Render provides six public service types for running code: + +- **Web service:** A continuously running server that receives public HTTP traffic and also has an internal hostname for private-network traffic. Use it for dynamic websites, APIs, and other internet-facing server applications. +- **Static site:** Built HTML, CSS, JavaScript, and other static assets served publicly from Render's global CDN. Use it only when the deployed application does not require server-side runtime logic. +- **Private service:** A continuously running server that receives traffic only over Render's private network. Use it for internal HTTP, TCP, gRPC, or other server processes that need an internal hostname but no public URL. +- **Background worker:** A continuously running process that does not receive incoming traffic or expose a public or internal hostname. Use it for queue consumers and other processes that pull or poll for work. +- **Cron job:** A command or process that starts on a schedule, performs a bounded unit of work, and exits. Use it for straightforward recurring tasks rather than an always-running process. +- **Workflow:** A collection of on-demand tasks executed across distributed compute, with Render handling task queuing, orchestration, and provisioning. Use it when the workload benefits from independently invoked tasks, retries, composition, or parallel execution instead of a continuously running worker process. + +Choose based on how the code executes and receives work: + +- Public incoming traffic that requires server-side logic belongs on a web service. Public static assets with no runtime server belong on a static site. +- An application that needs both public and private ingress remains a web service; use its internal hostname for traffic from other Render services. +- A process that receives private-network requests belongs on a private service. A process that only initiates connections and pulls work belongs on a background worker. +- A simple scheduled command that exits belongs on a cron job. An always-running queue consumer belongs on a background worker. On-demand or distributed tasks for which Render should manage queuing and per-run compute belong in a workflow. + +Cron jobs and Workflows use invocation-based execution models. The ordinary instance-count and autoscaling model used by continuously running services does not apply to them. + +Render Postgres and Render Key Value are fully managed datastores, not general-purpose compute service types for running application code. Use Render Postgres for relational data and Render Key Value for use cases such as shared caching and job queues. An attached persistent disk is a storage feature of certain compute services, not a service type of its own. + +After selecting a type, fetch the product article linked from the service-types reference before relying on details such as supported runtimes and sources, plans, scaling, networking, disks, health checks, deployment behavior, scheduling semantics, availability, or limits. These capabilities are not uniform across service types and can change independently. + +Human-facing service names do not always map directly to configuration identifiers or structure. When creating or editing a Blueprint, fetch the current Blueprint specification and use its service-type schema instead of inferring fields or values from this overview. In particular, do not assume that every Dashboard service type has a same-named Blueprint `type` or that managed datastores are declared like compute services. + diff --git a/skills/render-scaling/SKILL.md b/skills/render-scaling/SKILL.md index eee0cc1..c7c56bd 100644 --- a/skills/render-scaling/SKILL.md +++ b/skills/render-scaling/SKILL.md @@ -2,9 +2,9 @@ name: render-scaling description: >- Scales Render services—configures autoscaling targets, chooses instance - types, sets manual instance counts, and optimizes cost. Use when the user - needs to handle more traffic, set up autoscaling, pick the right instance - type, reduce costs, or troubleshoot scaling behavior like slow scale-down or + compute plans, sets manual instance counts, and optimizes cost. Use when the + user needs to handle more traffic, set up autoscaling, pick the right compute + plan, reduce costs, or troubleshoot scaling behavior like slow scale-down or stuck instances. license: MIT compatibility: Render web services, private services, and background workers @@ -16,7 +16,9 @@ metadata: # Render Scaling -This skill covers how to scale **Web Services**, **Private Services**, and **Background Workers** on Render: manual instance counts, **Professional+** autoscaling, plan (instance type) choices, and platform limits. Deeper tables and tuning guidance live under `references/`. +This skill covers how to scale **Web Services**, **Private Services**, and **Background Workers** on Render: manual instance counts, autoscaling with a **Pro workspace or higher**, compute plan choices, and platform limits. Deeper guidance lives under `references/`. + +When a service has or might need an attached disk, read `references/persistent-disks.md` before choosing a scaling architecture. ## When to Use @@ -24,18 +26,20 @@ This skill covers how to scale **Web Services**, **Private Services**, and **Bac - Configuring **autoscaling** (min/max, CPU and memory targets) - Choosing **vertical** (plan) vs **horizontal** (more instances) scaling - Understanding **constraints** (disks, static sites, cron/workflows, 100-instance cap) -- **Cost** implications of multi-instance and per-second billing +- **Cost** implications of running more or larger instances - **Blueprint** fields: `numInstances`, `scaling`, `plan` ## Manual Scaling - Set **instance count** from **1 to 100** via the **Dashboard**, **CLI**, or **API**. -- **All instances share the same instance type** (plan); you cannot mix plans on one service. +- **All instances share the same compute plan**; you cannot mix plans on one service. - Changes apply **immediately**: Render **provisions** new instances and **deprovisions** excess capacity as needed. ## Autoscaling -- Available on **Professional and higher** workspaces only. +Before recommending an autoscaling policy, establish the service type, workspace plan, whether the service is stateless or has a disk, the desired minimum and maximum instance counts, and whether CPU or memory is the limiting resource. + +- Available only with a **Pro workspace or higher**. - Configure **minimum** and **maximum** instances and targets for **CPU** and/or **memory** utilization (**1–90%** each). - **At least one metric must be enabled** (CPU or memory). If **both** CPU and memory autoscaling toggles are **off**, autoscaling is **disabled**. - If **both** manual instance settings and autoscaling are configured, **autoscaling wins**—manual count does not override the scaling policy in effect. @@ -53,7 +57,7 @@ Render computes a candidate instance count from utilization vs target: | Constraint | Behavior | |------------|----------| | **Per service** | **Maximum 100** instances | -| **Persistent disk** | **Cannot** scale to multiple instances—**single instance only** | +| **Persistent disk** | **Cannot** scale to multiple instances—disk-attached services stay **single-instance** | | **Static sites** | **Not** scalable (served by CDN) | | **Cron jobs & Workflows** | Scaling model **does not apply** (different execution model) | @@ -62,25 +66,19 @@ Render computes a candidate instance count from utilization vs target: - **Scale-up** is **immediate** when utilization supports it. - **Scale-down** waits **a few minutes** after conditions allow reduction (**spike protection**). This reduces **flapping** from brief load spikes. -## Instance Types - -- In Blueprints, the instance type is the **`plan`** field (e.g. `standard`, `pro`). -- Options span **free** / **starter** through **standard**, **pro**, **pro_plus**, **pro_max**, **pro_ultra**—each with defined **CPU** and **RAM** (see `references/instance-types.md`). +## Compute Plans -### Vertical vs Horizontal - -| Need | Approach | When | -|------|----------|------| -| More throughput | **Horizontal** (add instances) | Stateless services, request-based workloads | -| More RAM/CPU per process | **Vertical** (upgrade **plan**) | Memory-intensive or single-threaded apps | -| Both | **Combine** | Right-size plan, then scale out for traffic | +- In Blueprints, the compute plan is set with the **`plan`** field. +- See `references/compute-plans.md` for current terminology, canonical plan discovery, and guidance on scaling up versus out. ## Cost Patterns -- **Per-second billing**; **no separate fee** for scaling actions. -- You pay roughly for **compute time × number of running instances** (see [Render pricing](https://render.com/pricing) for current rates). +- Scaling changes the amount of billable compute by changing the number and size of running instances. +- Confirm current compute charges at [Render pricing](https://render.com/pricing). - **Right-size** by monitoring **CPU and memory** utilization (see **render-monitor**). +Sustained low CPU and memory across every instance indicates likely over-provisioning. Consult `references/compute-plans.md`, then test a smaller current compute plan, fewer manually scaled instances, or autoscaling that can scale down toward an appropriate utilization target (approximately 70% CPU is a common starting point for CPU-bound services). Change one dimension at a time when practical, and verify CPU, memory, latency, and errors under representative production traffic before keeping the change. + ## Blueprint Configuration **Manual instance count:** @@ -99,10 +97,10 @@ scaling: targetMemoryPercent: 80 ``` -**Instance type (plan):** +**Compute plan:** ```yaml -plan: standard +plan: 1c-2g ``` Do not rely on `numInstances` to cap autoscaling when a `scaling` block is present—**autoscaling takes precedence**. Preview behavior for scaling is detailed in `references/autoscaling-guide.md`. @@ -111,7 +109,8 @@ Do not rely on `numInstances` to cap autoscaling when a `scaling` block is prese | Topic | File | |--------|------| -| Plan names, CPU/RAM, flexible vs non-flexible, free tier | `references/instance-types.md` | +| Compute plans and vertical vs horizontal scaling | `references/compute-plans.md` | +| Persistent disk constraints and storage alternatives | `references/persistent-disks.md` | | Enabling autoscaling, targets, min/max, mistakes, previews | `references/autoscaling-guide.md` | ## Related Skills @@ -120,3 +119,16 @@ Do not rely on `numInstances` to cap autoscaling when a `scaling` block is prese - **render-background-workers** — Worker-specific configuration and scaling context - **render-blueprints** — Full Blueprint schema and field reference - **render-monitor** — Metrics, logs, and utilization for right-sizing + + +## Current documentation retrieval + +Whenever this skill directs you to consult current Render documentation: + +1. Retrieve the linked Markdown document directly with an available URL-fetching tool or HTTP client, such as `curl`. Do not substitute web-search summaries for the document. +2. Confirm that retrieval succeeded and returned the expected document, then read its contents. Saving a file or printing its path is not sufficient. +3. If the request fails or your tool cannot read the Markdown response, open and read the linked HTML version instead. +4. If neither version can be retrieved, disclose that the current reference is unavailable and follow any topic-specific fallback in the skill. Use bundled guidance only for stable constraints, and do not guess at changeable platform details. + +When a task requires multiple references, apply this workflow to each one and distinguish the documents you verified from those that remain unavailable. + diff --git a/skills/render-scaling/references/autoscaling-guide.md b/skills/render-scaling/references/autoscaling-guide.md index efd117a..9738cbe 100644 --- a/skills/render-scaling/references/autoscaling-guide.md +++ b/skills/render-scaling/references/autoscaling-guide.md @@ -1,6 +1,6 @@ # Autoscaling configuration guide -Autoscaling on Render applies to **Web Services**, **Private Services**, and **Background Workers** on **Professional+** workspaces. It adjusts instance count between **min** and **max** based on **CPU** and/or **memory** utilization targets. +With a **Pro workspace or higher**, autoscaling on Render applies to **Web Services**, **Private Services**, and **Background Workers**. It adjusts instance count between **min** and **max** based on **CPU** and/or **memory** utilization targets. ## Enabling autoscaling diff --git a/skills/render-scaling/references/compute-plans.md b/skills/render-scaling/references/compute-plans.md new file mode 100644 index 0000000..98d73b5 --- /dev/null +++ b/skills/render-scaling/references/compute-plans.md @@ -0,0 +1,29 @@ + +## Compute plans + +A compute plan determines the CPU and RAM available to each instance of a Render service. Use **compute plan**, not the former term **instance type**. Do not confuse a service's compute plan with its workspace plan, which controls account-level features and limits. + +Compute plans differ by service type: + +- Web services, private services, background workers, and cron jobs use CPU-and-memory plan IDs such as `0.5c-512mb` and `1c-2g`. +- Render Postgres has its own plan catalog and connection limits. +- Render Key Value uses memory-based plan IDs such as `256mb` and `1g`. +- Workflow tasks select a compute plan in application code; a Workflow service does not set a Blueprint `plan`. +- Static sites do not have compute plans. + +Legacy plan names such as `starter`, `standard`, and `pro` remain valid in Render tooling, including Blueprints and API requests. For new configuration, prefer the current plan ID when the selected configuration surface accepts it. Before passing a plan to an API, MCP tool, or CLI command, inspect that operation's current schema or help and use one of its accepted values; the compute-plan reference describes the product catalog, not every tool version's input contract. Do not rename an existing legacy plan merely for consistency unless the user asks for that change. + +Do not rely on a memorized plan catalog. When a task depends on current plan IDs, specifications, defaults, availability, or pricing, fetch the canonical compute-plan reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/compute-plans.md) or its [HTML version](https://render.com/docs/compute-plans). + +Read the section for the relevant service type. If the document cannot be fetched, do not guess at current plan details. Preserve an existing valid plan where possible, or explain that the plan must be confirmed in the Render Dashboard or current documentation. + +When estimating capacity or cost, remember that every instance of a scaled service uses the selected compute plan and is billed accordingly. Changing the compute plan for Render Postgres, Render Key Value, or a service with an attached persistent disk requires brief downtime; other services normally apply the change with a zero-downtime deploy. + + +## When to scale up vs. out + +- **Scale up** to a larger compute plan for memory-intensive applications, single-process or single-threaded architectures, and workloads that need more CPU per request or a larger heap without sharding. +- **Scale out** to more instances for stateless request handlers, high concurrency, and workloads that distribute evenly across identical processes. +- **Combine both approaches** by starting with a right-sized compute plan and adding horizontal scaling as traffic grows. Avoid multiplying undersized instances when every process needs substantial RAM. diff --git a/skills/render-scaling/references/instance-types.md b/skills/render-scaling/references/instance-types.md deleted file mode 100644 index ca8d9a9..0000000 --- a/skills/render-scaling/references/instance-types.md +++ /dev/null @@ -1,35 +0,0 @@ -# Instance types on Render - -Approximate **plan** specs for Web Services, Private Services, and Background Workers. **Prices change**—verify at [Render pricing](https://render.com/pricing). - -## Plan and spec table - -| Plan | CPU | RAM | Monthly Base | -|------|-----|-----|--------------| -| free | Shared | 512 MB | $0 | -| starter | Shared | 512 MB | $7 | -| starter_plus | 1 | 1 GB | $13 | -| standard | 1 | 2 GB | $25 | -| standard_plus | 2 | 4 GB | $50 | -| pro | 4 | 8 GB | $95 | -| pro_plus | 8 | 16 GB | $175 | -| pro_max | 16 | 32 GB | $350 | -| pro_ultra | 32 | 64 GB | $700 | - -> **Note:** Monthly figures are **approximate** and may not match your invoice (usage, proration, and promotions differ). Always use [render.com/pricing](https://render.com/pricing) for authoritative rates. - -## Flexible vs non-flexible plans - -Some plans are **flexible** (usable in mixed configurations such as **preview environments** alongside other instance types where the platform allows it); others are **non-flexible**. Exact flexible-plan rules depend on workspace and product updates—confirm in the Dashboard or docs when mixing preview and production instance types. - -## When to scale up vs out - -- **Scale up** (larger **plan**): **Memory-intensive** apps, **single-process** or **single-threaded** architectures, workloads that need **more CPU per request** or **larger heap** without sharding. -- **Scale out** (more **instances**): **Stateless** request handlers, **high concurrency**, **even load distribution** across identical processes. -- **Both**: Start with a **right-sized plan**, then add **horizontal** scaling as traffic grows. Avoid tiny instances multiplied many times if each process needs substantial RAM. - -## Free tier limitations - -- **Single instance** for the service. -- Web services **spin down after inactivity** (cold starts on the next request). -- **Limited** CPU and memory vs paid plans—treat free-tier behavior as distinct when advising on performance and scaling. diff --git a/skills/render-scaling/references/persistent-disks.md b/skills/render-scaling/references/persistent-disks.md new file mode 100644 index 0000000..3ba9242 --- /dev/null +++ b/skills/render-scaling/references/persistent-disks.md @@ -0,0 +1,29 @@ + +## Persistent disks + +Use this guidance only for service-attached persistent disks and for architecture or configuration decisions directly affected by them. Do not apply it to Render Postgres or Key Value storage, object storage, build caches, or ordinary ephemeral filesystem tasks. + +By default, a Render service's filesystem is ephemeral. Files created or changed at runtime are lost when the service is redeployed or restarted. Use a persistent disk only when a supported service must retain local filesystem data across those events. + +Before designing, configuring, or troubleshooting a persistent disk, fetch the current documentation: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/disks.md) or its [HTML version](https://render.com/docs/disks). + +Read the relevant sections before relying on details that can change, including supported service types, size limits and pricing, mount-path restrictions, snapshot cadence and retention, transfer methods, and current scaling or deployment limitations. If the document cannot be fetched, do not guess those details from memory. + +A persistent disk belongs to one service and is mounted at one absolute path. Only files written under that mount path persist; the rest of the service filesystem remains ephemeral. Make sure the application writes every intended durable file beneath the configured mount path. A disk is not shared storage, and another service cannot access it. + +Under the documented generally available behavior, a disk-backed service runs as a single instance and cannot use autoscaling or zero-downtime deploys. During a deploy, Render stops the existing instance before starting its replacement, so expect a short interruption. If the workload needs horizontal scaling, shared state, or stronger availability, use an external or managed datastore instead of a service-attached disk. + +The disk is available only to the running service. Builds, pre-deploy commands, and one-off jobs run on separate compute and cannot access it. Do not design a build step, pre-deploy command, or one-off job that depends on files stored on the mounted disk. + +The documented supported service types are paid web services, private services, and background workers. For other workload types, use an appropriate external datastore or reconsider the service architecture rather than assuming a disk can be attached. + +Disk capacity can be increased but not decreased. Confirm current limits and pricing in the fetched documentation, and choose capacity using observed usage plus reasonable headroom. + +Treat attaching, resizing, or restoring a disk as a stateful mutation. After attaching, verify that the service deploys successfully and that reads and writes use the mounted path. + +Snapshots are a disaster-recovery mechanism, not a substitute for application-consistent database backups. A snapshot restore replaces the entire disk; it cannot restore individual files, and it discards changes made after that snapshot. Do not use a disk snapshot to recover a custom database, because a filesystem-level snapshot can restore the database into an inconsistent or corrupted state. Use the database engine's native backup and restore tools instead. Check the current documentation before promising a particular snapshot schedule, retention period, or restore procedure. + +Mount paths must be absolute and must satisfy Render's current restrictions. Fetch the documentation instead of reproducing its forbidden-path list or runtime-specific path suggestions from memory. When declaring a disk in a Blueprint, also fetch the current Blueprint specification and follow its disk schema rather than relying on remembered syntax. + diff --git a/skills/render-static-sites/SKILL.md b/skills/render-static-sites/SKILL.md index f062473..d1aa492 100644 --- a/skills/render-static-sites/SKILL.md +++ b/skills/render-static-sites/SKILL.md @@ -31,6 +31,8 @@ Deploys static frontends (React, Vue, Hugo, Gatsby, Docusaurus, Jekyll, etc.) to For SSR frameworks (Next.js, Nuxt, SvelteKit) that need a running server, use **render-web-services** instead. For Blueprint authoring, see **render-blueprints**. +When choosing between a static site and a web service, read `references/service-types.md`. + ## Static Site vs Web Service | Need | Use | Why | @@ -133,7 +135,7 @@ services: - **Brotli compression** (better than gzip) - **HTTP/2** by default - **Immediate cache invalidation** on every deploy (zero-downtime, atomic deploys) -- **DDoS protection** included free +- **DDoS protection** included ## Billing @@ -142,12 +144,15 @@ Static sites have a **free tier**. They count against workspace-level monthly in - **Outbound bandwidth** (data served to users) - **Pipeline minutes** (build time) +Usage beyond included allowances can incur additional cost. Confirm current allowances and charges at [Render pricing](https://render.com/pricing). + ## References | Document | Contents | |----------|----------| | `references/routing-and-headers.md` | Redirect types, rewrite rules, header patterns, SPA config | | `references/framework-configs.md` | Build commands and publish paths for 10+ frameworks | +| `references/service-types.md` | Service-type selection and execution models | ## Related Skills @@ -155,3 +160,16 @@ Static sites have a **free tier**. They count against workspace-level monthly in - **render-blueprints** — Full `render.yaml` schema for static site fields - **render-domains** — Custom domain and TLS setup - **render-deploy** — Deploy flows, CLI, MCP operations + + +## Current documentation retrieval + +Whenever this skill directs you to consult current Render documentation: + +1. Retrieve the linked Markdown document directly with an available URL-fetching tool or HTTP client, such as `curl`. Do not substitute web-search summaries for the document. +2. Confirm that retrieval succeeded and returned the expected document, then read its contents. Saving a file or printing its path is not sufficient. +3. If the request fails or your tool cannot read the Markdown response, open and read the linked HTML version instead. +4. If neither version can be retrieved, disclose that the current reference is unavailable and follow any topic-specific fallback in the skill. Use bundled guidance only for stable constraints, and do not guess at changeable platform details. + +When a task requires multiple references, apply this workflow to each one and distinguish the documents you verified from those that remain unavailable. + diff --git a/skills/render-static-sites/references/service-types.md b/skills/render-static-sites/references/service-types.md new file mode 100644 index 0000000..a0a3786 --- /dev/null +++ b/skills/render-static-sites/references/service-types.md @@ -0,0 +1,37 @@ + +## Render service types + +Use this guidance when selecting or comparing Render service types, or when a task's architecture depends on the distinction between them. A task that is already unambiguously scoped to one service type does not need this entire overview. + +On Render, a service represents code deployed for a particular execution model. Render runs that service on one or more instances, and the service's compute plan determines the CPU and memory available to each instance. + +Before choosing a service type, fetch the current service-types reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/service-types.md) or its [HTML version](https://render.com/docs/service-types). + +If neither version can be retrieved, use the bundled overview below only for basic service-type selection. State that current platform details could not be verified, and do not guess about changeable capabilities such as supported runtimes, plans, scaling, networking, disks, health checks, deployment behavior, availability, or limits. + +Render provides six public service types for running code: + +- **Web service:** A continuously running server that receives public HTTP traffic and also has an internal hostname for private-network traffic. Use it for dynamic websites, APIs, and other internet-facing server applications. +- **Static site:** Built HTML, CSS, JavaScript, and other static assets served publicly from Render's global CDN. Use it only when the deployed application does not require server-side runtime logic. +- **Private service:** A continuously running server that receives traffic only over Render's private network. Use it for internal HTTP, TCP, gRPC, or other server processes that need an internal hostname but no public URL. +- **Background worker:** A continuously running process that does not receive incoming traffic or expose a public or internal hostname. Use it for queue consumers and other processes that pull or poll for work. +- **Cron job:** A command or process that starts on a schedule, performs a bounded unit of work, and exits. Use it for straightforward recurring tasks rather than an always-running process. +- **Workflow:** A collection of on-demand tasks executed across distributed compute, with Render handling task queuing, orchestration, and provisioning. Use it when the workload benefits from independently invoked tasks, retries, composition, or parallel execution instead of a continuously running worker process. + +Choose based on how the code executes and receives work: + +- Public incoming traffic that requires server-side logic belongs on a web service. Public static assets with no runtime server belong on a static site. +- An application that needs both public and private ingress remains a web service; use its internal hostname for traffic from other Render services. +- A process that receives private-network requests belongs on a private service. A process that only initiates connections and pulls work belongs on a background worker. +- A simple scheduled command that exits belongs on a cron job. An always-running queue consumer belongs on a background worker. On-demand or distributed tasks for which Render should manage queuing and per-run compute belong in a workflow. + +Cron jobs and Workflows use invocation-based execution models. The ordinary instance-count and autoscaling model used by continuously running services does not apply to them. + +Render Postgres and Render Key Value are fully managed datastores, not general-purpose compute service types for running application code. Use Render Postgres for relational data and Render Key Value for use cases such as shared caching and job queues. An attached persistent disk is a storage feature of certain compute services, not a service type of its own. + +After selecting a type, fetch the product article linked from the service-types reference before relying on details such as supported runtimes and sources, plans, scaling, networking, disks, health checks, deployment behavior, scheduling semantics, availability, or limits. These capabilities are not uniform across service types and can change independently. + +Human-facing service names do not always map directly to configuration identifiers or structure. When creating or editing a Blueprint, fetch the current Blueprint specification and use its service-type schema instead of inferring fields or values from this overview. In particular, do not assume that every Dashboard service type has a same-named Blueprint `type` or that managed datastores are declared like compute services. + diff --git a/skills/render-web-services/SKILL.md b/skills/render-web-services/SKILL.md index f08911f..4da3686 100644 --- a/skills/render-web-services/SKILL.md +++ b/skills/render-web-services/SKILL.md @@ -30,6 +30,10 @@ This skill covers **Web Service** behavior on Render: how traffic reaches your p Deeper patterns live under `references/` (health checks, domains, deploy phases). +Before configuring or troubleshooting deploys and health checks, read `references/deployments.md`. +Before attaching or changing a persistent disk, read `references/persistent-disks.md`. +Before configuring or troubleshooting private connectivity or additional ports, read `references/private-networking.md`. + ## Port Binding - Listen on **`0.0.0.0`** (all interfaces). Binding only to **`localhost`** or **`127.0.0.1`** prevents Render’s proxy from reaching your app. @@ -49,11 +53,7 @@ Deeper patterns live under `references/` (health checks, domains, deploy phases) ## Health Checks -- Configure a path via **`healthCheckPath`** in a Blueprint or the **Health Check Path** field in the Dashboard. -- Render issues **HTTP GET** requests to that path. Responses must be **`2xx` or `3xx`** for success. -- **Failed health checks** prevent a new deploy from **going live** (the deploy does not succeed in taking production traffic as expected). -- Render probes on a **repeat interval** with a per-request **timeout**; both are **configurable** in service settings (see Dashboard). Failed checks during rollout prevent the new revision from receiving traffic. -- Check frequency, timeouts, and tuning guidance in `references/health-check-patterns.md`. +Follow `references/deployments.md` for current platform behavior. For endpoint implementations and common failure patterns, see `references/health-check-patterns.md`. ## Custom Domains @@ -67,37 +67,24 @@ See `references/custom-domains.md` for Dashboard steps, verification, and troubl ## Auto-Deploy and PR Previews -- **`autoDeployTrigger`** (Blueprint) / auto-deploy settings control when production deploys run: - - **`commit`** — deploy on every push to the tracked branch - - **`checksPass`** — deploy only when required **Git checks** pass - - **`off`** — **manual** deploys only (Dashboard, CLI, hooks) +- Follow `references/deployments.md` for auto-deploy behavior and manual triggers. - **PR previews** are configured under Blueprint **`previews.generation`** (and related preview settings); generation behavior depends on repo integration and plan. ## Persistent Disks -- Attach disks via the **`disk`** field in a Blueprint (or equivalent Dashboard storage settings). -- A service with an attached persistent disk is **single-instance** only: **horizontal scaling** is not available in that configuration. -- **Zero-downtime deploys are disabled** when a persistent disk is attached—deploys follow a different rollout pattern. -- **Disk size increases** are allowed; **decreases** are not. -- The disk is **not mounted during the build phase**—only at **runtime** in the running service. +- A disk-backed web service stays **single-instance** and cannot scale horizontally. +- Attaching a disk disables **zero-downtime deploys**. +- The disk is available only to the running service, not during builds or pre-deploy commands. +- If the workload needs horizontal scaling or uninterrupted deploys, use shared external storage instead of a service-attached disk. +- Follow `references/persistent-disks.md` for current support, configuration, mount-path, runtime-access, sizing, and snapshot behavior. ## Deploy Lifecycle -Typical flow: - -1. **Build** — clone repo, run **`buildCommand`**, produce the runnable artifact/image. -2. **Pre-deploy command** (optional) — runs in the **new** image **before** traffic switches; use for **migrations**. If it **fails**, the deploy is **canceled**. -3. **Deploy** — new instances start; health checks must pass before traffic moves. -4. **Zero-downtime swap** (when applicable) — traffic shifts to new instances; **old instances drain** in-flight work. - -- **`maxShutdownDelaySeconds`** (range **1–300**, **default 30**) bounds how long old instances may continue handling requests during drain before shutdown. -- **Rollbacks** — revert to a **previous successful deploy** from the Dashboard. - -Full sequence, hooks, filters, and CLI notes: `references/deploy-lifecycle.md`. +For paid web services, use `preDeployCommand` for database migrations and other release tasks that must succeed before the new version receives traffic. It runs after the build on separate compute; if it fails, the deploy is canceled and the previous live version continues serving. Follow `references/deployments.md` for the full build, readiness, traffic-switching, draining, rollback, restart, and deploy-hook behavior. ## Free Tier Notes -Free Web Services have **separate limits**: e.g. **no custom domains** on the free instance type, and services **spin down after inactivity** (cold starts on next request). Treat free-tier behavior as distinct from paid Web Service defaults when advising on domains, uptime, and scaling. +Free Web Services have **separate limits**: services **spin down after inactivity** (cold starts on the next request), and they do not support scaling beyond a single instance or persistent disks. Treat free-tier behavior as distinct from paid Web Service defaults when advising on uptime and scaling. ## References @@ -105,7 +92,9 @@ Free Web Services have **separate limits**: e.g. **no custom domains** on the fr |--------|------| | Health check design, timeouts, pitfalls | `references/health-check-patterns.md` | | Domains, DNS, TLS verification | `references/custom-domains.md` | -| Build, pre-deploy, drain, rollbacks, triggers | `references/deploy-lifecycle.md` | +| Deploy lifecycle, health checks, rollback, triggers | `references/deployments.md` | +| Persistent disk constraints and configuration | `references/persistent-disks.md` | +| Private-network addressing, ports, discovery, and troubleshooting | `references/private-networking.md` | ## Related Skills @@ -113,3 +102,16 @@ Free Web Services have **separate limits**: e.g. **no custom domains** on the fr - **render-docker** — Docker-based Web Services and image/runtime details - **render-networking** — Private network, internal URLs, multi-port private listeners - **render-scaling** — Instance counts, plans, and scaling constraints (including disk interactions) + + +## Current documentation retrieval + +Whenever this skill directs you to consult current Render documentation: + +1. Retrieve the linked Markdown document directly with an available URL-fetching tool or HTTP client, such as `curl`. Do not substitute web-search summaries for the document. +2. Confirm that retrieval succeeded and returned the expected document, then read its contents. Saving a file or printing its path is not sufficient. +3. If the request fails or your tool cannot read the Markdown response, open and read the linked HTML version instead. +4. If neither version can be retrieved, disclose that the current reference is unavailable and follow any topic-specific fallback in the skill. Use bundled guidance only for stable constraints, and do not guess at changeable platform details. + +When a task requires multiple references, apply this workflow to each one and distinguish the documents you verified from those that remain unavailable. + diff --git a/skills/render-web-services/references/custom-domains.md b/skills/render-web-services/references/custom-domains.md index 3419d45..3cee76e 100644 --- a/skills/render-web-services/references/custom-domains.md +++ b/skills/render-web-services/references/custom-domains.md @@ -56,5 +56,3 @@ domains: | Certificate pending or invalid | Verification not complete; **conflicting** A/AAAA/CNAME records | | Wrong site | CNAME points to a **different** `[service-name].onrender.com` | | Apex not working | Provider lacks **flattening**; use **www** or ALIAS/ANAME | - -**Free tier:** Custom domains are **not** available on free Web Service instance types—use a paid instance type for custom hostnames. diff --git a/skills/render-web-services/references/deploy-lifecycle.md b/skills/render-web-services/references/deploy-lifecycle.md deleted file mode 100644 index 2079285..0000000 --- a/skills/render-web-services/references/deploy-lifecycle.md +++ /dev/null @@ -1,87 +0,0 @@ -# Web Service deploy lifecycle on Render - -This document expands on **build → pre-deploy → new instances → health check → traffic switch → drain** for Web Services. - -## Build phase - -- Render **clones** the repository at the configured **branch/commit**. -- Runs **`buildCommand`** (or the default for the environment). -- Output is a **build artifact** or image used for the **runtime** container. - -The **persistent disk** (if any) is **not** available during build—do not assume mounted paths from disks exist in the build environment. - -## Pre-deploy command - -- Optional **`preDeployCommand`** runs in the **new** image **before** production traffic moves to new instances. -- Typical use: **database migrations**, one-off schema updates, or validation that must pass before serving traffic. -- If the command **exits non-zero** (fails), the **deploy is canceled**; the previous live revision remains serving (subject to product behavior at the time). - -## Zero-downtime deploy (when enabled) - -For services **without** attached persistent disks (and subject to plan/type rules): - -1. **New instances** start from the new build. -2. **Health checks** must pass for the new revision. -3. **Traffic switches** to healthy new instances. -4. **Old instances drain** in-flight requests, then shut down. - -With a **persistent disk**, zero-downtime deploys are **disabled**; expect a different rollout (single instance, swap behavior per platform docs). - -## Graceful shutdown and `maxShutdownDelaySeconds` - -- **`maxShutdownDelaySeconds`** controls how long **old instances** may continue handling requests during drain before shutdown (allowed range **1–300**, **default 30**). -- Tune upward if requests are **long-lived** (large uploads, slow streaming) so clients see fewer hard cuts; tune downward if you need faster replacement (understand tradeoffs). - -## Rollback - -- From the **Dashboard**, you can **revert** to a **previous successful deploy** when something misbehaves after a release. -- Prefer rollbacks for bad config or failed migrations only after understanding **data** compatibility (migrations may be one-way). - -## Auto-deploy triggers - -Blueprint / service settings use **`autoDeployTrigger`** (or Dashboard equivalents): - -| Value | Behavior | -|--------|----------| -| **`commit`** | Deploy on every push to the **connected branch** | -| **`checksPass`** | Deploy only when required **Git provider checks** pass | -| **`off`** | **Manual** deploys only | - -Pair with branch protection and CI so **`checksPass`** matches your org’s quality gates. - -## Build filters - -- Configure **path filters** so builds run only when certain paths change (reduces noise and build minutes). -- Exact YAML keys depend on your Blueprint version; align with current Render Blueprint docs when generating `render.yaml`. - -## Manual deploy - -- Trigger from the **Dashboard** (Manual Deploy). -- CLI: **`render deploys create`** (with correct service context and authentication)—useful in scripts and non-Git triggers. - -## Deploy hooks - -- **Webhook URLs** can **trigger deploys** when called (e.g. from external CI or release systems). -- Secure hooks (secrets, allowlists) and avoid exposing them in public repos. - -## PR previews - -- Controlled via Blueprint **`previews.generation`** and related settings; previews spin up **ephemeral** service instances for pull requests when enabled and connected to the repo. - -## Mental model - -```text -push / hook / manual - ↓ - BUILD (no disk mount) - ↓ - PRE-DEPLOY (new image; optional) - ↓ - NEW INSTANCES + HEALTH CHECKS - ↓ - TRAFFIC SWITCH (if healthy) - ↓ - OLD INSTANCES DRAIN (maxShutdownDelaySeconds) -``` - -Use **`healthCheckPath`** and **`PORT`** correctness as the first line of defense when deploys “succeed” in the UI but never take traffic. diff --git a/skills/render-web-services/references/deployments.md b/skills/render-web-services/references/deployments.md new file mode 100644 index 0000000..295e0b6 --- /dev/null +++ b/skills/render-web-services/references/deployments.md @@ -0,0 +1,58 @@ + +## Deployments and health checks + +A Render deploy is asynchronous. A successful trigger means only that Render accepted or queued the deploy; it does not mean the new version is live. Before triggering a deploy, confirm the workspace, service, intended source commit or image, and current live deploy. Capture the new deploy ID, monitor it to a terminal state, and do not report success until its status is `live` and the deployed workload has been verified. + +Before configuring or troubleshooting deployments and health checks, fetch the current Render references: + +- [deploys.md](https://render.com/docs/deploys.md) (HTML: ) +- [health-checks.md](https://render.com/docs/health-checks.md) (HTML: ) + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read both references. + +Read the relevant sections of both documents. Confirm current service-type support, command timeouts, health-check thresholds, rollout behavior, and configuration syntax rather than relying on remembered values. + +Automatic deployment behavior depends on the service's source and settings. A service linked to a branch through a connected Git provider can deploy on each commit, wait for supported CI checks, or require manual triggers. Services that pull a prebuilt image and services linked by a public Git repository URL require manual deploys; moving a mutable image tag does not itself trigger one. When manually deploying a historical commit, verify whether that trigger method changes automatic-deploy settings. If automatic deploys remain enabled, a later branch update can replace the selected commit. + +The normal lifecycle is build command, optional pre-deploy command, then start command and readiness checks. If a command fails or times out, the deploy fails and later steps do not run. A pre-deploy command runs after the build on a separate instance before the new version is deployed. Neither the build nor pre-deploy instance can access an attached persistent disk, and pre-deploy filesystem changes do not carry into the running service. Use pre-deploy for release tasks such as database migrations, not for producing runtime artifacts. Pre-deploy commands are supported for paid web services, private services, and background workers. + +Render normally deploys services without downtime by starting the new version before retiring the current one. Web and private services continue routing traffic to the current instances until the new instances are ready. Multi-instance services roll out one instance at a time; if a replacement does not become healthy, Render cancels the rollout and retains or restores the previous version. Attaching a persistent disk disables zero-downtime deploys, so plan explicitly for an interruption. + +A workflow deployment has a different completion model. It builds and caches the image used by future task runs and includes a task-registration step, but it does not execute those tasks. After a workflow deploy succeeds, verify that the expected task definitions are registered. Trigger and monitor a task run separately only when execution is intended. For workflow-specific deployment behavior, fetch the current workflow overview: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/workflows.md) or its [HTML version](https://render.com/docs/workflows). + +Health checks apply to web services and private services. Both use TCP socket checks by default. Only web services support a configured HTTP health-check path. Render sends an HTTP `GET`; any `2xx` or `3xx` response received within five seconds succeeds, while other status codes, timeouts, and connection failures fail. Private services support TCP checks only. + +For a new deploy, all new instances must pass their checks at the same time within the current readiness window, documented as 15 minutes, before Render routes traffic to them. For a running service, consecutive failures currently remove an instance from routing after 15 seconds and restart it after 60 seconds. Treat these thresholds as platform behavior, not user-tunable health-check interval settings, and verify them in the fetched reference before relying on exact timing. + +Design an HTTP health endpoint to represent readiness for production traffic. Keep it fast and side-effect free. Check critical dependencies only when losing that dependency should make the entire instance unavailable; otherwise a transient dependency failure can unnecessarily remove healthy application capacity. Verify the configured path, response status, response time, listening port, and `0.0.0.0` binding when checks fail. + +After traffic moves, Render gives the previous instance a drain period, then sends `SIGTERM`. The application should stop accepting new work, finish or safely abandon in-flight work, close connections, and exit within its shutdown delay. Ensure the actual application process receives the signal: container entrypoints and shell wrappers should use `exec` or explicitly forward signals. Render sends `SIGKILL` if the process remains running after the delay. The documented default shutdown delay is 30 seconds and the usual maximum is 300 seconds, but support varies by service configuration; confirm the current reference and Blueprint or API validation before setting `maxShutdownDelaySeconds`. + +A service restart is a special deploy of the same commit and user-defined environment-variable values as the current running instance. It does not incorporate configuration changes saved after that deploy. Use a standard deploy when pending configuration must take effect. + +Only one deploy runs at a time for a service. A workspace's overlapping-deploy policy determines whether a new trigger waits or cancels the in-progress deploy. Do not assume the policy or wait for every intermediate revision: inspect the workspace setting and identify the deploy that actually became live. + +Treat rollback as a new deploy based on a retained previous build artifact, not as restoration of the entire service to an earlier point in time. It does not reverse database migrations, messages, external writes, or other side effects from the release, so confirm that the previous application version remains compatible with current external state. Disks and their data are not rolled back, some settings continue using current configuration, mutable image tags can resolve to a different image, and eligible artifacts are retained only for a limited period. Before rolling back, fetch the current rollback reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/rollbacks.md) or its [HTML version](https://render.com/docs/rollbacks). + +Read which configuration comes from the target deploy and which remains current. After the rollback is created, inspect the service's resulting automatic-deploy setting instead of assuming whether it remains enabled, and deliberately restore the intended setting after the underlying issue is resolved. + +Deploy hooks are secret credentials that authorize deploys. Never print, commit, or expose their full URLs. Before using one, fetch the current deploy-hook reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/deploy-hooks.md) or its [HTML version](https://render.com/docs/deploy-hooks). + +Distinguish an immediately started deploy from a queued one, and continue monitoring the resulting deploy rather than treating the HTTP response as completion. + +After a deploy becomes live, verify the behavior appropriate to the service type: make a request to a web or private service, confirm a worker is processing work, confirm a cron job or workflow invocation completes, and inspect recent runtime logs for new errors. If a deploy fails, diagnose the first failed lifecycle stage before retrying. + + +## Web-service-specific guidance + +- Pair CI-gated automatic deploys with branch protection so the required checks match the repository's intended release gates. +- Configure build filters when only changes to particular paths should trigger a build. Fetch the current Blueprint specification before choosing the YAML fields. +- PR previews are configured with the current Blueprint preview settings and require a connected repository. Fetch the current Blueprint specification before writing that configuration. +- For long-lived requests such as large uploads or streams, choose a shutdown delay that gives in-flight requests time to finish. A shorter delay replaces instances faster but can interrupt more requests. +- Manual deploys can be triggered from the Dashboard or supported CLI, API, and hook flows. Consult the current CLI command reference or local `render deploys --help` output before constructing a command. diff --git a/skills/render-web-services/references/health-check-patterns.md b/skills/render-web-services/references/health-check-patterns.md index d1ce8bc..56754c8 100644 --- a/skills/render-web-services/references/health-check-patterns.md +++ b/skills/render-web-services/references/health-check-patterns.md @@ -1,6 +1,6 @@ # Health check patterns for Render Web Services -Render uses an HTTP **GET** to your configured **`healthCheckPath`**. The response must be **`2xx` or `3xx`**. Anything else (including **`4xx`**, **`5xx`**, timeouts, or connection failures) counts as **unhealthy** and can **block a deploy from going live** or trigger rollback behavior. +Read [deployments.md](deployments.md) first for current Render health-check behavior, timing, and deploy effects. This reference focuses on application endpoint design. ## Endpoint design @@ -60,12 +60,6 @@ async fn health() -> impl Responder { } ``` -## Timeouts and tuning - -- If the app **starts listening after** the health check window expects readiness, deploys may **fail or roll back**. -- **Slow-starting** apps (large JVM warmup, many workers): ensure the **listen** happens as early as possible, or **increase** health check **timeout** / **interval** in settings if the platform allows—so the first successful check occurs after the server is truly up. -- A failing dependency check (DB down) will keep the service **unhealthy**; that is often correct for **readiness** but harsh if you only wanted **liveness**. Prefer **readiness** semantics for Render’s path unless you have a reason not to. - ## Common issues | Symptom | Likely cause | diff --git a/skills/render-web-services/references/persistent-disks.md b/skills/render-web-services/references/persistent-disks.md new file mode 100644 index 0000000..3ba9242 --- /dev/null +++ b/skills/render-web-services/references/persistent-disks.md @@ -0,0 +1,29 @@ + +## Persistent disks + +Use this guidance only for service-attached persistent disks and for architecture or configuration decisions directly affected by them. Do not apply it to Render Postgres or Key Value storage, object storage, build caches, or ordinary ephemeral filesystem tasks. + +By default, a Render service's filesystem is ephemeral. Files created or changed at runtime are lost when the service is redeployed or restarted. Use a persistent disk only when a supported service must retain local filesystem data across those events. + +Before designing, configuring, or troubleshooting a persistent disk, fetch the current documentation: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/disks.md) or its [HTML version](https://render.com/docs/disks). + +Read the relevant sections before relying on details that can change, including supported service types, size limits and pricing, mount-path restrictions, snapshot cadence and retention, transfer methods, and current scaling or deployment limitations. If the document cannot be fetched, do not guess those details from memory. + +A persistent disk belongs to one service and is mounted at one absolute path. Only files written under that mount path persist; the rest of the service filesystem remains ephemeral. Make sure the application writes every intended durable file beneath the configured mount path. A disk is not shared storage, and another service cannot access it. + +Under the documented generally available behavior, a disk-backed service runs as a single instance and cannot use autoscaling or zero-downtime deploys. During a deploy, Render stops the existing instance before starting its replacement, so expect a short interruption. If the workload needs horizontal scaling, shared state, or stronger availability, use an external or managed datastore instead of a service-attached disk. + +The disk is available only to the running service. Builds, pre-deploy commands, and one-off jobs run on separate compute and cannot access it. Do not design a build step, pre-deploy command, or one-off job that depends on files stored on the mounted disk. + +The documented supported service types are paid web services, private services, and background workers. For other workload types, use an appropriate external datastore or reconsider the service architecture rather than assuming a disk can be attached. + +Disk capacity can be increased but not decreased. Confirm current limits and pricing in the fetched documentation, and choose capacity using observed usage plus reasonable headroom. + +Treat attaching, resizing, or restoring a disk as a stateful mutation. After attaching, verify that the service deploys successfully and that reads and writes use the mounted path. + +Snapshots are a disaster-recovery mechanism, not a substitute for application-consistent database backups. A snapshot restore replaces the entire disk; it cannot restore individual files, and it discards changes made after that snapshot. Do not use a disk snapshot to recover a custom database, because a filesystem-level snapshot can restore the database into an inconsistent or corrupted state. Use the database engine's native backup and restore tools instead. Check the current documentation before promising a particular snapshot schedule, retention period, or restore procedure. + +Mount paths must be absolute and must satisfy Render's current restrictions. Fetch the documentation instead of reproducing its forbidden-path list or runtime-specific path suggestions from memory. When declaring a disk in a Blueprint, also fetch the current Blueprint specification and follow its disk schema rather than relying on remembered syntax. + diff --git a/skills/render-web-services/references/private-networking.md b/skills/render-web-services/references/private-networking.md new file mode 100644 index 0000000..d68d6be --- /dev/null +++ b/skills/render-web-services/references/private-networking.md @@ -0,0 +1,25 @@ + +## Private networking + +Render services can communicate over a private network without traversing the public internet. Private-network peers must belong to the same workspace and run in the same region. An isolated project environment can additionally block traffic both to and from resources outside that environment, so workspace and region matching alone do not guarantee connectivity. + +Before designing, configuring, or troubleshooting private-network communication, fetch the current Render private-network reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/private-network.md) or its [HTML version](https://render.com/docs/private-network). + +Read the relevant sections. Confirm current service-type capabilities, port restrictions, environment-isolation behavior, discovery-hostname guidance, and plan requirements instead of relying on a memorized catalog. + +Web services and private services have internal hostnames and can receive private-network traffic. A private service must bind at least one port; use a background worker instead when a workload does not need to accept inbound connections. Render Postgres and Key Value instances provide internal connection URLs. Workflows, background workers, and cron jobs can initiate private-network connections but do not have an internal address for receiving them. Static sites are not on the private network. Free web services can initiate private-network connections but cannot receive them. + +Prefer the internal address or URL shown under **Connect > Internal** in the Render Dashboard. Include the protocol when the client or server requires one; an address such as `service:10000` does not by itself establish whether to use HTTP, HTTPS, or another protocol. A process that receives traffic must listen on the intended port and on an interface reachable outside its own container, such as `0.0.0.0`, rather than only on loopback. + +For Blueprint-managed connections, fetch the current Blueprint specification and use supported service or database references instead of copying a generated hostname, port, credential, or connection string. Web and private services currently expose `host`, `port`, and `hostport` properties. A Blueprint can obtain another service's discovery hostname by referencing that service's `RENDER_DISCOVERY_SERVICE` environment variable with `fromService.envVarKey`; the discovery hostname is not a service property. The fetched specification is authoritative for the syntax and supported references. + +A service can expose at most 75 ports on the private network. Ports `18012`, `18013`, and `19099` are unavailable for private-network communication. Port `10000` is not generally blocked: for a web service, private traffic to port `10000` routes to its primary HTTP server even when that server binds to another port. In that case, both port `10000` and the actual primary HTTP port route to the same server. + +Use a service's normal internal hostname for ordinary service-to-service traffic. For advanced per-instance communication, each web or private service has a discovery hostname, conventionally formed by appending `-discovery` to its internal hostname, that resolves to all active instance IP addresses. A service receives its own discovery hostname in `RENDER_DISCOVERY_SERVICE`. Use DNS APIs that honor the system resolver configuration, and do not persist resolved instance IPs because they can change between deploys. Prefer hostname-based communication unless per-instance addressing or custom load balancing is specifically required. + +When a private-network connection fails, verify the workspace, region, project-environment isolation settings, whether the destination service type accepts inbound traffic, the internal hostname or URL, protocol, port, listening interface, current deploy health, and DNS resolution. Do not substitute a public URL or expose a private service merely to bypass a private-network configuration problem. + +AWS PrivateLink is a separate Pro-or-higher feature for connecting a Render private network to compatible AWS-hosted systems. Fetch its current documentation before proposing or configuring it; do not treat ordinary Render service-to-service networking and PrivateLink as interchangeable. + diff --git a/skills/render-workflows/SKILL.md b/skills/render-workflows/SKILL.md index 7a8ed48..032203a 100644 --- a/skills/render-workflows/SKILL.md +++ b/skills/render-workflows/SKILL.md @@ -1,145 +1,262 @@ --- name: render-workflows -description: Sets up, develops, tests, and deploys Render Workflows. Covers first-time scaffolding (via CLI or manual), SDK installation (Python or TypeScript), task patterns (retries, subtasks, fan-out), local development, Dashboard deployment, and troubleshooting. Use when a user wants to set up Render Workflows for the first time, scaffold a workflow service, add or modify workflow tasks, test workflows locally, or deploy workflows to Render. +description: >- + Build, validate locally, deploy, and troubleshoot Render Workflows with the + current Python or TypeScript SDK. Use for defining or chaining tasks, + integrating the SDK into an existing project, running tasks with the local + development server, optionally scaffolding a starter, authoring + "type: workflow" in render.yaml, triggering runs from application code, and + releasing workflows. license: MIT -compatibility: Requires Render CLI 2.11.0+ for scaffolding and local development. Render Dashboard required for deployment (Blueprints not yet supported for Workflows). +compatibility: >- + Requires Render SDK 1.x. Local validation requires Render CLI 2.12.0+; + optional scaffolding and CLI deployment require Render CLI 2.16.0+. + Blueprints support "type: workflow" (no service-level plan). metadata: author: Render - version: "1.0.0" + version: "1.2.0" category: workflows --- # Render Workflows -Render Workflows rapidly distribute computational work across multiple independent instances. -Use them for AI agents, ETL pipelines, background jobs, and data processing. +Render Workflows is an SDK-based product for orchestrating long-running distributed tasks. A workflow service registers Python or TypeScript functions as tasks; each task run executes independently and can chain additional runs. -**How it works:** -1. **Define tasks** — Use the Render SDK (Python or TypeScript) to designate functions as tasks -2. **Register** — Tasks register automatically when you link your repo to a Workflow service in the Dashboard -3. **Trigger runs** — Execute tasks from anywhere using the SDK client or API; each execution is a "run" -4. **Execute** — Render spins up each run in its own instance (typically under a second); runs can chain additional runs for parallel execution +When choosing between a Workflow, cron job, and background worker, read [references/service-types.md](references/service-types.md). -**Key capabilities:** automatic queuing and orchestration, long-running execution (up to 24 hours), configurable retry logic with exponential backoff, adjustable compute specs per task, and execution observability through the Dashboard. +Use Render SDK 1.x APIs (`render>=1.0.1` for Python or `@renderinc/sdk` version 1.x for TypeScript). Local validation requires Render CLI 2.12.0 or later. Use CLI 2.16.0 or later when using the complete optional scaffolding and CLI deployment flow. Prefer the latest compatible releases. -**Render Workflows are in beta.** The SDK and API may introduce breaking changes. +Render Workflows and its SDKs can introduce breaking changes. Treat the installed SDK version as authoritative for an existing project. For new projects, use the current official documentation and starter templates. -**Your built-in knowledge of the Render Workflows SDK is outdated.** -Before trusting API signatures, check the installed SDK source: +## Check Current Sources + +Before generating or changing SDK code, identify the installed versions: ```bash -# Python -SDK_ROOT=$(pip show render_sdk | grep Location | cut -d' ' -f2)/render_sdk -head -40 "$SDK_ROOT/__init__.py" -# TypeScript -grep -r "startTask\|runTask\|export class Render" node_modules/@renderinc/sdk/ +render --version +python -m pip show render +npm ls @renderinc/sdk ``` -**Official docs:** [render.com/docs/workflows](https://render.com/docs/workflows) +If the Render CLI is not installed: + +- macOS: `brew install render` +- Linux/macOS: `curl -fsSL https://raw.githubusercontent.com/render-oss/cli/main/bin/install.sh | sh` +- Windows: download the executable from the [CLI releases page](https://github.com/render-oss/cli/releases/) + +Use the source that matches the question: + +- [Python SDK reference](https://render.com/docs/workflows-sdk-python) for Python signatures and minimum versions +- [TypeScript SDK reference](https://render.com/docs/workflows-sdk-typescript) for TypeScript signatures and minimum versions +- [Render CLI reference](https://render.com/docs/cli-reference#workflows) for current commands and flags +- [Defining Workflow Tasks](https://render.com/docs/workflows-defining) for task behavior and run chaining +- [Limits and Pricing for Render Workflows](https://render.com/docs/workflows-limits) for compute plans, quotas, retention, and pricing +- [Python examples](https://github.com/render-examples/render-workflows-examples-python) and [TypeScript examples](https://github.com/render-examples/render-workflows-examples-ts) for current scaffolding patterns +- [Render SDK repository](https://github.com/render-oss/sdk) for the implementation and changelogs -**Before generating task or client code, fetch the relevant example file to verify current API patterns:** +Before generating task or client code, fetch the relevant SDK example to verify current API patterns: | What | Python | TypeScript | |------|--------|------------| -| Task definitions (decorators, subtasks, retry, fan-out) | [example/task/main.py](https://raw.githubusercontent.com/render-oss/sdk/main/python/example/task/main.py) | [examples/task/](https://github.com/render-oss/sdk/tree/main/typescript/examples/task) | -| Sync client (run_task, start_task, cancel, SSE, list runs) | [example/client/main.py](https://raw.githubusercontent.com/render-oss/sdk/main/python/example/client/main.py) | [examples/client/](https://github.com/render-oss/sdk/tree/main/typescript/examples/client) | +| Task definitions (subtasks, retry, fan-out) | [example/task/main.py](https://raw.githubusercontent.com/render-oss/sdk/main/python/example/task/main.py) | [examples/task/](https://github.com/render-oss/sdk/tree/main/typescript/examples/task) | +| Client (run, start, cancel, stream, list runs) | [example/client/main.py](https://raw.githubusercontent.com/render-oss/sdk/main/python/example/client/main.py) | [examples/client/](https://github.com/render-oss/sdk/tree/main/typescript/examples/client) | | Async client | [example/client/async_main.py](https://raw.githubusercontent.com/render-oss/sdk/main/python/example/client/async_main.py) | — | -This skill carries a [quick-reference cheat sheet](references/quick-reference.md) for the API surface. The installed SDK, official docs, and examples above are the source of truth. +Do not silently upgrade an existing project's SDK major version. If an upgrade is part of the request, read the relevant SDK changelog and migrate all task definitions and callers together. ---- +## SDK 1.x Invariants + +Preserve these rules in generated code: -## Getting Started +- Python installs and imports the `render` package, not `render_sdk`. +- Every task function accepts a `TaskContext` as its first positional parameter. Render supplies it; callers do not include it in task input. +- Chain a task run with `await ctx.run(task_definition, ...args)`. A task definition is not directly callable. +- All tasks in a `ctx.run` chain belong to the same workflow service. Trigger another workflow through the SDK client or Render API. +- Python calls `app.start()` from its workflow entrypoint. TypeScript task registration auto-starts in the workflow environment. +- Task arguments and return values must be JSON-serializable. -Supported languages: **Python** and **TypeScript**. +Read [references/quick-reference.md](references/quick-reference.md) when writing SDK code. Read [references/task-patterns.md](references/task-patterns.md) for chaining, fan-out, retries, scheduled triggers, or cross-workflow calls. -### Prerequisites +## Choose a Starting Point -**Render CLI (required)** +Do not require `render workflows init`. In an existing codebase, add the SDK and task definitions directly, preserve the project's dependency and build conventions, and validate them with the local development server. For a minimal project or direct integration guidance, read [references/manual-scaffolding.md](references/manual-scaffolding.md). + +### Optional starter scaffolding + +Use the CLI scaffolder when the user wants a quick example project or a new standalone workflow service: ```bash -render --version +render workflows init ``` -Requires version 2.11.0+. If not installed: -- macOS: `brew install render` -- Linux/macOS: `curl -fsSL https://raw.githubusercontent.com/render-oss/cli/main/bin/install.sh | sh` -- Windows: download the executable from the [CLI releases page](https://github.com/render-oss/cli/releases/) +For non-interactive setup, pass the language and destination explicitly: -### Scaffold a new workflow service +```bash +render workflows init --confirm --language python --dir workflows --git=false +render workflows init --confirm --language node --dir workflows --git=false +``` -**Always prefer `render workflows init` as the primary setup path.** Only fall back to manual scaffolding if the CLI command is unavailable. +Use `--git=false` when scaffolding inside an existing Git repository to avoid creating a nested repository. Other useful options include `--template`, `--install-deps`, and `--install-agent-skill`; verify current behavior in the CLI reference. + +## Try It Locally with the SDK + +For a first integration, follow the runnable Python or TypeScript [local SDK walkthrough](references/manual-scaffolding.md#try-it-locally-with-the-sdk): define `ping`, start the local task server, invoke it from a separate client script, and verify the returned `"pong"`. No `init`, deployment, or Render API key is needed for this local example. Set local mode in the calling application process, not only in the task server's environment. + +After adding or changing SDK task definitions, use the local development server as the primary validation loop. Start it with the workflow's actual start command: ```bash -render workflows init +render workflows dev -- ``` -**Interactive mode** (default): walks the user through scaffolding an example project, testing it locally, and deploying it to Render. +In another terminal, list and run tasks against the local server: -**Non-interactive mode**: sets up an example project without prompting. +```bash +render workflows tasks list --local +render workflows start --local --input='[]' -o json +render workflows tasks runs show --local -o json +``` -If `render workflows init` fails or is not available: -- **Command not found:** CLI version may be too old. Run `render --version` and upgrade to 2.11.0+. -- **Command not supported:** fall back to [references/manual-scaffolding.md](references/manual-scaffolding.md) for step-by-step manual setup. +If a task doesn't appear in the local task list, see [Troubleshooting > Local task list is empty or missing tasks](references/troubleshooting.md#local-task-list-is-empty-or-missing-tasks). ---- +Use a JSON array for positional input. Python tasks can also receive a JSON object for named input. Read [references/local-development.md](references/local-development.md) for environment files, custom ports, run inspection, cancellation, and application-client configuration. + +In non-interactive mode, `workflows start` returns the new task run ID before the run necessarily finishes. Use that ID with `tasks runs show`, polling for a bounded period until the run completes, fails, or is canceled. Verify the result or error, not only that the run was created. -## Define Tasks +When safe and practical, run this verification yourself and stop the dev server afterward. Do not claim a task registers successfully based only on source inspection. -Guide the user through defining their actual tasks. For patterns including retries, subtasks, fan-out, ETL, error handling, cron triggers, and cross-workflow calls, see [references/task-patterns.md](references/task-patterns.md). +## Deploy After Local Validation + +Creating or releasing a workflow changes the user's Render account. Only do it when deployment is part of the request and the tasks have been validated locally when local execution is supported. + +Before deploying or interpreting deploy status, read [references/deployments.md](references/deployments.md), including its Workflow-specific task-registration behavior. + +Before deploying, authenticate and confirm the target workspace: -**After adding a task**, verify it registers by starting the local dev server and listing tasks: ```bash -render workflows dev -- -# In another terminal: -render workflows tasks list --local +render whoami +render workspace current +``` + +If authentication is missing, use `render login` for an interactive local session or provide `RENDER_API_KEY` through the environment for automation. Never print the key. + +Confirm the intended branch and region, and ensure the exact code to deploy is committed and pushed to GitHub, GitLab, or Bitbucket. Neither path deploys uncommitted local changes. + +Two creation paths. MCP supports neither. + +| Path | Use when | Runtimes | +|------|----------|----------| +| Blueprint (`render.yaml`) | The repo uses IaC, or the workflow ships beside other Render services | `python`, `node` | +| `render workflows create` or Dashboard | Standalone workflow with no Blueprint | `python`, `node`, `go`, `ruby`, `elixir`, plus Docker in the Dashboard only | + +### Deploy with a Blueprint (preferred) + +Do **not** set `plan` on a workflow service. Task compute is configured in code (`plan` on the task), not on the service. + +```yaml +services: + - type: workflow + name: my-workflow + runtime: python + region: oregon + repo: https://github.com/render-examples/render-workflows-examples-python + branch: main + rootDir: hello-world + buildCommand: pip install -r requirements.txt + startCommand: python main.py + envVars: + - key: RENDER_API_KEY + sync: false ``` -If the task doesn't appear, see [Troubleshooting > Task Registration Issues](references/troubleshooting.md#task-registration-issues). +TypeScript variant: `runtime: node`, `buildCommand: npm install`, and a `startCommand` that runs the project's workflow entrypoint. The TypeScript starter uses `npm start` (`tsx src/main.ts`); the manual setup in [references/manual-scaffolding.md](references/manual-scaffolding.md) uses `npm run workflows:start`. Match both commands to the scripts in `package.json`. Use `npm run build` and `node dist/main.js` only if the project defines a `build` script that emits `dist/main.js`. + +Required: `type`, `name`, `runtime`, `region`, `startCommand`, plus `buildCommand` and `repo`. Optional: `branch`, `rootDir`, `buildFilter`, `autoDeployTrigger`, `envVars` (applied to every task run). + +The schema's `required` array lists only the first five. Do not treat it as the complete set: the validator also rejects a workflow missing `buildCommand` or `repo`. -## Local Development +- `buildCommand is required for non-docker workflows`. Only Docker-based workflows omit a build command, and those cannot appear in a Blueprint, so a Blueprint workflow always needs one. +- `repo is required for git-based services`. This fires even when validating from inside that repository with an `origin` remote, which is not how `web` and other Git-based types behave. -See [references/local-development.md](references/local-development.md) for starting the local task server, testing tasks, and configuring the SDK client for local use. +Caveats: -## Deploy to Render +- Preview environments skip workflow services. Other Blueprint resources still replicate. +- Render rejects a Blueprint that would create a workflow with the same name as an existing Blueprint-managed workflow in the workspace. +- The [Workflows intro FAQ](https://render.com/docs/workflows) may still say Blueprints cannot manage workflows. That is stale. Follow the [changelog](https://render.com/changelog/added-blueprint-support-for-render-workflows) and `https://render.com/schema/render.yaml.json`. -Workflows are deployed as a **Workflow** service type in the Render Dashboard. **Blueprints (render.yaml) are not yet compatible with Workflows.** +Validate before applying: -**Deploy checklist:** +```bash +render blueprints validate +``` + +A passing validate is not proof a runtime is supported. `render blueprints validate` currently accepts `runtime: docker` on a workflow even though the schema rejects it. -- [ ] Code pushed to GitHub, GitLab, or Bitbucket -- [ ] In the [Render Dashboard](https://dashboard.render.com), click **New > Workflow** -- [ ] Link your repository -- [ ] Set **Root Directory** to `workflows/` -- [ ] Configure build and start commands (see table below) -- [ ] Add environment variables (e.g., `RENDER_API_KEY` for tasks that call other workflows) -- [ ] Click **Deploy Workflow** -- [ ] Verify deployment: check the Dashboard for a successful deploy event +Pair with **render-blueprints** for wiring and **render-deploy** for the apply/deeplink flow. -| Field | Python | TypeScript | -|-------|--------|------------| -| **Language** | Python 3 | Node | -| **Build Command** | `pip install -r requirements.txt` | `npm install && npm run build` | -| **Start Command** | `python main.py` | `node dist/main.js` | +### Create with the CLI or Dashboard -If the deploy fails, check the service logs in the Dashboard. For common deployment errors, see [Troubleshooting](references/troubleshooting.md). For general deploy debugging, use the **render-debug** skill. +Use this for a standalone workflow with no Blueprint. Interactive mode prompts for configuration: -**Running tasks from other services:** +```bash +render workflows create +``` -After deployment, trigger tasks from your other Render services using the SDK client. +Non-interactive, using the build and run commands from the starter template or the project's existing configuration: + +```bash +render workflows create \ + --name my-workflow \ + --repo . \ + --branch \ + --region \ + --runtime python \ + --build-command "pip install -r requirements.txt" \ + --run-command "python main.py" +``` + +`--repo .` resolves the repository's remote. For a workflow in a subdirectory, add `--root-directory`. Environment variables can be supplied with repeatable `--env-file` and `--env-var` flags. Never expose secrets in commands or output. + +A workflow can build from a Dockerfile, but only through the Dashboard (**New > Workflow**): [the CLI and API cannot create one](https://render.com/docs/workflows-tutorial#docker-specific-limitations), and neither can a Blueprint. Docker-based workflows take no build command and cannot run against the local task server. No creation path can pull a prebuilt registry image. + +For later explicit releases, use: + +```bash +render workflows versions release \ + --commit \ + --wait +``` + +Do not report deployment success from command acceptance alone. Wait for the release, then verify that the expected tasks registered and that one safe task reaches a terminal state with the expected result: + +```bash +render workflows versions list -o text +render workflows tasks list -o text +render workflows start / --input='[]' -o json +render workflows tasks runs show -o json +``` + +Poll `tasks runs show` for a bounded period if the run is still queued or running. Stop and report the release or task error instead of retrying an external mutation indefinitely. + +If deployment fails, read [references/troubleshooting.md](references/troubleshooting.md). Use the `render-debug` skill for broader Render deployment diagnosis when it is available. + +## Trigger Deployed Tasks + +Task slugs use `{workflow-slug}/{task-name}`. + +Python, synchronous: -Python (synchronous): ```python -from render_sdk import Render +from render import Render render = Render() result = render.workflows.run_task("my-workflow/hello", ["world"]) print(result.results) ``` -Python (asynchronous): +Python, asynchronous: + ```python -from render_sdk import RenderAsync +from render import RenderAsync render = RenderAsync() started = await render.workflows.start_task("my-workflow/hello", ["world"]) @@ -148,6 +265,7 @@ print(finished.results) ``` TypeScript: + ```typescript import { Render } from "@renderinc/sdk"; @@ -157,54 +275,43 @@ const finished = await started.get(); console.log(finished.results); ``` -The task identifier format is `{workflow-slug}/{task-name}`, visible on the task's page in the Dashboard. +These clients use `RENDER_API_KEY` unless a token is passed explicitly. Prefer environment variables or a secret manager over hard-coded credentials. -Workflows do not have built-in scheduling. To trigger tasks on a schedule, use a Render cron job with the SDK client. For cron and cross-workflow examples, see [references/task-patterns.md](references/task-patterns.md). +Workflows do not currently provide native scheduled triggers. Use a Render cron job that invokes the SDK client or API when scheduling is required. ---- +## Limits, Compute Plans, and Pricing -## Constraints and Limits +Do not hard-code compute-plan IDs, resource specifications, quotas, retention periods, or prices in this skill or its references. -| Constraint | Limit | Notes | -|------------|-------|-------| -| Arguments and return values | Must be JSON-serializable | No class instances, functions, etc. | -| Argument size | 4 MB max | Per task invocation | -| Task definitions | 500 per workflow service | | -| Concurrent runs | 20-100 base (plan-dependent) | Max 200-300 with purchased concurrency | -| Timeout range | 30-86,400 seconds | Default: 2 hours (7,200s) | -| Run duration | Up to 24 hours | | +Before setting a task's `plan`, estimating cost, or advising on capacity, consult [references/compute-plans.md](references/compute-plans.md) and [Limits and Pricing for Render Workflows](https://render.com/docs/workflows-limits). Keep only API-shape constraints needed to write correct code in the skill. -### Instance Types - -| Plan | Specs | -|------|-------| -| `starter` | 0.5 CPU / 512 MB | -| `standard` (default) | 1 CPU / 2 GB | -| `pro` | 2 CPU / 4 GB | -| `pro_plus` | 4 CPU / 8 GB | -| `pro_max` | 8 CPU / 16 GB | -| `pro_ultra` | 16 CPU / 32 GB | +## References -`pro_plus`, `pro_max`, and `pro_ultra` require requesting access. Set via the `plan` task option. +- [references/quick-reference.md](references/quick-reference.md): SDK 1.x task and client surface +- [references/compute-plans.md](references/compute-plans.md): current compute-plan guidance for task `plan` values +- [references/deployments.md](references/deployments.md): deploy lifecycle and Workflow task registration +- [references/service-types.md](references/service-types.md): choosing between Workflows and other service types +- [references/task-patterns.md](references/task-patterns.md): chaining, fan-out, retries, cron triggers, and cross-workflow calls +- [references/local-development.md](references/local-development.md): local server, CLI runs, environment configuration, and limitations +- [references/troubleshooting.md](references/troubleshooting.md): common setup, registration, execution, and client failures +- [references/manual-scaffolding.md](references/manual-scaffolding.md): direct SDK project setup without `workflows init` -For current pricing, see [Limits and Pricing for Render Workflows](https://render.com/docs/workflows-limits). +## Related Skills ---- +- `render-blueprints`: `type: workflow` in `render.yaml`, previews, wiring +- `render-deploy`: Blueprint apply flow for multi-service apps that include a workflow +- `render-debug`: diagnose deployment and runtime failures +- `render-monitor`: inspect service health and performance -## References + +## Current documentation retrieval -- **Quick-reference cheat sheet:** [references/quick-reference.md](references/quick-reference.md) (API surface, env vars, error types) -- **Task patterns:** [references/task-patterns.md](references/task-patterns.md) -- **Local development:** [references/local-development.md](references/local-development.md) -- **Troubleshooting:** [references/troubleshooting.md](references/troubleshooting.md) -- **Manual scaffolding (fallback):** [references/manual-scaffolding.md](references/manual-scaffolding.md) -- **Official docs:** [render.com/docs/workflows](https://render.com/docs/workflows) -- **Starter template (Python):** [render-examples/workflows-template-python](https://github.com/render-examples/workflows-template-python) -- **Starter template (TypeScript):** [render-examples/workflows-template-ts](https://github.com/render-examples/workflows-template-ts) -- **SDK repo:** [github.com/render-oss/sdk](https://github.com/render-oss/sdk) +Whenever this skill directs you to consult current Render documentation: -## Related Skills +1. Retrieve the linked Markdown document directly with an available URL-fetching tool or HTTP client, such as `curl`. Do not substitute web-search summaries for the document. +2. Confirm that retrieval succeeded and returned the expected document, then read its contents. Saving a file or printing its path is not sufficient. +3. If the request fails or your tool cannot read the Markdown response, open and read the linked HTML version instead. +4. If neither version can be retrieved, disclose that the current reference is unavailable and follow any topic-specific fallback in the skill. Use bundled guidance only for stable constraints, and do not guess at changeable platform details. -- **render-deploy:** Deploy web services, static sites, and databases -- **render-debug:** Debug failed deployments and runtime errors -- **render-monitor:** Monitor service health and performance +When a task requires multiple references, apply this workflow to each one and distinguish the documents you verified from those that remain unavailable. + diff --git a/skills/render-workflows/references/compute-plans.md b/skills/render-workflows/references/compute-plans.md new file mode 100644 index 0000000..5d0ccc1 --- /dev/null +++ b/skills/render-workflows/references/compute-plans.md @@ -0,0 +1,23 @@ + +## Compute plans + +A compute plan determines the CPU and RAM available to each instance of a Render service. Use **compute plan**, not the former term **instance type**. Do not confuse a service's compute plan with its workspace plan, which controls account-level features and limits. + +Compute plans differ by service type: + +- Web services, private services, background workers, and cron jobs use CPU-and-memory plan IDs such as `0.5c-512mb` and `1c-2g`. +- Render Postgres has its own plan catalog and connection limits. +- Render Key Value uses memory-based plan IDs such as `256mb` and `1g`. +- Workflow tasks select a compute plan in application code; a Workflow service does not set a Blueprint `plan`. +- Static sites do not have compute plans. + +Legacy plan names such as `starter`, `standard`, and `pro` remain valid in Render tooling, including Blueprints and API requests. For new configuration, prefer the current plan ID when the selected configuration surface accepts it. Before passing a plan to an API, MCP tool, or CLI command, inspect that operation's current schema or help and use one of its accepted values; the compute-plan reference describes the product catalog, not every tool version's input contract. Do not rename an existing legacy plan merely for consistency unless the user asks for that change. + +Do not rely on a memorized plan catalog. When a task depends on current plan IDs, specifications, defaults, availability, or pricing, fetch the canonical compute-plan reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/compute-plans.md) or its [HTML version](https://render.com/docs/compute-plans). + +Read the section for the relevant service type. If the document cannot be fetched, do not guess at current plan details. Preserve an existing valid plan where possible, or explain that the plan must be confirmed in the Render Dashboard or current documentation. + +When estimating capacity or cost, remember that every instance of a scaled service uses the selected compute plan and is billed accordingly. Changing the compute plan for Render Postgres, Render Key Value, or a service with an attached persistent disk requires brief downtime; other services normally apply the change with a zero-downtime deploy. + diff --git a/skills/render-workflows/references/deployments.md b/skills/render-workflows/references/deployments.md new file mode 100644 index 0000000..5ca9905 --- /dev/null +++ b/skills/render-workflows/references/deployments.md @@ -0,0 +1,50 @@ + +## Deployments and health checks + +A Render deploy is asynchronous. A successful trigger means only that Render accepted or queued the deploy; it does not mean the new version is live. Before triggering a deploy, confirm the workspace, service, intended source commit or image, and current live deploy. Capture the new deploy ID, monitor it to a terminal state, and do not report success until its status is `live` and the deployed workload has been verified. + +Before configuring or troubleshooting deployments and health checks, fetch the current Render references: + +- [deploys.md](https://render.com/docs/deploys.md) (HTML: ) +- [health-checks.md](https://render.com/docs/health-checks.md) (HTML: ) + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read both references. + +Read the relevant sections of both documents. Confirm current service-type support, command timeouts, health-check thresholds, rollout behavior, and configuration syntax rather than relying on remembered values. + +Automatic deployment behavior depends on the service's source and settings. A service linked to a branch through a connected Git provider can deploy on each commit, wait for supported CI checks, or require manual triggers. Services that pull a prebuilt image and services linked by a public Git repository URL require manual deploys; moving a mutable image tag does not itself trigger one. When manually deploying a historical commit, verify whether that trigger method changes automatic-deploy settings. If automatic deploys remain enabled, a later branch update can replace the selected commit. + +The normal lifecycle is build command, optional pre-deploy command, then start command and readiness checks. If a command fails or times out, the deploy fails and later steps do not run. A pre-deploy command runs after the build on a separate instance before the new version is deployed. Neither the build nor pre-deploy instance can access an attached persistent disk, and pre-deploy filesystem changes do not carry into the running service. Use pre-deploy for release tasks such as database migrations, not for producing runtime artifacts. Pre-deploy commands are supported for paid web services, private services, and background workers. + +Render normally deploys services without downtime by starting the new version before retiring the current one. Web and private services continue routing traffic to the current instances until the new instances are ready. Multi-instance services roll out one instance at a time; if a replacement does not become healthy, Render cancels the rollout and retains or restores the previous version. Attaching a persistent disk disables zero-downtime deploys, so plan explicitly for an interruption. + +A workflow deployment has a different completion model. It builds and caches the image used by future task runs and includes a task-registration step, but it does not execute those tasks. After a workflow deploy succeeds, verify that the expected task definitions are registered. Trigger and monitor a task run separately only when execution is intended. For workflow-specific deployment behavior, fetch the current workflow overview: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/workflows.md) or its [HTML version](https://render.com/docs/workflows). + +Health checks apply to web services and private services. Both use TCP socket checks by default. Only web services support a configured HTTP health-check path. Render sends an HTTP `GET`; any `2xx` or `3xx` response received within five seconds succeeds, while other status codes, timeouts, and connection failures fail. Private services support TCP checks only. + +For a new deploy, all new instances must pass their checks at the same time within the current readiness window, documented as 15 minutes, before Render routes traffic to them. For a running service, consecutive failures currently remove an instance from routing after 15 seconds and restart it after 60 seconds. Treat these thresholds as platform behavior, not user-tunable health-check interval settings, and verify them in the fetched reference before relying on exact timing. + +Design an HTTP health endpoint to represent readiness for production traffic. Keep it fast and side-effect free. Check critical dependencies only when losing that dependency should make the entire instance unavailable; otherwise a transient dependency failure can unnecessarily remove healthy application capacity. Verify the configured path, response status, response time, listening port, and `0.0.0.0` binding when checks fail. + +After traffic moves, Render gives the previous instance a drain period, then sends `SIGTERM`. The application should stop accepting new work, finish or safely abandon in-flight work, close connections, and exit within its shutdown delay. Ensure the actual application process receives the signal: container entrypoints and shell wrappers should use `exec` or explicitly forward signals. Render sends `SIGKILL` if the process remains running after the delay. The documented default shutdown delay is 30 seconds and the usual maximum is 300 seconds, but support varies by service configuration; confirm the current reference and Blueprint or API validation before setting `maxShutdownDelaySeconds`. + +A service restart is a special deploy of the same commit and user-defined environment-variable values as the current running instance. It does not incorporate configuration changes saved after that deploy. Use a standard deploy when pending configuration must take effect. + +Only one deploy runs at a time for a service. A workspace's overlapping-deploy policy determines whether a new trigger waits or cancels the in-progress deploy. Do not assume the policy or wait for every intermediate revision: inspect the workspace setting and identify the deploy that actually became live. + +Treat rollback as a new deploy based on a retained previous build artifact, not as restoration of the entire service to an earlier point in time. It does not reverse database migrations, messages, external writes, or other side effects from the release, so confirm that the previous application version remains compatible with current external state. Disks and their data are not rolled back, some settings continue using current configuration, mutable image tags can resolve to a different image, and eligible artifacts are retained only for a limited period. Before rolling back, fetch the current rollback reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/rollbacks.md) or its [HTML version](https://render.com/docs/rollbacks). + +Read which configuration comes from the target deploy and which remains current. After the rollback is created, inspect the service's resulting automatic-deploy setting instead of assuming whether it remains enabled, and deliberately restore the intended setting after the underlying issue is resolved. + +Deploy hooks are secret credentials that authorize deploys. Never print, commit, or expose their full URLs. Before using one, fetch the current deploy-hook reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/deploy-hooks.md) or its [HTML version](https://render.com/docs/deploy-hooks). + +Distinguish an immediately started deploy from a queued one, and continue monitoring the resulting deploy rather than treating the HTTP response as completion. + +After a deploy becomes live, verify the behavior appropriate to the service type: make a request to a web or private service, confirm a worker is processing work, confirm a cron job or workflow invocation completes, and inspect recent runtime logs for new errors. If a deploy fails, diagnose the first failed lifecycle stage before retrying. + diff --git a/skills/render-workflows/references/local-development.md b/skills/render-workflows/references/local-development.md index 46fbf80..4e32c41 100644 --- a/skills/render-workflows/references/local-development.md +++ b/skills/render-workflows/references/local-development.md @@ -1,116 +1,106 @@ # Local Development -Run workflow tasks locally for faster development and testing. - -## Contents - -- Prerequisites -- Starting the local task server -- Triggering task runs (CLI and application code) -- Viewing results -- Limitations +Use the Render CLI's local task server to register and run tasks without deploying. Read the current [local development documentation](https://render.com/docs/workflows-local-development) when behavior differs from this reference. ## Prerequisites -- **Render CLI 2.11.0+**: `render --version` - - macOS: `brew install render` - - Linux/macOS: `curl -fsSL https://raw.githubusercontent.com/render-oss/cli/main/bin/install.sh | sh` - - Windows: download the executable from the [CLI releases page](https://github.com/render-oss/cli/releases/) -- A workflow project with registered tasks +- Render CLI 2.12.0 or later for local development; this skill recommends 2.16.0 or later for the complete scaffolding and deployment flow +- A Python or TypeScript workflow project with its dependencies installed +- A non-Docker workflow start command; Docker-based workflows do not currently support the local task server -## Starting the Local Task Server +## Start the Local Task Server -From your project directory: +Run from the workflow project's root directory: ```bash # Python -render workflows dev -- python workflows/main.py +render workflows dev -- python main.py -# TypeScript -render workflows dev -- npx tsx workflows/main.ts +# TypeScript starter +render workflows dev -- npm start ``` -The local server starts on port `8120`. Customize with `--port`: +The default port is `8120`. Use the same custom port on every related CLI command: ```bash -render workflows dev --port 8121 -- python workflows/main.py +render workflows dev --port 8121 -- python main.py +render workflows tasks list --local --port 8121 ``` -The server picks up code changes automatically as you iterate. +The CLI loads `.env` from the current directory automatically. To load explicit files, pass `--env-file` more than once if needed; later files override earlier files: + +```bash +render workflows dev \ + --env-file .env \ + --env-file .env.local \ + -- python main.py +``` -## Triggering Task Runs +Use `--debug` when task execution events are needed for diagnosis. -### From the CLI +## Run and Inspect Tasks -List and run tasks interactively: +Interactive task browser: ```bash render workflows tasks list --local ``` -**The `--local` flag is required.** Without it, the CLI lists deployed (remote) tasks. +Non-interactive flow: -The interactive menu lets you: -1. Select a task -2. Choose `run` -3. Provide input as a JSON array (e.g., `[5]` or `[]`) -4. View live logs +```bash +render workflows tasks list --local -o text +render workflows start calculate_square --local --input='[5]' -o text +render workflows tasks runs list calculate_square --local -o text +render workflows tasks runs show --local -o json +render workflows cancel --local +``` -### From Application Code +Use `-o text`, `-o json`, or `-o yaml` to disable menu navigation. The canonical long form of `render workflows start` is `render workflows tasks runs start`; the canonical long form of `cancel` is `render workflows tasks runs cancel`. -Configure your app to target the local task server. +Non-interactive `workflows start` can return while the run is still queued or running. Copy its task run ID and poll `tasks runs show` for a bounded period until the status is completed, failed, or canceled. Confirm the result or error rather than treating run creation as successful execution. -**Python:** +Inputs: -Set environment variables: -```bash -RENDER_USE_LOCAL_DEV=true -``` +- Use a JSON array for positional arguments: `[5]`, `["left", "right"]`, or `[]`. +- A Python task can use a JSON object for named arguments: `{"value": 5}`. +- Do not include the `TaskContext` parameter in either input form. + +## Trigger Local Runs from Application Code + +For complete Python and TypeScript client scripts with a verified `ping` result, follow [Try It Locally with the SDK](manual-scaffolding.md#try-it-locally-with-the-sdk). + +Local SDK calls do not require a Render API key or a deployed workflow. Set local mode in the **calling application's** environment (setting it only on the task server does not configure a separately running client): -Or for a custom port: ```bash -RENDER_USE_LOCAL_DEV=true -RENDER_LOCAL_DEV_URL=http://localhost:8121 +export RENDER_USE_LOCAL_DEV=true ``` -The SDK clients (`Render()` and `RenderAsync()`) automatically detect these and route requests to the local server. - -**TypeScript:** +For a custom server URL, also set: -Same environment variables: ```bash -RENDER_USE_LOCAL_DEV=true +export RENDER_LOCAL_DEV_URL=http://localhost:8121 ``` -Or pass configuration directly: +Python `Render()` and `RenderAsync()` clients detect these variables. TypeScript supports the same variables or explicit configuration: + ```typescript import { Render } from "@renderinc/sdk"; const render = new Render({ useLocalDev: true, - localDevUrl: "http://localhost:8120", + localDevUrl: "http://localhost:8121", }); ``` -**Render API (any language):** - -Swap the base URL for task endpoints: -``` -http://localhost:8120 -``` - -The local task server only simulates task-related endpoints. Other Render API endpoints are not supported locally. - -## Viewing Results +For direct Render API code, use the local task server as the base URL for task endpoints only. Other Render API endpoints are not simulated. -After running a task via the CLI: -1. Press **Esc** to go back to the command menu -2. Select `runs` to see task runs -3. Select a run and choose `results` to see output +## Local-Only Behavior -## Limitations +- Logs and results are held in memory and disappear when the server stops. +- Stored run history can increase memory usage; restart the server during high-volume testing. +- Local task and run identifiers are generated for each server session and do not correspond to deployed identifiers. +- The server reloads task definitions when it starts subprocesses, so source changes are picked up without deploying. +- Local execution simulates task orchestration but does not reproduce production container isolation, networking, or compute characteristics. -- Logs and results are stored **in memory** and lost on server shutdown -- High volume of runs can increase memory usage; restart the server periodically -- Task and run IDs are random UUIDs, not matching deployed identifiers -- Subtasks run locally in the same server process +Stop the local task server after verification when an agent started it for the user. diff --git a/skills/render-workflows/references/manual-scaffolding.md b/skills/render-workflows/references/manual-scaffolding.md index e3faafa..2fe957e 100644 --- a/skills/render-workflows/references/manual-scaffolding.md +++ b/skills/render-workflows/references/manual-scaffolding.md @@ -1,129 +1,208 @@ -# Manual Scaffolding (Fallback) +# Direct SDK Project Setup -Use this path only if `render workflows init` is not available. Follow these steps in order. +Use this reference to add the Render Workflows SDK directly to an existing codebase or create a minimal workflow service without `render workflows init`. Preserve an existing project's dependency, module, and build conventions. For a new standalone service, prefer adapting the current official [Python examples](https://github.com/render-examples/render-workflows-examples-python) or [TypeScript examples](https://github.com/render-examples/render-workflows-examples-ts) over copying this minimal structure blindly. -## Contents +## Choose the Language and Boundary -- Step 1: Detect language -- Step 2: Create the `workflows/` directory -- Step 3: Install dependencies -- Step 4: Verify setup +Use the language requested by the user. Otherwise infer it from the project: -> **IMPORTANT:** Do NOT modify the project's root `package.json` or `requirements.txt`. Do NOT run `npm install ` or `pip install ` at the project root. The `workflows/` directory is a self-contained service with its own dependency files. +| Indicators | Language | +|---|---| +| `pyproject.toml`, `requirements.txt`, `Pipfile`, or Python source | Python | +| `package.json`, `tsconfig.json`, or TypeScript source | TypeScript | -> **The official starter templates have likely changed since this skill was written.** -> Always check the real template before scaffolding: -> - **Python:** [render-examples/workflows-template-python](https://github.com/render-examples/workflows-template-python) -> -> If the user already has the SDK installed, inspect it for up-to-date signatures: -> ```bash -> # Python: check SDK source -> SDK_ROOT=$(pip show render_sdk | grep Location | cut -d' ' -f2)/render_sdk -> head -40 "$SDK_ROOT/__init__.py" -> -> # TypeScript: check type definitions -> grep -r "export.*task\|export.*Render" node_modules/@renderinc/sdk/ -> ``` -> -> **Official examples:** [Python](https://github.com/render-oss/sdk/tree/main/python/example) | [TypeScript](https://github.com/render-oss/sdk/tree/main/typescript/examples) -> -> The inline snippets in this skill are a fallback. The official repos are the source of truth. +If both ecosystems are present, prefer the language already used by the component that will trigger or own the workflow. Ask only when the choice materially changes the integration. -## Step 1: Detect Language +Create a self-contained workflow service directory when the workflow has an independent build or deployment boundary. Do not overwrite unrelated root dependency files. -**Principle:** If the user named the language in their prompt, use it directly. Auto-detect from config files next. Only ask if genuinely ambiguous. +In an existing application, add a dedicated workflow entrypoint and run it separately from the web server. Keep task registration out of the client script and preserve the application's start command; add a script such as `workflows:start` for the workflow process. -Check the project for language indicators: +## Python -| Indicator | Language | -|-----------|----------| -| `requirements.txt`, `pyproject.toml`, `Pipfile`, `*.py` | Python | -| `package.json`, `tsconfig.json`, `*.ts` | TypeScript | +Minimum files: -If both are present or neither is found, ask the user which language to use. - -## Step 2: Create the `workflows/` Directory - -Use the official Render starter templates as the source of truth for file structure and contents: - -- **Python:** [render-examples/workflows-template-python](https://github.com/render-examples/workflows-template-python) -- **TypeScript:** [render-examples/workflows-template-ts](https://github.com/render-examples/workflows-template-ts) +```text +workflows/ +|-- main.py +`-- requirements.txt +``` -Fetch the template contents (clone, download, or read from the repo) and place them in a `workflows/` directory at the project root. At minimum, the directory should contain: +`requirements.txt`: -**Python:** `main.py`, `requirements.txt` -**TypeScript:** `index.ts` (or `main.ts`), `package.json`, `tsconfig.json` +```text +render>=1.0.1 +``` -Key patterns to follow from the templates: +`main.py`: -**Python entry point** (`main.py`): ```python -from render_sdk import Workflows, Retry +from render import TaskContext, Workflows -app = Workflows( - default_retry=Retry(max_retries=3, wait_duration_ms=1000, backoff_scaling=2.0), -) +app = Workflows() @app.task -def ping() -> str: +def ping(_ctx: TaskContext) -> str: return "pong" if __name__ == "__main__": app.start() ``` -**TypeScript entry point** (`index.ts`): +Install dependencies in an isolated environment: + +```bash +cd workflows +python3 -m venv .venv +source .venv/bin/activate +python -m pip install -r requirements.txt +``` + +Use an equivalent activation command on Windows or non-POSIX shells. + +## TypeScript + +Minimum files: + +```text +workflows/ +|-- src/ +| `-- main.ts +|-- package.json +`-- tsconfig.json +``` + +`package.json`: + +```json +{ + "name": "my-workflow", + "private": true, + "type": "module", + "scripts": { + "workflows:start": "tsx src/main.ts", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "@renderinc/sdk": "^1.0.0" + }, + "devDependencies": { + "@types/node": "^20.0.0", + "tsx": "^4.20.2", + "typescript": "^5.0.0" + } +} +``` + +`src/main.ts`: + ```typescript -import { task } from "@renderinc/sdk/workflows"; +import { task, type TaskContext } from "@renderinc/sdk/workflows"; task( - { - name: "ping", - retry: { maxRetries: 3, waitDurationMs: 1000, backoffScaling: 2.0 }, - }, - function ping(): string { + { name: "ping" }, + function ping(_ctx: TaskContext): string { return "pong"; }, ); ``` -Each template includes a zero-argument `ping` task so the user can immediately verify the setup works. +For this standalone example, use Node.js 20 or later and this `tsconfig.json`: + +```json +{ + "compilerOptions": { + "target": "ES2022", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "strict": true, + "noEmit": true, + "skipLibCheck": true, + "types": ["node"] + }, + "include": ["src/**/*.ts"] +} +``` + +Install dependencies and check the TypeScript source: -## Step 3: Install Dependencies +```bash +cd workflows +npm install +npm run typecheck +``` -After all files from Step 2 are created, install dependencies. +When integrating into an established service, preserve its TypeScript configuration and use Node type definitions compatible with its runtime. Adapt the dedicated workflow script to its existing tooling. + +## Try It Locally with the SDK + +Use the `ping` task and dependencies defined above for your chosen language. No deployment, Render API key, or `render workflows init` is needed. The task server and calling script run in separate processes. + +### Python + +Add `client.py` next to `main.py`: + +```python +from render import Render + +render = Render() +result = render.workflows.run_task("ping", []) +assert result.results == ["pong"], result +print(result.results[0]) +``` + +In terminal 1, from the workflow directory, start the task server: -**Python:** ```bash -pip install -r workflows/requirements.txt +render workflows dev -- .venv/bin/python main.py ``` -**TypeScript:** +In terminal 2, from the same directory, enable local mode for the **client process** and invoke the task: + ```bash -npm install --prefix workflows +RENDER_USE_LOCAL_DEV=true .venv/bin/python client.py ``` -## Step 4: Verify Setup +### TypeScript -Check that setup succeeded before handing off: +Add `src/client.ts`: -- [ ] `workflows/` directory exists with the expected files -- [ ] Dependencies installed without errors +```typescript +import assert from "node:assert/strict"; +import { Render } from "@renderinc/sdk"; -Then present the user with these verification commands to run in their own terminal: +const render = new Render(); +const result = await render.workflows.runTask("ping", []); +assert.deepEqual(result.results, ["pong"]); +console.log(result.results[0]); +``` -**Verification checklist:** +In terminal 1, from the workflow directory: -- [ ] Start the local task server: - - Python: `render workflows dev -- python workflows/main.py` - - TypeScript: `render workflows dev -- npx tsx workflows/main.ts` -- [ ] In a second terminal: `render workflows tasks list --local` -- [ ] Select `ping`, choose `run`, enter `[]` as input -- [ ] Verify the result is `"pong"` +```bash +npm run typecheck +render workflows dev -- npm run workflows:start +``` + +In terminal 2, from the same directory: + +```bash +RENDER_USE_LOCAL_DEV=true npx tsx src/client.ts +``` + +### Confirm the Result + +Each client waits for completion, checks the result, and prints `pong`. Local calls use the registered task name `ping`; deployed calls use `{workflow-slug}/ping`. The empty array supplies zero task arguments; do not pass `TaskContext`. The external client's `results` field is an array, so this task's returned string is at index `0`. + +The commands above use POSIX environment syntax. On other shells, set `RENDER_USE_LOCAL_DEV=true` in the client environment before running the script. For custom ports, set the matching `RENDER_LOCAL_DEV_URL` there too; see [local-development.md](local-development.md#trigger-local-runs-from-application-code). Keep these local settings out of deployed application environments. + +If the client fails or stays pending, inspect local runs instead of repeatedly starting new ones: + +```bash +render workflows tasks list --local -o text +render workflows tasks runs list ping --local -o text +render workflows tasks runs show --local -o json +``` -Do NOT start the dev server or run test commands yourself. Present the checklist for the user to run. +For this smoke test, bound the client wait (for example, one minute), inspect errors if it does not complete, and stop the local task server after verification when an agent started it. Run creation alone is not successful validation. -**If verification fails:** -- **Task server won't start:** check CLI version (`render --version`, needs 2.11.0+) and start command. See [Troubleshooting > Task Server Issues](troubleshooting.md#task-server-issues). -- **`ping` task not listed:** ensure the entry point imports the task file. See [Task Registration Issues](troubleshooting.md#task-registration-issues). -- **Dependency install errors:** confirm you ran install inside `workflows/`, not the project root. +For deployment, use the workflow directory as the service's root directory and preserve the build/start commands validated locally. The current CLI can generate a `render workflows create` command from `workflows init`; when scaffolding manually, construct that command from the project's actual configuration. diff --git a/skills/render-workflows/references/quick-reference.md b/skills/render-workflows/references/quick-reference.md index dee2d91..0eb8769 100644 --- a/skills/render-workflows/references/quick-reference.md +++ b/skills/render-workflows/references/quick-reference.md @@ -1,122 +1,156 @@ -# Workflows SDK Quick Reference +# Workflows SDK 1.x Quick Reference -This is an **approximate** API surface map -- not a substitute for the real SDK. -Always verify signatures against the installed package before generating code. +Use this reference for the current SDK 1.x programming model. Verify exact signatures against the installed package and the official [Python](https://render.com/docs/workflows-sdk-python) or [TypeScript](https://render.com/docs/workflows-sdk-typescript) reference before changing an existing project. -## Contents +## Version and Source Checks -- Where to find the real SDK source -- API surface map (defining tasks, task options, triggering runs, error types) -- Instance types -- Retry defaults -- Environment variables +```bash +# Python distribution and import location +python -m pip show render +python -c 'import render; print(render.__file__)' -## Where to find the real SDK source +# TypeScript package +npm ls @renderinc/sdk +``` -### Python +Current source locations: -```bash -SDK_ROOT=$(pip show render_sdk | grep Location | cut -d' ' -f2)/render_sdk - -# Signatures and source -# $SDK_ROOT/__init__.py — exports + usage examples in docstring -# $SDK_ROOT/workflows/app.py — Workflows class, @app.task, Retry, from_workflows() -# $SDK_ROOT/workflows/task.py — task internals, Options dataclass -# $SDK_ROOT/client/workflows_sync.py — sync client methods (Render().workflows.*) -# $SDK_ROOT/client/workflows.py — async client methods (RenderAsync().workflows.*) -# $SDK_ROOT/client/errors.py — error hierarchy -# $SDK_ROOT/client/types.py — TaskRun, TaskRunDetails, etc. -``` +- Python: `render/__init__.py`, `render/workflows/`, and `render/client/` +- TypeScript: `@renderinc/sdk/workflows` for task definitions and `@renderinc/sdk` for the API client +- Upstream examples: [Python](https://github.com/render-oss/sdk/tree/main/python/example) and [TypeScript](https://github.com/render-oss/sdk/tree/main/typescript/examples) -### TypeScript +## Define Tasks -```bash -TS_ROOT=node_modules/@renderinc/sdk +| Concept | Python | TypeScript | +|---|---|---| +| Imports | `from render import TaskContext, Workflows` | `import { task, type TaskContext } from "@renderinc/sdk/workflows"` | +| Register | `@app.task` | `task(options, fn)` | +| Required first parameter | `ctx: TaskContext` | `ctx: TaskContext` | +| Chain another run | `await ctx.run(task_def, *args)` | `await ctx.run(taskDef, ...args)` | +| Start task server | `app.start()` | Automatic in the workflow environment | +| Combine files | `Workflows.from_workflows(app1, app2)` | Import task modules synchronously from the entrypoint | +| In-process unit call | `task_def.func(fake_ctx, *args)` | `taskDef.func(fakeCtx, ...args)` | + +Minimal Python definition: + +```python +from render import TaskContext, Workflows + +app = Workflows() + +@app.task +def square(_ctx: TaskContext, value: int) -> int: + return value * value + +@app.task +async def sum_squares(ctx: TaskContext, left: int, right: int) -> int: + first = await ctx.run(square, left) + second = await ctx.run(square, right) + return first + second + +if __name__ == "__main__": + app.start() +``` -# Signatures and types -# $TS_ROOT/dist/workflows.d.ts — task() function, task options types -# $TS_ROOT/dist/client.d.ts — Render class, startTask, runTask, etc. -# $TS_ROOT/dist/index.d.ts — top-level exports -# $TS_ROOT/README.md — usage examples (if present) +Minimal TypeScript definition: + +```typescript +import { task, type TaskContext } from "@renderinc/sdk/workflows"; + +const square = task( + { name: "square" }, + (_ctx: TaskContext, value: number): number => value * value, +); + +task( + { name: "sumSquares" }, + async (ctx: TaskContext, left: number, right: number): Promise => { + const [first, second] = await Promise.all([ + ctx.run(square, left), + ctx.run(square, right), + ]); + return first + second; + }, +); ``` -## API surface map +## Task Options -### Defining tasks +| Purpose | Python | TypeScript | +|---|---|---| +| Custom name | `name=` | `name` | +| Retry | `retry=Retry(...)` | `retry: {...}` | +| Timeout | `timeout_seconds=` | `timeoutSeconds` | +| Compute plan | `plan=` | `plan` | -| Concept | Python | TypeScript | -|---------|--------|------------| -| Entry point | `from render_sdk import Workflows` | `import { task } from "@renderinc/sdk/workflows"` | -| Define a task | `@app.task` decorator | `task(options, fn)` | -| Start server | `app.start()` in `__main__` | Auto-starts via `RENDER_SDK_SOCKET_PATH` | -| Merge multi-file tasks | `Workflows.from_workflows(app1, app2)` | Side-effect imports in `index.ts` | -| Retry config | `Retry(max_retries, wait_duration_ms, backoff_scaling)` | `{ maxRetries, waitDurationMs, backoffScaling }` | - -### Task options - -| Option | Python (`@app.task` kwarg) | TypeScript (`task()` first arg) | -|--------|---------------------------|--------------------------------| -| Name | `name` | `name` (required) | -| Retry | `retry` (Retry instance) | `retry` (object) | -| Timeout | `timeout_seconds` | `timeoutSeconds` | -| Instance type | `plan` | `plan` | - -Workflow-level defaults: `Workflows(default_retry=..., default_timeout=..., default_plan=...)`. - -### Triggering runs (client SDK) - -| Concept | Python sync (`Render`) | Python async (`RenderAsync`) | TypeScript (`Render`) | -|---------|----------------------|----------------------------|----------------------| -| Fire-and-forget | `start_task()` | `await start_task()` | `await startTask()` | -| Start + wait | `run_task()` | `await run_task()` | `await runTask()` | -| Get run details | `get_task_run()` | `await get_task_run()` | `await getTaskRun()` | +Python workflow defaults are `default_retry`, `default_timeout`, and `default_plan` on `Workflows(...)`. + +Do not copy plan IDs, compute specifications, timeout bounds, or prices from this reference. Resolve current values from [compute-plans.md](compute-plans.md) and [Limits and Pricing for Render Workflows](https://render.com/docs/workflows-limits). + +Retry fields: + +| Python | TypeScript | +|---|---| +| `max_retries` | `maxRetries` | +| `wait_duration_ms` | `waitDurationMs` | +| `backoff_scaling` | `backoffScaling` | + +Retries can repeat side effects. A retried task that writes data, charges a customer, sends a message, or calls a mutating API needs an idempotency or deduplication strategy. + +## Trigger Runs with the Client + +| Operation | Python sync `Render` | Python async `RenderAsync` | TypeScript `Render` | +|---|---|---|---| +| Start without waiting | `start_task()` | `await start_task()` | `await startTask()` | +| Start and wait | `run_task()` | `await run_task()` | `await runTask()` | +| Wait on started run | Poll `get_task_run()` | `await started` | `await started.get()` | +| Get details | `get_task_run()` | `await get_task_run()` | `await getTaskRun()` | | List runs | `list_task_runs()` | `await list_task_runs()` | `await listTaskRuns()` | -| Cancel run | `cancel_task_run()` | `await cancel_task_run()` | `await cancelTaskRun()` | -| Stream events (SSE) | `task_run_events()` | `task_run_events()` | `taskRunEvents()` | +| Cancel root run | `cancel_task_run()` | `await cancel_task_run()` | `await cancelTaskRun()` | +| Stream terminal events | `task_run_events()` | `task_run_events()` async iterator | `taskRunEvents()` async iterator | -Task identifier format: `{workflow-slug}/{task-name}`. +Python input can be positional or named: -### Error types +```python +render.workflows.run_task("my-workflow/add", [2, 3]) +render.workflows.run_task("my-workflow/add", {"left": 2, "right": 3}) +``` -| Python | TypeScript | Notes | -|--------|------------|-------| -| `RenderError` | `RenderError` | Base class | -| `ClientError` | `ClientError` | 400-level | -| `RateLimitError` | — | 429 (subclass of ClientError) | -| `ServerError` | `ServerError` | 500-level | -| `TimeoutError` | — | Request timeout | -| `TaskRunError` | — | Task run failed | -| — | `AbortError` | Request aborted via AbortSignal | +TypeScript input is positional: + +```typescript +await render.workflows.runTask("my-workflow/add", [2, 3]); +``` -Import paths -- Python: `render_sdk.client.errors`, TypeScript: `@renderinc/sdk`. +Use the term **task slug** for `{workflow-slug}/{task-name}`. Task run IDs have the `trn-...` form. -### Instance types +`list_task_runs()` and `listTaskRuns()` return cursor-bearing wrapper objects; access the task run through `.task_run` in Python and `.taskRun` in TypeScript. -| Plan | Specs | -|------|-------| -| `starter` | 0.5 CPU / 512 MB | -| `standard` (default) | 1 CPU / 2 GB | -| `pro` | 2 CPU / 4 GB | -| `pro_plus` | 4 CPU / 8 GB | -| `pro_max` | 8 CPU / 16 GB | -| `pro_ultra` | 16 CPU / 32 GB | +## Error Types -`pro_plus`, `pro_max`, `pro_ultra` require requesting access. +| Python | TypeScript | Meaning | +|---|---|---| +| `RenderError` | `RenderError` | Base SDK error | +| `ClientError` | `ClientError` | Client or 4xx response | +| `RateLimitError` | `ClientError` with rate-limit status | Rate limited | +| `ServerError` | `ServerError` | Server, network, or 5xx failure | +| `TimeoutError` | — | Request timeout | +| `TaskRunError` | — | Task run failed or was canceled while waiting | +| — | `AbortError` | Client-side operation aborted | -### Retry defaults +Python error imports come from `render.client.errors`. TypeScript errors are exported from `@renderinc/sdk`. -| Scenario | `backoff_scaling` default | -|----------|--------------------------| -| Explicit retry config provided, field omitted | 1.5 | -| No retry config (built-in defaults) | 2.0 | +Aborting an SDK request or wait does not cancel the remote task run. Call the explicit cancellation method with the root task run ID. -### Environment variables +## Environment Variables | Variable | Purpose | -|----------|---------| -| `RENDER_API_KEY` | API authentication | -| `RENDER_SDK_SOCKET_PATH` | Unix socket (set by Render) | -| `RENDER_SDK_MODE` | `"run"` or `"register"` (set by Render) | -| `RENDER_SDK_AUTO_START` | TS only: `"false"` to disable | -| `RENDER_USE_LOCAL_DEV` | `"true"` for local task server | -| `RENDER_LOCAL_DEV_URL` | Custom local server URL | +|---|---| +| `RENDER_API_KEY` | Authenticate SDK calls to the Render API | +| `RENDER_SDK_SOCKET_PATH` | Internal task-runtime socket set by Render or the CLI | +| `RENDER_SDK_MODE` | Internal Python registration or run mode | +| `RENDER_SDK_AUTO_START` | Set to `false` to disable TypeScript auto-start | +| `RENDER_USE_LOCAL_DEV` | Set to `true` to use the local task server | +| `RENDER_LOCAL_DEV_URL` | Override the local task server URL | + +Do not ask users to set internal runtime variables manually. Start local workflows through `render workflows dev`. diff --git a/skills/render-workflows/references/service-types.md b/skills/render-workflows/references/service-types.md new file mode 100644 index 0000000..a0a3786 --- /dev/null +++ b/skills/render-workflows/references/service-types.md @@ -0,0 +1,37 @@ + +## Render service types + +Use this guidance when selecting or comparing Render service types, or when a task's architecture depends on the distinction between them. A task that is already unambiguously scoped to one service type does not need this entire overview. + +On Render, a service represents code deployed for a particular execution model. Render runs that service on one or more instances, and the service's compute plan determines the CPU and memory available to each instance. + +Before choosing a service type, fetch the current service-types reference: + +Using the documentation-retrieval workflow in the root `SKILL.md`, retrieve and read the [Markdown reference](https://render.com/docs/service-types.md) or its [HTML version](https://render.com/docs/service-types). + +If neither version can be retrieved, use the bundled overview below only for basic service-type selection. State that current platform details could not be verified, and do not guess about changeable capabilities such as supported runtimes, plans, scaling, networking, disks, health checks, deployment behavior, availability, or limits. + +Render provides six public service types for running code: + +- **Web service:** A continuously running server that receives public HTTP traffic and also has an internal hostname for private-network traffic. Use it for dynamic websites, APIs, and other internet-facing server applications. +- **Static site:** Built HTML, CSS, JavaScript, and other static assets served publicly from Render's global CDN. Use it only when the deployed application does not require server-side runtime logic. +- **Private service:** A continuously running server that receives traffic only over Render's private network. Use it for internal HTTP, TCP, gRPC, or other server processes that need an internal hostname but no public URL. +- **Background worker:** A continuously running process that does not receive incoming traffic or expose a public or internal hostname. Use it for queue consumers and other processes that pull or poll for work. +- **Cron job:** A command or process that starts on a schedule, performs a bounded unit of work, and exits. Use it for straightforward recurring tasks rather than an always-running process. +- **Workflow:** A collection of on-demand tasks executed across distributed compute, with Render handling task queuing, orchestration, and provisioning. Use it when the workload benefits from independently invoked tasks, retries, composition, or parallel execution instead of a continuously running worker process. + +Choose based on how the code executes and receives work: + +- Public incoming traffic that requires server-side logic belongs on a web service. Public static assets with no runtime server belong on a static site. +- An application that needs both public and private ingress remains a web service; use its internal hostname for traffic from other Render services. +- A process that receives private-network requests belongs on a private service. A process that only initiates connections and pulls work belongs on a background worker. +- A simple scheduled command that exits belongs on a cron job. An always-running queue consumer belongs on a background worker. On-demand or distributed tasks for which Render should manage queuing and per-run compute belong in a workflow. + +Cron jobs and Workflows use invocation-based execution models. The ordinary instance-count and autoscaling model used by continuously running services does not apply to them. + +Render Postgres and Render Key Value are fully managed datastores, not general-purpose compute service types for running application code. Use Render Postgres for relational data and Render Key Value for use cases such as shared caching and job queues. An attached persistent disk is a storage feature of certain compute services, not a service type of its own. + +After selecting a type, fetch the product article linked from the service-types reference before relying on details such as supported runtimes and sources, plans, scaling, networking, disks, health checks, deployment behavior, scheduling semantics, availability, or limits. These capabilities are not uniform across service types and can change independently. + +Human-facing service names do not always map directly to configuration identifiers or structure. When creating or editing a Blueprint, fetch the current Blueprint specification and use its service-type schema instead of inferring fields or values from this overview. In particular, do not assume that every Dashboard service type has a same-named Blueprint `type` or that managed datastores are declared like compute services. + diff --git a/skills/render-workflows/references/task-patterns.md b/skills/render-workflows/references/task-patterns.md index 8775a41..d9bf6e5 100644 --- a/skills/render-workflows/references/task-patterns.md +++ b/skills/render-workflows/references/task-patterns.md @@ -1,57 +1,65 @@ # Task Patterns -Common workflow patterns for both Python and TypeScript. +These examples use the Render SDK 1.x task model. Every task accepts `TaskContext` first, and chained runs go through `ctx.run`. -## Contents +For Python snippets, assume: -- Fan-out / fan-in -- ETL pipeline -- Retry-heavy tasks -- Error handling in tasks -- Integration patterns (cron triggers, cross-workflow calls) +```python +from render import Retry, TaskContext, Workflows + +app = Workflows() +``` + +For TypeScript snippets, assume: + +```typescript +import { task, type TaskContext } from "@renderinc/sdk/workflows"; +``` + +## Fan-Out and Fan-In -## Fan-Out / Fan-In +Use concurrent chaining when independent work benefits from separate compute and retry boundaries. -Process a batch of items in parallel using subtasks, then aggregate results. +Python: -**Python:** ```python import asyncio @app.task -async def process_batch(image_urls: list[str]) -> dict: +def process_image(_ctx: TaskContext, url: str) -> dict: + return {"url": url, "success": True} + +@app.task +async def process_batch(ctx: TaskContext, image_urls: list[str]) -> dict: results = await asyncio.gather( - *[process_image(url) for url in image_urls] + *(ctx.run(process_image, url) for url in image_urls) ) - successful = sum(1 for r in results if r["success"]) + successful = sum(1 for result in results if result["success"]) return { "total": len(image_urls), "processed": successful, "failed": len(image_urls) - successful, "results": list(results), } - -@app.task -def process_image(url: str) -> dict: - return {"url": url, "success": True} ``` -**TypeScript:** +TypeScript: + ```typescript const processImage = task( { name: "processImage" }, - function processImage(url: string): { url: string; success: boolean } { + function processImage(_ctx: TaskContext, url: string) { return { url, success: true }; }, ); task( { name: "processBatch" }, - async function processBatch(imageUrls: string[]): Promise { + async function processBatch(ctx: TaskContext, imageUrls: string[]) { const results = await Promise.all( - imageUrls.map(url => processImage(url)), + imageUrls.map((url) => ctx.run(processImage, url)), ); - const successful = results.filter(r => r.success).length; + const successful = results.filter((result) => result.success).length; return { total: imageUrls.length, processed: successful, @@ -62,201 +70,186 @@ task( ); ``` -## ETL Pipeline +Avoid unbounded fan-out when the input can be arbitrarily large. Batch inputs or add application-level concurrency control when downstream systems, rate limits, or cost require it. -Extract, transform, load pattern with chained subtasks. +## Sequential Pipeline + +Use sequential chaining when each stage depends on the prior stage's result. + +Python: -**Python:** ```python @app.task -async def etl_pipeline(source: str, destination: str) -> dict: - raw_data = await extract(source) - transformed = await transform(raw_data) - result = await load(destination, transformed) - return result +def extract(_ctx: TaskContext, source: str) -> dict: + return {"source": source, "records": []} @app.task -def extract(source: str) -> dict: - return {"records": []} +def transform(_ctx: TaskContext, data: dict) -> dict: + return {"records": data["records"]} @app.task -def transform(data: dict) -> dict: - return {"records": []} +def load(_ctx: TaskContext, destination: str, data: dict) -> dict: + return {"destination": destination, "loaded": len(data["records"])} @app.task -def load(destination: str, data: dict) -> dict: - return {"loaded": len(data["records"])} +async def etl_pipeline( + ctx: TaskContext, + source: str, + destination: str, +) -> dict: + raw_data = await ctx.run(extract, source) + transformed = await ctx.run(transform, raw_data) + return await ctx.run(load, destination, transformed) ``` -**TypeScript:** +TypeScript: + ```typescript const extract = task( { name: "extract" }, - function extract(source: string): object { - return { records: [] }; - }, + (_ctx: TaskContext, source: string) => ({ source, records: [] as object[] }), ); const transform = task( { name: "transform" }, - function transform(data: object): object { - return { records: [] }; - }, + (_ctx: TaskContext, data: { records: object[] }) => ({ records: data.records }), ); const load = task( { name: "load" }, - function load(destination: string, data: object): object { - return { loaded: 0 }; - }, + (_ctx: TaskContext, destination: string, data: { records: object[] }) => ({ + destination, + loaded: data.records.length, + }), ); task( { name: "etlPipeline" }, - async function etlPipeline(source: string, destination: string): Promise { - const rawData = await extract(source); - const transformed = await transform(rawData); - return await load(destination, transformed); + async function etlPipeline( + ctx: TaskContext, + source: string, + destination: string, + ) { + const rawData = await ctx.run(extract, source); + const transformed = await ctx.run(transform, rawData); + return ctx.run(load, destination, transformed); }, ); ``` -## Retry-Heavy Tasks +## Retries and Idempotency -Tasks with aggressive retry for unreliable external APIs. +Tasks retry automatically by default. Before running tasks that send emails, charge payments, or modify external state, use idempotency keys or another deduplication mechanism to prevent duplicate effects. -**Python:** -```python -from render_sdk import Retry +Python: -@app.task(retry=Retry(max_retries=5, wait_duration_ms=2000, backoff_scaling=2.0)) -def call_external_api(endpoint: str, payload: dict) -> dict: +```python +@app.task( + retry=Retry( + max_retries=5, + wait_duration_ms=2000, + backoff_scaling=2.0, + ) +) +def fetch_document(_ctx: TaskContext, url: str) -> str: import urllib.request - import json - req = urllib.request.Request( - endpoint, - data=json.dumps(payload).encode(), - headers={"Content-Type": "application/json"}, - ) - with urllib.request.urlopen(req, timeout=30) as resp: - return json.loads(resp.read()) + with urllib.request.urlopen(url, timeout=30) as response: + return response.read().decode() ``` -**TypeScript:** +TypeScript: + ```typescript task( { - name: "callExternalApi", - retry: { maxRetries: 5, waitDurationMs: 2000, backoffScaling: 2.0 }, - timeoutSeconds: 60, + name: "fetchDocument", + retry: { + maxRetries: 5, + waitDurationMs: 2000, + backoffScaling: 2, + }, }, - async function callExternalApi(endpoint: string, payload: object): Promise { - const resp = await fetch(endpoint, { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify(payload), - }); - if (!resp.ok) throw new Error(`HTTP ${resp.status}`); - return resp.json(); + async function fetchDocument(_ctx: TaskContext, url: string): Promise { + const response = await fetch(url); + if (!response.ok) throw new Error(`HTTP ${response.status}`); + return response.text(); }, ); ``` -## Error Handling in Tasks +Do not retry every error indiscriminately in task code. Let the configured task policy handle run retries, and distinguish permanent validation failures from transient upstream failures when the task itself implements request-level retry logic. For common execution issues and fixes, see [troubleshooting.md](troubleshooting.md). + +## Testing Task Logic In Process -Tasks that raise exceptions are retried automatically according to their retry config. Use this intentionally. For common execution issues and fixes, see [troubleshooting.md](troubleshooting.md). +SDK 1.x returns task definitions rather than callable task wrappers. Invoke `.func` with a test context for unit tests: + +Python: -**Python:** ```python -@app.task(retry=Retry(max_retries=3, wait_duration_ms=1000)) -def resilient_task(data: dict) -> dict: - result = process(data) - if not result["valid"]: - raise ValueError("Invalid result, retrying...") - return result +class NoSubtasks: + async def run(self, task, *args, **kwargs): + raise AssertionError("unexpected chained run") + +assert process_image.func(NoSubtasks(), "https://example.com/a.png")["success"] ``` -**TypeScript:** +TypeScript: + ```typescript -task( - { - name: "resilientTask", - retry: { maxRetries: 3, waitDurationMs: 1000 }, - }, - function resilientTask(data: object): object { - const result = process(data); - if (!result.valid) { - throw new Error("Invalid result, retrying..."); - } - return result; +const noSubtasks = { + metadata: {}, + run: async () => { + throw new Error("unexpected chained run"); }, -); -``` +}; ---- +const result = processImage.func(noSubtasks, "https://example.com/a.png"); +``` -## Integration Patterns +For orchestration tests, supply a fake `TaskContext.run` that records task definitions and returns controlled results. -Patterns for triggering workflow tasks from outside a workflow context. +## Scheduled Trigger -## Cron-Triggered Workflows +Render Workflows does not currently provide native scheduling. A Render cron job can trigger a deployed task with the SDK client. -Render Workflows do not have built-in scheduling. Use a Render cron job to trigger tasks on a schedule. +Python sync client: -**Python cron job (synchronous)** (`cron_trigger.py`): ```python -from render_sdk import Render +from render import Render -def main(): +def main() -> None: render = Render() result = render.workflows.run_task("my-workflow/daily-cleanup", []) - print(f"Cleanup completed: {result.status}") + print(result.status) if __name__ == "__main__": main() ``` -**Python cron job (asynchronous)** (`cron_trigger.py`): -```python -import asyncio -from render_sdk import RenderAsync - -async def main(): - render = RenderAsync() - started = await render.workflows.start_task("my-workflow/daily-cleanup", []) - finished = await started - print(f"Cleanup completed: {finished.status}") +TypeScript: -asyncio.run(main()) -``` - -**TypeScript cron job** (`cron-trigger.ts`): ```typescript import { Render } from "@renderinc/sdk"; const render = new Render(); - -async function main() { - const result = await render.workflows.runTask("my-workflow/daily-cleanup", []); - console.log("Cleanup completed:", result.status); -} - -main(); +const result = await render.workflows.runTask("my-workflow/daily-cleanup", []); +console.log(result.status); ``` -Set up the cron job in the Render Dashboard or via MCP with the desired schedule. +Store `RENDER_API_KEY` as a secret on the triggering service. -## Cross-Workflow Calls +## Cross-Workflow Call -A task in one workflow can trigger tasks in a **different** workflow using the SDK client (not subtask syntax): +`ctx.run` only chains tasks in the same workflow service. To call a different workflow, use the API client. This creates an independent run rather than a parent-child relationship in the workflow graph. + +Python: -**Python:** ```python -from render_sdk import RenderAsync +from render import RenderAsync @app.task -async def orchestrate(data: dict) -> dict: +async def orchestrate(_ctx: TaskContext, data: dict) -> object: render = RenderAsync() result = await render.workflows.run_task( "other-workflow/process", @@ -265,13 +258,14 @@ async def orchestrate(data: dict) -> dict: return result.results ``` -**TypeScript:** +TypeScript: + ```typescript import { Render } from "@renderinc/sdk"; task( { name: "orchestrate" }, - async function orchestrate(data: object): Promise { + async function orchestrate(_ctx: TaskContext, data: object): Promise { const render = new Render(); const result = await render.workflows.runTask( "other-workflow/process", @@ -282,4 +276,4 @@ task( ); ``` -> **Note:** Cross-workflow calls are not tracked as subtask relationships in the Dashboard. +Cross-workflow calls require an API key and are subject to Render API behavior. Prefer same-workflow chaining when the tasks form one logical execution graph. diff --git a/skills/render-workflows/references/troubleshooting.md b/skills/render-workflows/references/troubleshooting.md index 4ddfdac..0b1f43e 100644 --- a/skills/render-workflows/references/troubleshooting.md +++ b/skills/render-workflows/references/troubleshooting.md @@ -1,233 +1,222 @@ # Troubleshooting -Common issues and fixes when developing with Render Workflows, sourced from the SDK source code and official docs. +Use this reference for common Render Workflows setup, registration, execution, and client failures. Check the current [Workflows documentation](https://render.com/docs/workflows) and installed SDK version before relying on an implementation detail. -## Contents +## CLI and Local Server -- Task server issues -- Task registration issues -- Task execution issues -- Client issues -- Connection and networking -- Local development gotchas -- Limits reference +### `render workflows` or a subcommand is unavailable -## Task Server Issues +Run `render --version` and upgrade the CLI. Different workflow features arrived in different versions; this skill uses 2.16.0 or later for scaffolding, local development, and CLI deployment. -### Task server won't start +On macOS with Homebrew: -**Symptom:** `render workflows dev` fails or hangs. +```bash +brew upgrade render +``` -| Cause | Fix | -|-------|-----| -| CLI version < 2.11.0 | Run `render --version` to check. Upgrade: `brew upgrade render` (macOS) or reinstall via the install script. | -| Wrong start command | Python: `render workflows dev -- python workflows/main.py`. TypeScript: `render workflows dev -- npx tsx workflows/main.ts`. | -| Missing `app.start()` (Python) | Add `if __name__ == "__main__": app.start()` at the bottom of your entry point. | -| Port already in use | Use `--port` flag: `render workflows dev --port 8121 -- ...` | +For other platforms, follow the current [CLI installation guide](https://render.com/docs/cli#installation). -### `app.start()` fails with `ValueError` (Python) +### Local task server does not start -**Symptom:** `ValueError` about missing `RENDER_SDK_MODE` or `RENDER_SDK_SOCKET_PATH`. +| Cause | Resolution | +|---|---| +| Start command is wrong | Run the same entrypoint used by the workflow service, such as `python main.py` or `npm start`. | +| Python dependencies are in a virtual environment | Use its interpreter, such as `.venv/bin/python main.py`. | +| Python entrypoint does not call `app.start()` | Add the call to the executed entrypoint. | +| Port is occupied | Start with `--port ` and pass the same port to every local CLI or SDK call. | +| Docker-based workflow | Use a native local entrypoint or test after deployment; Docker workflows do not currently support the local task server. | -**Cause:** `app.start()` expects env vars that the Render CLI sets automatically. Running `python main.py` directly (without the CLI) triggers this. +Do not run a Python workflow entrypoint directly when it expects Render runtime variables. Start it through: -**Fix:** Always start via the CLI: `render workflows dev -- python workflows/main.py`. The CLI sets the required env vars. +```bash +render workflows dev -- python main.py +``` -### Auto-start crashes with `process.exit(1)` (TypeScript) +### Environment variables are missing locally -**Symptom:** Process exits immediately with no useful error message. +The CLI loads `.env` from its current directory. Run from the intended workflow root, or pass one or more explicit files: -**Cause:** The SDK auto-starts the task server via `setImmediate` when `RENDER_SDK_SOCKET_PATH` is set. If `startTaskServer()` throws, the SDK calls `process.exit(1)` with only a `console.error`. +```bash +render workflows dev --env-file .env --env-file .env.local -- python main.py +``` -**Fix:** Check that `RENDER_SDK_SOCKET_PATH` points to a valid, writable path. Use the Render CLI for local dev. Set `RENDER_SDK_AUTO_START=false` to disable auto-start and start manually if needed. +Later files override earlier ones. Confirm that secrets are ignored by Git and do not print their values during diagnosis. -## Task Registration Issues +## SDK 1.x Migration Failures -### "Task not found" in CLI +### Python cannot import `render_sdk` -**Symptom:** `render workflows tasks list --local` shows no tasks or is missing expected tasks. +The current Python distribution and import module are named `render`: -| Cause | Fix | -|-------|-----| -| Module not imported (Python) | Ensure your entry point imports all task files or uses `Workflows.from_workflows()`. | -| Module not imported (TypeScript) | Add `import './your-task-file'` to your `index.ts` entry point. | -| Server not running | Start the local task server first, then run `list --local` in a second terminal. | -| Missing `--local` flag | Without `--local`, the CLI lists deployed (remote) tasks, not local ones. | +```bash +python -m pip install 'render>=1.0.1' +python -c 'import render; print(render.__file__)' +``` -### Late registration after auto-start (TypeScript) +Update imports such as: -**Symptom:** Dynamically imported tasks are not available for execution; a warning appears in logs. +```python +from render import Render, Retry, TaskContext, Workflows +``` + +### Task registration rejects the function signature -**Cause:** The SDK auto-starts via `setImmediate` after synchronous module loading. Tasks registered after that (e.g., via dynamic `import()`) miss the registration window. +Every task must accept `TaskContext` as its first positional parameter, including tasks that do not use it: -**Fix:** Define all tasks at module scope using synchronous `import './module'` statements. Avoid dynamic imports for task files. +```python +@app.task +def ping(_ctx: TaskContext) -> str: + return "pong" +``` -### Duplicate task names +```typescript +task({ name: "ping" }, (_ctx: TaskContext) => "pong"); +``` -**Symptom:** Python raises `ValueError("Task '{name}' already registered")`. TypeScript silently overwrites the previous task. +The context is supplied by Render and is not included in CLI, SDK, or API task input. -**Cause:** Two tasks registered with the same `name`. +### A registered task is “not callable” -**Fix:** Use unique names for every task. When using `Workflows.from_workflows()` in Python, a `ValueError` is raised if any imported apps share a task name. +SDK 1.x returns a task definition, not a callable wrapper. -### Empty task name (TypeScript) +- From another task, use `await ctx.run(task_definition, ...args)`. +- In a unit test, call `task_definition.func(fake_context, ...args)` explicitly. +- From an application or script, use `Render().workflows.start_task()` or `run_task()` and the task slug. -**Symptom:** `Error: Task function must have a name or name must be provided`. +Do not restore direct calls as a workaround; direct calls would bypass distributed execution and task-run observability. -**Fix:** Always pass `name` in the options object: `task({ name: "myTask" }, function myTask() { ... })`. +## Task Registration -## Task Execution Issues +### Local task list is empty or missing tasks -### Subtask hangs forever +| Cause | Resolution | +|---|---| +| Missing `--local` | Use `render workflows tasks list --local`. | +| Server is not running | Start `render workflows dev` in another terminal first. | +| Python module is not incorporated | Import its `Workflows` object and combine apps with `Workflows.from_workflows(...)`. | +| TypeScript module is not imported | Add a synchronous module import to the entrypoint. | +| TypeScript task registered after auto-start | Define and import tasks synchronously at module scope; avoid dynamic imports for registration. | +| Duplicate task name | Give every task a unique registered name. | -**Symptom:** A task that calls other tasks never completes. +TypeScript's registry can replace a previous task with the same name, so detect duplicates during review rather than relying on a runtime error. -| Cause | Fix | -|-------|-----| -| Missing `await` | Subtask calls return a `TaskInstance` (Python) or `Promise` (TypeScript), not the result. You must `await` them. | -| Missing `async` keyword | Python: chaining tasks must be declared `async def`. TypeScript: must use `async function`. | -| Sequential instead of parallel | If you `await` each subtask individually, they run serially. Use `asyncio.gather()` (Python) or `Promise.all()` (TypeScript) for parallel execution. | +### TypeScript exits during auto-start -### Calling subtask outside a task context (Python) +The TypeScript SDK auto-starts task registration when `RENDER_SDK_SOCKET_PATH` is present. Use the Render CLI locally. Only set `RENDER_SDK_AUTO_START=false` when deliberately taking manual control of startup. -**Symptom:** `RuntimeError` about running a subtask outside task execution context. +## Task Execution -**Cause:** Task functions that are decorated with `@app.task` can only trigger subtask runs when called from within another executing task. Calling them from regular code (e.g., a script or REPL) fails because the internal `_current_client` context is not set. +### Chained run hangs or never starts -**Fix:** To trigger tasks from outside a task, use the SDK client (`Render()` or `RenderAsync()`) with `start_task()` or `run_task()`. Subtask syntax is only for task-to-task chaining. +Check that: -### Mixed positional and keyword arguments (Python) +- The parent task is `async`. +- The child is registered in the same workflow service. +- The call is `await ctx.run(child, ...)`. +- Parallel calls are collected with `asyncio.gather`, `asyncio.TaskGroup`, `Promise.all`, or a deliberate equivalent. -**Symptom:** `ValueError` about not mixing positional and keyword arguments. +Awaiting each independent child one at a time makes the chain serial rather than parallel. -**Cause:** The Python SDK does not allow calling a subtask with both `*args` and `**kwargs` simultaneously. +### Python rejects mixed task arguments -**Fix:** Use either positional args or keyword args, not both: `await my_task(1, 2)` or `await my_task(a=1, b=2)`. +`ctx.run` accepts positional arguments or named arguments, not both in the same call: -### "Not JSON serializable" error +```python +await ctx.run(task, first, second) +await ctx.run(task, left=first, right=second) +``` -**Symptom:** Task fails with a serialization error. +The same distinction applies when triggering a Python task through the SDK: send a list for positional input or a dictionary for named input. -| Cause | Fix | -|-------|-----| -| Non-serializable arguments | Task args must be JSON-serializable: dicts/objects, lists/arrays, strings, numbers, booleans, None/null. No class instances, functions, dates, sets, bytes, or `BigInt`. | -| Non-serializable return value | Same rule applies to return values. Convert complex objects to dicts/plain objects before returning. | -| Non-serializable default values (Python) | Default parameter values that aren't JSON-serializable are silently dropped. The API metadata won't reflect them. Use only JSON-serializable defaults. | +### Input or result is not JSON-serializable -### Task run fails silently +Convert values to JSON-compatible objects before passing or returning them. In particular, encode dates, byte strings, sets, class instances, and TypeScript `BigInt` values explicitly. -**Symptom:** Task run shows `failed` status with no useful error. +For current payload-size limits, consult [Limits and Pricing for Render Workflows](https://render.com/docs/workflows-limits). -| Cause | Fix | -|-------|-----| -| Unhandled exception | Add logging inside your task. Wrap risky code in try/except (Python) or try/catch (TypeScript). | -| No retry config | Add retry configuration so transient failures are retried automatically. | -| Timeout exceeded | Default timeout is 2 hours. Set `timeout_seconds` (Python) or `timeoutSeconds` (TypeScript) per task if you need more. Max: 24 hours. | -| All retries exhausted | After `max_retries + 1` total attempts, the run is marked failed. Inspect `TaskRunDetails.attempts` for per-attempt error details. | +### Retried task duplicates a side effect -### Timeout value rejected by API +Retries rerun task logic. Use idempotency keys, upserts, transactional guards, or downstream deduplication for writes, payments, messages, and other mutations. Do not enable retries on unsafe operations without a repeat-safety strategy. -**Symptom:** Task registration or run fails with a validation error. +### Timeout or compute plan is rejected -**Cause:** The SDK does not validate `timeout_seconds`/`timeoutSeconds` client-side. Out-of-range values (outside 30–86,400) are sent to the API, which rejects them. +Verify the task option name first: -**Fix:** Keep timeout values between 30 seconds and 86,400 seconds (24 hours). +- Python task: `timeout_seconds=` and `plan=` +- Python workflow default: `default_timeout=` and `default_plan=` +- TypeScript task: `timeoutSeconds` and `plan` -## Client Issues +Then resolve current timeout bounds and compute-plan IDs from [Limits and Pricing for Render Workflows](https://render.com/docs/workflows-limits). Do not substitute a remembered legacy plan name. -### `Render()` with `await` fails (Python) +## API Client -**Symptom:** `TypeError` or unexpected behavior when using `await` with `Render()`. +### `await Render()` fails in Python -**Fix:** `Render()` is the synchronous client. Use `RenderAsync()` for async contexts: +`Render` is synchronous. Use `RenderAsync` in an async context: ```python -# Synchronous (Flask, Django, scripts) -from render_sdk import Render -render = Render() -result = render.workflows.run_task("my-workflow/task", [42]) +from render import RenderAsync -# Asynchronous (FastAPI, async scripts) -from render_sdk import RenderAsync render = RenderAsync() result = await render.workflows.run_task("my-workflow/task", [42]) ``` -### "Invalid API key" or "Unauthorized" - -| Cause | Fix | -|-------|-----| -| Missing `RENDER_API_KEY` | Set the environment variable: `export RENDER_API_KEY=rnd_...` | -| Wrong key | Generate a new key at `https://dashboard.render.com/u/*/settings#api-keys` | -| Key doesn't match workspace | Ensure the key belongs to the workspace that owns the workflow | -| No key and no token passed | Both `Render()` and `RenderAsync()` raise `ValueError` if no token is available | - -### Argument too large +Use `Render` without `await` in synchronous code. -**Symptom:** Request rejected with a size error. +### Unauthorized or API key missing -**Fix:** Task arguments cannot exceed 4 MB total per invocation. Reduce payload size or pass references (URLs, IDs) instead of raw data. +The SDK uses `RENDER_API_KEY` unless a token is passed to the constructor. Confirm that the key belongs to a user with access to the workflow's workspace. Never log or commit the key. -### SSE stream ends without event +### Client wait was aborted but the run continues -**Symptom:** `RenderError("Task run completed with no event")` (Python) or unhandled stream error (TypeScript). +Canceling a TypeScript `AbortSignal`, closing an SSE stream, or interrupting a local wait does not cancel the remote run. Call the explicit cancellation method with the root task run ID: -**Cause:** The SSE connection closed before a terminal event (`completed`, `failed`, `canceled`) was received. - -**Fix:** This is typically a transient network issue. The SDK retries internally (up to 5 attempts with exponential backoff). If it persists, check network connectivity and try again. You can also poll with `get_task_run()` as a fallback. - -### AbortSignal does not cancel remote task (TypeScript) +```typescript +await render.workflows.cancelTaskRun(taskRunId); +``` -**Symptom:** After aborting, the task run continues executing on Render. +Canceling a root run cancels its active chained runs. A child run is not an independent cancellation target. -**Cause:** `AbortSignal` only cancels the local SDK wait (the HTTP request or SSE stream). The remote task run keeps running. +### Run listing shape is unexpected -**Fix:** To actually cancel a running task, explicitly call `render.workflows.cancelTaskRun(taskRunId)` after aborting. +Current list methods return cursor-bearing wrappers: -### Rate limiting (429) +- Python: access `.task_run` on each item. +- TypeScript: access `.taskRun` on each item. -**Symptom:** `RateLimitError` (Python) or `ClientError` with 429 status (TypeScript). +Use the returned cursor for pagination instead of assuming one call returns all runs. -**Fix:** Reduce request frequency. The SDK retries rate-limited requests internally for UDS calls (up to 15 attempts), but client-to-API rate limits require you to back off. +### Rate limiting or queued runs -## Connection & Networking +API-triggered runs and chained runs have different limits and queueing behavior. Consult [Limits and Pricing for Render Workflows](https://render.com/docs/workflows-limits) for current API rate, compute, and queueing rules. Back off on rate-limit responses; do not assume those requests were queued. -### UDS retries exhausted +## Deployment -**Symptom:** Error after approximately 2.5 minutes of retries during task execution. +### `render workflows create` fails -**Cause:** The internal Unix Domain Socket client retries transient errors (5xx, timeouts, rate limits) up to 15 times with exponential backoff (250ms initial, 2x factor, 16s cap). After 15 failures, the last error is thrown. +Confirm the active workspace, backing Git remote, repository access, runtime, root directory, and exact build/run commands. For non-interactive creation, required fields must be passed as flags. -**Fix:** This usually indicates the task server is unhealthy or overwhelmed. Check server logs, restart the task server, and ensure the socket path is valid. +If `--repo .` cannot resolve the repository, inspect the local Git remote and pass the supported Git provider URL explicitly. -### Runs queued at concurrency limit +### Tasks do not appear after deployment -**Symptom:** New task runs stay in `pending` status for a long time. +Check the workflow's build and release logs. Confirm that the deployed start command executes the same entrypoint verified locally and that all task modules are imported during registration. -**Cause:** Your workspace has hit its concurrent run limit. New runs are queued (not rejected) until another run completes. +To release a new version explicitly and wait for the outcome: -**Fix:** Wait for in-progress runs to finish, cancel unnecessary runs, or purchase additional concurrency in your workspace settings. Creating multiple workflow services does not increase the limit. +```bash +render workflows versions release --wait +``` -## Local Development Gotchas +### Blueprint sync fails or the workflow is missing from a preview -| Gotcha | Details | -|--------|---------| -| Local IDs don't match production | Task and run IDs in local dev are random UUIDs. They won't match deployed identifiers. | -| Data is in-memory only | Logs and results are lost when the local server shuts down. | -| Memory grows with many runs | Restart the local server periodically during heavy testing. | -| Only task endpoints are simulated | Other Render API endpoints are not available on the local server. | -| Cross-workflow calls not tracked | Calls between workflows via the SDK client are not shown as chained runs in the Dashboard. | +Workflows are valid Blueprint services (`type: workflow`). Common failures: -## Limits Reference +| Symptom | Cause | Fix | +|---------|-------|-----| +| Schema / validate error on `plan` | Service-level `plan` is not allowed on workflows | Remove `plan`. Set compute on the task in code. | +| Workflow deploys but behaves unexpectedly with `runtime: docker` | Workflow runtimes are `python` and `node` only. `render blueprints validate` currently accepts `runtime: docker` on a workflow even though the published schema rejects it, so a passing validate is not proof the runtime is supported | Use `runtime: python` or `runtime: node`. Validate against `https://render.com/schema/render.yaml.json` rather than trusting the CLI result alone | +| Preview stack has no workflow | Preview environments skip workflows | Expected. Other services still replicate. Trigger tasks against the non-preview workflow or deploy the workflow separately. | +| Blueprint rejected for duplicate name | A Blueprint-managed workflow with that `name` already exists in the workspace | Rename the service, or adopt the existing resource instead of creating a second one | -| Limit | Value | -|-------|-------| -| Max task definitions per workflow | 500 | -| Max argument size per run | 4 MB | -| Concurrent runs (Hobby) | 20 base, up to 200 | -| Concurrent runs (Professional) | 50 base, up to 200 | -| Concurrent runs (Org/Enterprise) | 100 base, up to 300 | -| Run timeout range | 30 seconds – 24 hours | -| Default run timeout | 2 hours | -| UDS internal retries | 15 attempts over ~2.5 minutes | -| SSE wait retries | 5 attempts with exponential backoff | +Do not copy the stale Workflows FAQ bullet that says Blueprints cannot manage workflows. Confirm against the [changelog](https://render.com/changelog/added-blueprint-support-for-render-workflows) and `https://render.com/schema/render.yaml.json`. diff --git a/tests/package/manifest.test.ts b/tests/package/manifest.test.ts index d673d81..103a92e 100644 --- a/tests/package/manifest.test.ts +++ b/tests/package/manifest.test.ts @@ -105,9 +105,9 @@ describe("package manifest", () => { } }); - it("carries the metadata for the v0.1.0 GitHub release", () => { + it("carries the metadata for the v0.2.0 GitHub release", () => { expect(pkg.name).toBe("@render/pi-render"); - expect(pkg.version).toBe("0.1.0"); + expect(pkg.version).toBe("0.2.0"); expect(pkg.license).toBe("MIT"); expect(readFileSync(join(repoRoot, "LICENSE"), "utf8")).toContain("MIT License"); expect(pkg.description?.length ?? 0).toBeGreaterThan(20); diff --git a/tests/package/skills.test.ts b/tests/package/skills.test.ts index cff82f7..a7ca573 100644 --- a/tests/package/skills.test.ts +++ b/tests/package/skills.test.ts @@ -143,7 +143,7 @@ describe("vendored Render skills", () => { const commit = record.match(/^commit: ([0-9a-f]{40})$/m)?.[1]; expect(source).toBe("https://github.com/render-oss/skills"); - expect(ref).toBe("main"); + expect(ref).toMatch(/^(main|skills-v\d+\.\d+\.\d+)$/); expect(commit, "no 40-char commit recorded in .sync-source").toBeDefined(); expect(record).not.toMatch(/^synced:/m); });