Render deploys Breadbox via
Blueprints — pulling the
prebuilt image from ghcr.io/canalesb93/breadbox:latest. About
2 minutes end-to-end.
The button reads render.yaml at the repo root and provisions:
- breadbox — pulled from
ghcr.io/canalesb93/breadbox:latest(prebuilt multi-arch image, no Dockerfile build at deploy time), starter plan (required tier for persistent disks) - breadbox-db — managed PostgreSQL 16 on the
basic-256mbplan - 6 GB persistent disk mounted at
/var/lib/breadbox(covers agent transcripts + scheduled pg_dump backups) DATABASE_URLwired from the managed Postgres connection stringENVIRONMENT=dockerso the runtime resolvesBB_DATA_DIRto/var/lib/breadbox
openssl rand -hex 32You'll paste this into Render's blueprint prompt in step 3. Save it somewhere safe — it encrypts your bank-provider credentials at rest, and losing it locks you out of stored Plaid / Teller tokens.
Render walks you through:
- Connecting your Render account (sign up if needed).
- Naming the blueprint instance.
Because the blueprint uses runtime: image, Render does NOT fork
the GitHub repo into your account. It just pulls the prebuilt image
from ghcr.io/canalesb93/breadbox:latest directly. Zero GitHub
permissions required.
Render's blueprint reader sees sync: false on ENCRYPTION_KEY and
prompts for a value. Paste the hex string from step 1.
Why not auto-generate? Render's
generateValue: trueproduces base64, but Breadbox'sENCRYPTION_KEYparser is hex-only. The one hex-paste step is the trade-off until the parser learns base64.
Click Apply. Render provisions both services, creates the disk, pulls the image, runs migrations, and starts Breadbox. ~30 s end-to-end because there's no Docker build — the image is pulled prebuilt from ghcr.io.
Watch the deploy logs from the Blueprint dashboard. The healthcheck
at /health/ready flips green once the server is listening.
Render gives the breadbox service a *.onrender.com URL. Open it,
land on /setup, create your admin.
The service pulls :latest, which tracks the newest stable
release (not every commit to main). Render does not
auto-redeploy when a new release is published — by design, so
self-hosters of a financial app control their own upgrade timing.
To pull a newer image, click Manual Deploy → Deploy latest image on the service in the Render dashboard. The breadbox admin dashboard also surfaces an "update available" badge in the sidebar when a newer GitHub release exists.
To pin to a specific release (recommended for full reproducibility),
edit the image.url in your render.yaml (or your own template
copy) — e.g. ghcr.io/canalesb93/breadbox:v0.1.0 — and Render
redeploys to that tag on the next sync. To instead track the
unreleased tip of main, use ghcr.io/canalesb93/breadbox:edge.
- Roughly $7/mo at default sizing: starter web ($7) + basic-256mb Postgres (often free during trial / cheap thereafter).
- Render's free tier doesn't support persistent disks, so
starteris the floor for Breadbox. - Postgres + disk both add a small storage line item; check render.com/pricing for current numbers.
/var/lib/breadbox is one Render persistent disk holding:
/var/lib/breadbox/transcripts/agents/— agent NDJSON transcripts/var/lib/breadbox/backups/— scheduled pg_dump backups
Render disks survive deploys. Resize from the disk dashboard if you outgrow 6 GB.
Important Render limitation: a web service with an attached disk can't be scaled horizontally. Breadbox is single-instance by design (cron + agent scheduler don't coordinate across replicas), so this matches the architecture exactly.
Render → service → Settings → Custom Domains → Add. Follow the DNS CNAME instructions Render prints. Render terminates TLS automatically.
Image pull fails
Hit Manual Deploy to retry. The ghcr.io image is public; the
most common cause of a pull failure is a transient ghcr outage.
Service crashes on startup with ENCRYPTION_KEY: invalid hex
The value you pasted isn't 64 hex chars. Regenerate with
openssl rand -hex 32 and update it under Environment.
/health/ready never goes green
Check the service logs. Most common cause is the Postgres still
warming up (Render brings databases up in parallel; the migration
step retries for ~60 s but can give up on cold starts). Hit Manual
Deploy once the database shows Available.
- Single instance only. Disk attachment blocks horizontal scaling, and Breadbox's scheduler isn't multi-instance-safe anyway.
- No auto-redeploy on upstream commits. The blueprint pulls a
fixed image tag (
:latest); Render redeploys only on a manual trigger or when you change the tag inrender.yaml.