docs: update redis references from upstash to self-hosted (#677)

- environments.md: update redis column to show fly.io apps
- background-tasks.md: update production/staging section with fly URLs and pricing
- docket_runs.py: update hints to show flyctl proxy commands
- fly.toml/fly.staging.toml: update DOCKET_URL comments

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>

authored by zzstoatzz.io Claude Opus 4.5 and committed by GitHub bafa0f24 d21bb171

Changed files
+20 -27
backend
docs
scripts
+1 -1
backend/fly.staging.toml
··· 44 44 # - AWS_ACCESS_KEY_ID (cloudflare R2) 45 45 # - AWS_SECRET_ACCESS_KEY (cloudflare R2) 46 46 # - OAUTH_ENCRYPTION_KEY (generate: python -c 'from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())') 47 - # - DOCKET_URL (upstash redis: rediss://default:xxx@xxx.upstash.io:6379) 47 + # - DOCKET_URL (self-hosted redis: redis://plyr-redis-stg.internal:6379)
+1 -1
backend/fly.toml
··· 39 39 # - AWS_ACCESS_KEY_ID (cloudflare R2) 40 40 # - AWS_SECRET_ACCESS_KEY (cloudflare R2) 41 41 # - OAUTH_ENCRYPTION_KEY (generate: python -c 'from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())') 42 - # - DOCKET_URL (upstash redis: rediss://default:xxx@xxx.upstash.io:6379) 42 + # - DOCKET_URL (self-hosted redis: redis://plyr-redis.internal:6379)
+12 -17
docs/backend/background-tasks.md
··· 71 71 72 72 ### production/staging 73 73 74 - Redis instances are provisioned via Upstash (managed Redis): 74 + Redis instances are self-hosted on Fly.io (redis:7-alpine): 75 75 76 - | environment | instance | region | 77 - |-------------|----------|--------| 78 - | production | `plyr-redis-prd` | us-east-1 (near fly.io) | 79 - | staging | `plyr-redis-stg` | us-east-1 | 76 + | environment | fly app | region | 77 + |-------------|---------|--------| 78 + | production | `plyr-redis` | iad | 79 + | staging | `plyr-redis-stg` | iad | 80 80 81 81 set `DOCKET_URL` in fly.io secrets: 82 82 ```bash 83 - flyctl secrets set DOCKET_URL=rediss://default:xxx@xxx.upstash.io:6379 -a relay-api 84 - flyctl secrets set DOCKET_URL=rediss://default:xxx@xxx.upstash.io:6379 -a relay-api-staging 83 + flyctl secrets set DOCKET_URL=redis://plyr-redis.internal:6379 -a relay-api 84 + flyctl secrets set DOCKET_URL=redis://plyr-redis-stg.internal:6379 -a relay-api-staging 85 85 ``` 86 86 87 - note: use `rediss://` (with double 's') for TLS connections to Upstash. 87 + note: uses Fly internal networking (`.internal` domain), no TLS needed within private network. 88 88 89 89 ## usage 90 90 ··· 134 134 135 135 ## costs 136 136 137 - **Upstash pricing** (pay-per-request): 138 - - free tier: 10k commands/day 139 - - pro: $0.2 per 100k commands + $0.25/GB storage 137 + **self-hosted Redis on Fly.io** (fixed monthly): 138 + - ~$2/month per instance (256MB shared-cpu VM) 139 + - ~$4/month total for prod + staging 140 140 141 - for plyr.fm's volume (~100 uploads/day), this stays well within free tier or costs $0-5/mo. 142 - 143 - **tips to avoid surprise bills**: 144 - - use **regional** (not global) replication 145 - - set **max data limit** (256MB is plenty for a task queue) 146 - - monitor usage in Upstash dashboard 141 + this replaced Upstash pay-per-command pricing which was costing ~$75/month at scale (37M commands/month). 147 142 148 143 ## fallback behavior 149 144
+2 -2
docs/deployment/environments.md
··· 7 7 | environment | trigger | backend URL | database | redis | frontend | storage | 8 8 |-------------|---------|-------------|----------|-------|----------|---------| 9 9 | **development** | local | localhost:8001 | plyr-dev (neon) | localhost:6379 (docker) | localhost:5173 | audio-dev, images-dev (r2) | 10 - | **staging** | push to main | api-stg.plyr.fm | plyr-stg (neon) | plyr-redis-stg (upstash) | stg.plyr.fm (main branch) | audio-staging, images-staging (r2) | 11 - | **production** | github release | api.plyr.fm | plyr-prd (neon) | plyr-redis-prd (upstash) | plyr.fm (production-fe branch) | audio-prod, images-prod (r2) | 10 + | **staging** | push to main | api-stg.plyr.fm | plyr-stg (neon) | plyr-redis-stg (fly.io) | stg.plyr.fm (main branch) | audio-staging, images-staging (r2) | 11 + | **production** | github release | api.plyr.fm | plyr-prd (neon) | plyr-redis (fly.io) | plyr.fm (production-fe branch) | audio-prod, images-prod (r2) | 12 12 13 13 ## workflow 14 14
+4 -6
scripts/docket_runs.py
··· 38 38 url = os.environ.get("DOCKET_URL_STAGING") 39 39 if not url: 40 40 print("error: DOCKET_URL_STAGING not set") 41 - print( 42 - "hint: export DOCKET_URL_STAGING=rediss://default:xxx@xxx.upstash.io:6379" 43 - ) 41 + print("hint: flyctl proxy 6380:6379 -a plyr-redis-stg") 42 + print(" export DOCKET_URL_STAGING=redis://localhost:6380") 44 43 return 1 45 44 elif args.env == "production": 46 45 url = os.environ.get("DOCKET_URL_PRODUCTION") 47 46 if not url: 48 47 print("error: DOCKET_URL_PRODUCTION not set") 49 - print( 50 - "hint: export DOCKET_URL_PRODUCTION=rediss://default:xxx@xxx.upstash.io:6379" 51 - ) 48 + print("hint: flyctl proxy 6381:6379 -a plyr-redis") 49 + print(" export DOCKET_URL_PRODUCTION=redis://localhost:6381") 52 50 return 1 53 51 54 52 print(f"connecting to {args.env}...")