-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrender.yaml
More file actions
120 lines (116 loc) · 5.4 KB
/
render.yaml
File metadata and controls
120 lines (116 loc) · 5.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# Render Blueprint for Doable
# Spec ref: https://render.com/docs/blueprint-spec
#
# Auto-detected on Connect to a public GitHub repo (Dashboard → New → Blueprint).
# Render reads this file, prompts for any env vars with sync: false, then provisions:
# managed PG → api (preDeployCommand runs migrate) → ws → web.
#
# All app images come from ghcr.io (built by .github/workflows/publish-docker-images.yml).
# Source-build path is intentionally NOT used — Render's free/Starter tier OOMs during the
# Next.js build. See doablechore/PlatformTemplatesPRD/04-render.md.
databases:
- name: doable-db
databaseName: doable
user: doable
plan: starter # bump to standard for >50 users
postgresMajorVersion: 16
ipAllowList: [] # internal-only
services:
# --- API server (Hono REST) ---
- type: web
name: doable-api
runtime: image
image:
url: ghcr.io/doable-me/doable-api:latest
plan: starter # 512MB — bump to standard (2GB) for >25 users
region: oregon
healthCheckPath: /health
# preDeployCommand runs migrations before every deploy. Idempotent (every migration
# is CREATE … IF NOT EXISTS, so re-runs are no-ops).
preDeployCommand: node /app/services/api/dist/db/migrate.js
envVars:
- { key: DATABASE_URL, fromDatabase: { name: doable-db, property: connectionString } }
- { key: NODE_ENV, value: production }
# Per-app database + AI runtime. ON by default; set to "0" to disable.
- { key: DOABLE_APP_DB_ENABLED, value: "1" }
- { key: DOABLE_APP_AI_ENABLED, value: "1" }
- { key: API_PORT, value: "4000" }
- { key: API_HOST, value: "0.0.0.0" }
- { key: WS_PORT, value: "4001" }
- { key: WS_HOST, value: "0.0.0.0" }
- { key: API_URL, value: http://doable-api:4000 }
- { key: WS_INTERNAL_URL, value: http://doable-ws:4001 }
# Public URLs — operator fills these once the Render-assigned hostname is known.
# Format: https://<service-name>-<hash>.onrender.com
- { key: NEXT_PUBLIC_API_URL, sync: false }
- { key: NEXT_PUBLIC_WS_URL, sync: false }
- { key: NEXT_PUBLIC_APP_URL, sync: false }
- { key: CORS_ORIGINS, sync: false }
# Required secrets — Render auto-generates on first deploy.
- { key: JWT_SECRET, generateValue: true }
- { key: ENCRYPTION_KEY, generateValue: true }
- { key: INTERNAL_SECRET, generateValue: true }
- { key: DOABLE_KEK, generateValue: true }
- { key: INSTALL_BOOTSTRAP_TOKEN, generateValue: true }
- { key: INSTALL_BOOTSTRAP_TOKEN_EXPIRES_AT, sync: false } # operator: ISO8601 now+24h
# 19 AI provider env-seeds — leave any blank to skip (configure via wizard later).
- { key: ANTHROPIC_API_KEY, sync: false }
- { key: OPENAI_API_KEY, sync: false }
- { key: GEMINI_API_KEY, sync: false }
- { key: MINIMAX_API_KEY, sync: false }
- { key: OPENROUTER_API_KEY, sync: false }
- { key: TOGETHER_API_KEY, sync: false }
- { key: FIREWORKS_API_KEY, sync: false }
- { key: OPENCODE_ZEN_API_KEY, sync: false }
- { key: GROQ_API_KEY, sync: false }
- { key: CEREBRAS_API_KEY, sync: false }
- { key: DEEPSEEK_API_KEY, sync: false }
- { key: MISTRAL_API_KEY, sync: false }
- { key: COHERE_API_KEY, sync: false }
- { key: XAI_API_KEY, sync: false }
- { key: PERPLEXITY_API_KEY, sync: false }
- { key: DEEPINFRA_API_KEY, sync: false }
- { key: NVIDIA_API_KEY, sync: false }
- { key: MOONSHOT_API_KEY, sync: false }
- { key: ZHIPU_API_KEY, sync: false }
# Optional OAuth + Stripe
- { key: GITHUB_CLIENT_ID, sync: false }
- { key: GITHUB_CLIENT_SECRET, sync: false }
- { key: GOOGLE_CLIENT_ID, sync: false }
- { key: GOOGLE_CLIENT_SECRET, sync: false }
- { key: STRIPE_SECRET_KEY, sync: false }
- { key: STRIPE_WEBHOOK_SECRET, sync: false }
# --- WebSocket server (Yjs CRDT) ---
- type: pserv
name: doable-ws
runtime: image
image:
url: ghcr.io/doable-me/doable-ws:latest
plan: starter
region: oregon
envVars:
- { key: DATABASE_URL, fromDatabase: { name: doable-db, property: connectionString } }
- { key: NODE_ENV, value: production }
- { key: WS_PORT, value: "4001" }
- { key: WS_HOST, value: "0.0.0.0" }
- { key: API_URL, value: http://doable-api:4000 }
- { key: JWT_SECRET, fromService: { type: web, name: doable-api, envVarKey: JWT_SECRET } }
- { key: INTERNAL_SECRET, fromService: { type: web, name: doable-api, envVarKey: INTERNAL_SECRET } }
# --- Web frontend (Next.js) ---
- type: web
name: doable-web
runtime: image
image:
url: ghcr.io/doable-me/doable-web:latest
plan: starter
region: oregon
envVars:
# Web's NEXT_PUBLIC_* are rewritten at container startup by docker/web-runtime-entrypoint.sh
# (placeholder strings in the bundle are sed-replaced). The values below are what the
# browser sees — they MUST match doable-api's NEXT_PUBLIC_* above.
- { key: NEXT_PUBLIC_API_URL, sync: false }
- { key: NEXT_PUBLIC_WS_URL, sync: false }
- { key: NEXT_PUBLIC_APP_URL, sync: false }
- { key: HOSTNAME, value: "0.0.0.0" }
- { key: PORT, value: "3000" }
- { key: NODE_ENV, value: production }