vibecarbon 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (495) hide show
  1. package/LICENSE +663 -0
  2. package/README.md +188 -0
  3. package/carbon/.claude/hooks/task-completed-gate.sh +19 -0
  4. package/carbon/.claude/hooks/teammate-idle-gate.sh +29 -0
  5. package/carbon/.claude/settings.json +29 -0
  6. package/carbon/.cursor/rules/vibecarbon.mdc +6 -0
  7. package/carbon/.dockerignore +57 -0
  8. package/carbon/.env.example +219 -0
  9. package/carbon/.github/copilot-instructions.md +3 -0
  10. package/carbon/.github/workflows/deploy.yml +346 -0
  11. package/carbon/.github/workflows/vibecarbon-build.yml +81 -0
  12. package/carbon/.windsurfrules +74 -0
  13. package/carbon/AGENTS.md +422 -0
  14. package/carbon/CLAUDE.md +3 -0
  15. package/carbon/DEVELOPMENT.md +187 -0
  16. package/carbon/Dockerfile +98 -0
  17. package/carbon/LICENSE +21 -0
  18. package/carbon/PRODUCTION.md +364 -0
  19. package/carbon/README.md +193 -0
  20. package/carbon/TESTING.md +138 -0
  21. package/carbon/backup/Dockerfile +75 -0
  22. package/carbon/backup/backup.sh +95 -0
  23. package/carbon/backup/compose-backup.sh +140 -0
  24. package/carbon/biome.json +83 -0
  25. package/carbon/cloud-init/docker-ce-setup.yaml +55 -0
  26. package/carbon/cloud-init/k3s/master-init.sh +215 -0
  27. package/carbon/cloud-init/k3s/supabase-init.sh +167 -0
  28. package/carbon/cloud-init/k3s/worker-init.sh +147 -0
  29. package/carbon/components.json +24 -0
  30. package/carbon/content/blog/authentication-guide.mdx +34 -0
  31. package/carbon/content/blog/getting-started.mdx +41 -0
  32. package/carbon/content/changelog/v0-1-0.mdx +40 -0
  33. package/carbon/content/docs/analytics.mdx +90 -0
  34. package/carbon/content/docs/authentication.mdx +231 -0
  35. package/carbon/content/docs/background-jobs.mdx +116 -0
  36. package/carbon/content/docs/cli.mdx +630 -0
  37. package/carbon/content/docs/database.mdx +236 -0
  38. package/carbon/content/docs/deployment.mdx +227 -0
  39. package/carbon/content/docs/development.mdx +238 -0
  40. package/carbon/content/docs/environments.mdx +84 -0
  41. package/carbon/content/docs/getting-started.mdx +112 -0
  42. package/carbon/content/docs/legal/privacy-policy.mdx +89 -0
  43. package/carbon/content/docs/legal/terms-of-service.mdx +99 -0
  44. package/carbon/content/docs/optional-services.mdx +160 -0
  45. package/carbon/db/Dockerfile +23 -0
  46. package/carbon/docker-compose.dev-init.yml +5 -0
  47. package/carbon/docker-compose.metabase.override.yml +14 -0
  48. package/carbon/docker-compose.metabase.prod.yml +28 -0
  49. package/carbon/docker-compose.metabase.yml +84 -0
  50. package/carbon/docker-compose.n8n.override.yml +14 -0
  51. package/carbon/docker-compose.n8n.prod.yml +31 -0
  52. package/carbon/docker-compose.n8n.yml +97 -0
  53. package/carbon/docker-compose.observability.override.yml +18 -0
  54. package/carbon/docker-compose.observability.prod.yml +28 -0
  55. package/carbon/docker-compose.observability.yml +125 -0
  56. package/carbon/docker-compose.override.yml +28 -0
  57. package/carbon/docker-compose.prod.yml +294 -0
  58. package/carbon/docker-compose.yml +508 -0
  59. package/carbon/docker-entrypoint.sh +12 -0
  60. package/carbon/ha/activate-standby.sh +52 -0
  61. package/carbon/ha/primary-init.sql +36 -0
  62. package/carbon/ha/standby-init.sh +74 -0
  63. package/carbon/k8s/LICENSE +99 -0
  64. package/carbon/k8s/README.md +272 -0
  65. package/carbon/k8s/base/app/deployment.yaml +130 -0
  66. package/carbon/k8s/base/app/hpa.yaml +44 -0
  67. package/carbon/k8s/base/app/kustomization.yaml +10 -0
  68. package/carbon/k8s/base/app/network-policy.yaml +124 -0
  69. package/carbon/k8s/base/app/pdb.yaml +14 -0
  70. package/carbon/k8s/base/app/rbac.yaml +36 -0
  71. package/carbon/k8s/base/app/service.yaml +16 -0
  72. package/carbon/k8s/base/backup/cronjob.yaml +120 -0
  73. package/carbon/k8s/base/backup/kustomization.yaml +7 -0
  74. package/carbon/k8s/base/backup/network-policy.yaml +31 -0
  75. package/carbon/k8s/base/backup/rbac.yaml +7 -0
  76. package/carbon/k8s/base/cluster-autoscaler/deployment.yaml +103 -0
  77. package/carbon/k8s/base/cluster-autoscaler/kustomization.yaml +17 -0
  78. package/carbon/k8s/base/cluster-autoscaler/rbac.yaml +109 -0
  79. package/carbon/k8s/base/config/configmap.yaml +48 -0
  80. package/carbon/k8s/base/config/kustomization.yaml +8 -0
  81. package/carbon/k8s/base/hetzner-ccm/kustomization.yaml +9 -0
  82. package/carbon/k8s/base/hetzner-csi/kustomization.yaml +9 -0
  83. package/carbon/k8s/base/kustomization.yaml +43 -0
  84. package/carbon/k8s/base/namespace.yaml +7 -0
  85. package/carbon/k8s/base/network-policies.yaml +95 -0
  86. package/carbon/k8s/base/registry/kustomization.yaml +5 -0
  87. package/carbon/k8s/base/registry/local-registry.yaml +193 -0
  88. package/carbon/k8s/base/traefik/certificate.yaml +21 -0
  89. package/carbon/k8s/base/traefik/configmap.yaml +13 -0
  90. package/carbon/k8s/base/traefik/deployment.yaml +165 -0
  91. package/carbon/k8s/base/traefik/ingressroute.yaml +141 -0
  92. package/carbon/k8s/base/traefik/kustomization.yaml +11 -0
  93. package/carbon/k8s/base/traefik/middleware.yaml +109 -0
  94. package/carbon/k8s/base/traefik/network-policy.yaml +92 -0
  95. package/carbon/k8s/base/traefik/service.yaml +38 -0
  96. package/carbon/k8s/flux/README.md +49 -0
  97. package/carbon/k8s/flux/clusters/primary/vibecarbon.yaml +128 -0
  98. package/carbon/k8s/flux/clusters/standby/vibecarbon.yaml +83 -0
  99. package/carbon/k8s/gitops/cert-manager-webhook-hetzner/helm-release.yaml +38 -0
  100. package/carbon/k8s/gitops/cert-manager-webhook-hetzner/helm-repository.yaml +16 -0
  101. package/carbon/k8s/gitops/cert-manager-webhook-hetzner/kustomization.yaml +10 -0
  102. package/carbon/k8s/gitops/supabase/helm-release.yaml +66 -0
  103. package/carbon/k8s/gitops/supabase/helm-repository.yaml +18 -0
  104. package/carbon/k8s/gitops/supabase/kustomization.yaml +33 -0
  105. package/carbon/k8s/infra/cert-manager-resources/cluster-issuers-cloudflare.yaml +51 -0
  106. package/carbon/k8s/infra/cert-manager-resources/cluster-issuers-hetzner.yaml +59 -0
  107. package/carbon/k8s/infra/cert-manager-resources/cluster-issuers-manual.yaml +43 -0
  108. package/carbon/k8s/infra/cert-manager-resources/kustomization.yaml +15 -0
  109. package/carbon/k8s/infra/kustomization.yaml +21 -0
  110. package/carbon/k8s/infra/traefik-crds/kustomization.yaml +10 -0
  111. package/carbon/k8s/overlays/local/configmap.yaml +23 -0
  112. package/carbon/k8s/overlays/local/ingressroute-studio.yaml +104 -0
  113. package/carbon/k8s/overlays/local/kustomization.yaml +215 -0
  114. package/carbon/k8s/overlays/local/namespace.yaml +8 -0
  115. package/carbon/k8s/overlays/local/secrets.yaml +32 -0
  116. package/carbon/k8s/overlays/production/kustomization.yaml +34 -0
  117. package/carbon/k8s/test-local.sh +318 -0
  118. package/carbon/k8s/values/supabase.values.yaml +133 -0
  119. package/carbon/package.json +154 -0
  120. package/carbon/runtime.Dockerfile +17 -0
  121. package/carbon/scripts/_dev-jwt.mjs +45 -0
  122. package/carbon/scripts/check-rls.ts +53 -0
  123. package/carbon/scripts/dev-init.js +191 -0
  124. package/carbon/scripts/dev.js +191 -0
  125. package/carbon/scripts/docker-down.js +63 -0
  126. package/carbon/scripts/docker-logs.js +59 -0
  127. package/carbon/scripts/docker-up.js +222 -0
  128. package/carbon/scripts/generate-dev-configs.sh +131 -0
  129. package/carbon/scripts/generate-rss.ts +116 -0
  130. package/carbon/scripts/generate-sitemap.ts +102 -0
  131. package/carbon/scripts/k8s-apply.js +71 -0
  132. package/carbon/scripts/k8s-delete.js +75 -0
  133. package/carbon/scripts/lib/manifest.js +176 -0
  134. package/carbon/scripts/secret-scan.mjs +278 -0
  135. package/carbon/scripts/validate-dev-configs.sh +101 -0
  136. package/carbon/src/client/App.tsx +202 -0
  137. package/carbon/src/client/assets/hyperformant-dark.svg +29 -0
  138. package/carbon/src/client/assets/hyperformant-light.svg +29 -0
  139. package/carbon/src/client/assets/logos/aider.svg +1 -0
  140. package/carbon/src/client/assets/logos/antigravity.svg +1 -0
  141. package/carbon/src/client/assets/logos/bolt.svg +1 -0
  142. package/carbon/src/client/assets/logos/claude-code.svg +1 -0
  143. package/carbon/src/client/assets/logos/copilot.svg +1 -0
  144. package/carbon/src/client/assets/logos/cursor.svg +1 -0
  145. package/carbon/src/client/assets/logos/gemini-cli.svg +1 -0
  146. package/carbon/src/client/assets/logos/lovable.svg +1 -0
  147. package/carbon/src/client/assets/logos/openai-codex.svg +1 -0
  148. package/carbon/src/client/assets/logos/v0.svg +1 -0
  149. package/carbon/src/client/assets/logos/windsurf.svg +1 -0
  150. package/carbon/src/client/assets/vibecarbon-icon.svg +19 -0
  151. package/carbon/src/client/assets/vibecarbon-logo-dark.svg +29 -0
  152. package/carbon/src/client/assets/vibecarbon-logo-light.svg +29 -0
  153. package/carbon/src/client/components/AIIntegrationSection.tsx +120 -0
  154. package/carbon/src/client/components/AppSidebar.tsx +760 -0
  155. package/carbon/src/client/components/ArchitectureSection.tsx +46 -0
  156. package/carbon/src/client/components/CTAFooter.tsx +59 -0
  157. package/carbon/src/client/components/ComparisonSection.tsx +132 -0
  158. package/carbon/src/client/components/ContentPanel.tsx +66 -0
  159. package/carbon/src/client/components/ContentSkeleton.tsx +21 -0
  160. package/carbon/src/client/components/ErrorBoundary.tsx +46 -0
  161. package/carbon/src/client/components/FAQSection.tsx +76 -0
  162. package/carbon/src/client/components/FileUpload.tsx +210 -0
  163. package/carbon/src/client/components/HeaderActions.tsx +17 -0
  164. package/carbon/src/client/components/Hero.tsx +608 -0
  165. package/carbon/src/client/components/ImpersonationBanner.tsx +31 -0
  166. package/carbon/src/client/components/LanguageSwitcher.tsx +67 -0
  167. package/carbon/src/client/components/Logo.tsx +87 -0
  168. package/carbon/src/client/components/LogoStrip.tsx +76 -0
  169. package/carbon/src/client/components/MetricsStrip.tsx +48 -0
  170. package/carbon/src/client/components/Nav.tsx +195 -0
  171. package/carbon/src/client/components/NewsletterSignup.tsx +147 -0
  172. package/carbon/src/client/components/NotificationDrawer.tsx +171 -0
  173. package/carbon/src/client/components/PageHeader.tsx +24 -0
  174. package/carbon/src/client/components/PlanGate.tsx +36 -0
  175. package/carbon/src/client/components/PricingSection.tsx +371 -0
  176. package/carbon/src/client/components/SEO.tsx +34 -0
  177. package/carbon/src/client/components/SmoothScroll.tsx +45 -0
  178. package/carbon/src/client/components/TechStackSection.tsx +165 -0
  179. package/carbon/src/client/components/WorkflowSection.tsx +604 -0
  180. package/carbon/src/client/components/admin/DockerLogs.tsx +276 -0
  181. package/carbon/src/client/components/admin/PerformanceMetrics.tsx +230 -0
  182. package/carbon/src/client/components/admin/ServiceCard.tsx +45 -0
  183. package/carbon/src/client/components/admin/ServicesStatus.tsx +296 -0
  184. package/carbon/src/client/components/architecture/ArchitectureDiagram.tsx +413 -0
  185. package/carbon/src/client/components/auth/AuthProvider.tsx +466 -0
  186. package/carbon/src/client/components/effects/FilmGrainOverlay.tsx +35 -0
  187. package/carbon/src/client/components/effects/FresnelEdge.tsx +49 -0
  188. package/carbon/src/client/components/effects/GlowTracker.tsx +46 -0
  189. package/carbon/src/client/components/effects/SparkBurst.tsx +145 -0
  190. package/carbon/src/client/components/effects/VGlowEffect.tsx +83 -0
  191. package/carbon/src/client/components/effects/index.ts +2 -0
  192. package/carbon/src/client/components/layouts/SidebarLayout.tsx +20 -0
  193. package/carbon/src/client/components/scroll/ScrollSection.tsx +76 -0
  194. package/carbon/src/client/components/scroll/ScrollytellingProvider.tsx +81 -0
  195. package/carbon/src/client/components/scroll/index.ts +2 -0
  196. package/carbon/src/client/components/ui/accordion.tsx +71 -0
  197. package/carbon/src/client/components/ui/alert-dialog.tsx +162 -0
  198. package/carbon/src/client/components/ui/alert.tsx +73 -0
  199. package/carbon/src/client/components/ui/aspect-ratio.tsx +22 -0
  200. package/carbon/src/client/components/ui/avatar.tsx +91 -0
  201. package/carbon/src/client/components/ui/badge.tsx +50 -0
  202. package/carbon/src/client/components/ui/breadcrumb.tsx +100 -0
  203. package/carbon/src/client/components/ui/button-group.tsx +78 -0
  204. package/carbon/src/client/components/ui/button.tsx +120 -0
  205. package/carbon/src/client/components/ui/calendar.tsx +182 -0
  206. package/carbon/src/client/components/ui/card.tsx +85 -0
  207. package/carbon/src/client/components/ui/carousel.tsx +227 -0
  208. package/carbon/src/client/components/ui/chart.tsx +357 -0
  209. package/carbon/src/client/components/ui/checkbox.tsx +27 -0
  210. package/carbon/src/client/components/ui/collapsible.tsx +15 -0
  211. package/carbon/src/client/components/ui/command.tsx +178 -0
  212. package/carbon/src/client/components/ui/context-menu.tsx +233 -0
  213. package/carbon/src/client/components/ui/dialog.tsx +132 -0
  214. package/carbon/src/client/components/ui/drawer.tsx +118 -0
  215. package/carbon/src/client/components/ui/dropdown-menu.tsx +242 -0
  216. package/carbon/src/client/components/ui/empty.tsx +94 -0
  217. package/carbon/src/client/components/ui/field.tsx +226 -0
  218. package/carbon/src/client/components/ui/hover-card.tsx +44 -0
  219. package/carbon/src/client/components/ui/input-group.tsx +146 -0
  220. package/carbon/src/client/components/ui/input-otp.tsx +83 -0
  221. package/carbon/src/client/components/ui/input.tsx +20 -0
  222. package/carbon/src/client/components/ui/item.tsx +188 -0
  223. package/carbon/src/client/components/ui/kbd.tsx +26 -0
  224. package/carbon/src/client/components/ui/label.tsx +21 -0
  225. package/carbon/src/client/components/ui/menubar.tsx +250 -0
  226. package/carbon/src/client/components/ui/navigation-menu.tsx +155 -0
  227. package/carbon/src/client/components/ui/pagination.tsx +102 -0
  228. package/carbon/src/client/components/ui/popover.tsx +75 -0
  229. package/carbon/src/client/components/ui/progress.tsx +66 -0
  230. package/carbon/src/client/components/ui/radio-group.tsx +36 -0
  231. package/carbon/src/client/components/ui/resizable.tsx +46 -0
  232. package/carbon/src/client/components/ui/scroll-area.tsx +48 -0
  233. package/carbon/src/client/components/ui/select.tsx +186 -0
  234. package/carbon/src/client/components/ui/separator.tsx +21 -0
  235. package/carbon/src/client/components/ui/sheet.tsx +124 -0
  236. package/carbon/src/client/components/ui/sidebar.tsx +702 -0
  237. package/carbon/src/client/components/ui/skeleton.tsx +13 -0
  238. package/carbon/src/client/components/ui/slider.tsx +57 -0
  239. package/carbon/src/client/components/ui/sonner.tsx +45 -0
  240. package/carbon/src/client/components/ui/spinner.tsx +15 -0
  241. package/carbon/src/client/components/ui/switch.tsx +30 -0
  242. package/carbon/src/client/components/ui/table.tsx +89 -0
  243. package/carbon/src/client/components/ui/tabs.tsx +73 -0
  244. package/carbon/src/client/components/ui/textarea.tsx +18 -0
  245. package/carbon/src/client/components/ui/toggle-group.tsx +87 -0
  246. package/carbon/src/client/components/ui/toggle.tsx +44 -0
  247. package/carbon/src/client/components/ui/tooltip.tsx +56 -0
  248. package/carbon/src/client/hooks/api/index.ts +14 -0
  249. package/carbon/src/client/hooks/api/useAuthSettings.ts +80 -0
  250. package/carbon/src/client/hooks/api/useSubscription.ts +87 -0
  251. package/carbon/src/client/hooks/use-mobile.ts +21 -0
  252. package/carbon/src/client/hooks/useMousePosition.ts +91 -0
  253. package/carbon/src/client/hooks/useNotifications.tsx +124 -0
  254. package/carbon/src/client/hooks/useOrganizationMembers.ts +127 -0
  255. package/carbon/src/client/hooks/useOrganizations.tsx +230 -0
  256. package/carbon/src/client/hooks/usePackageManager.ts +69 -0
  257. package/carbon/src/client/hooks/useReducedMotion.ts +20 -0
  258. package/carbon/src/client/hooks/useRunningServices.ts +114 -0
  259. package/carbon/src/client/hooks/useScrollProgress.ts +56 -0
  260. package/carbon/src/client/index.css +467 -0
  261. package/carbon/src/client/index.html +56 -0
  262. package/carbon/src/client/lib/admin-services.ts +151 -0
  263. package/carbon/src/client/lib/api.ts +32 -0
  264. package/carbon/src/client/lib/blog.ts +35 -0
  265. package/carbon/src/client/lib/changelog.ts +33 -0
  266. package/carbon/src/client/lib/docs-search.ts +101 -0
  267. package/carbon/src/client/lib/docs.ts +37 -0
  268. package/carbon/src/client/lib/i18n.ts +32 -0
  269. package/carbon/src/client/lib/supabase.ts +72 -0
  270. package/carbon/src/client/lib/tailwind-colors.ts +357 -0
  271. package/carbon/src/client/lib/theme.ts +117 -0
  272. package/carbon/src/client/lib/utils.ts +22 -0
  273. package/carbon/src/client/locales/de.json +529 -0
  274. package/carbon/src/client/locales/en.json +461 -0
  275. package/carbon/src/client/locales/es.json +529 -0
  276. package/carbon/src/client/locales/fr.json +529 -0
  277. package/carbon/src/client/locales/pt.json +529 -0
  278. package/carbon/src/client/main.tsx +56 -0
  279. package/carbon/src/client/mdx.d.ts +13 -0
  280. package/carbon/src/client/pages/ApiDocs.tsx +76 -0
  281. package/carbon/src/client/pages/AuthCallback.tsx +34 -0
  282. package/carbon/src/client/pages/Blog.tsx +167 -0
  283. package/carbon/src/client/pages/Changelog.tsx +171 -0
  284. package/carbon/src/client/pages/Charts.tsx +388 -0
  285. package/carbon/src/client/pages/Checkout.tsx +227 -0
  286. package/carbon/src/client/pages/Contact.tsx +174 -0
  287. package/carbon/src/client/pages/Dashboard.tsx +368 -0
  288. package/carbon/src/client/pages/Docs.tsx +372 -0
  289. package/carbon/src/client/pages/ForgotPassword.tsx +111 -0
  290. package/carbon/src/client/pages/Home.tsx +187 -0
  291. package/carbon/src/client/pages/Legal.tsx +100 -0
  292. package/carbon/src/client/pages/Login.tsx +408 -0
  293. package/carbon/src/client/pages/MFAVerify.tsx +156 -0
  294. package/carbon/src/client/pages/NotFound.tsx +21 -0
  295. package/carbon/src/client/pages/Onboarding.tsx +246 -0
  296. package/carbon/src/client/pages/ResetPassword.tsx +200 -0
  297. package/carbon/src/client/pages/UIComponents.tsx +390 -0
  298. package/carbon/src/client/pages/admin/ContactSubmissions.tsx +220 -0
  299. package/carbon/src/client/pages/admin/Dashboard.tsx +24 -0
  300. package/carbon/src/client/pages/admin/Infrastructure.tsx +257 -0
  301. package/carbon/src/client/pages/admin/Jobs.tsx +225 -0
  302. package/carbon/src/client/pages/admin/Logs.tsx +18 -0
  303. package/carbon/src/client/pages/admin/Newsletter.tsx +300 -0
  304. package/carbon/src/client/pages/admin/Notifications.tsx +603 -0
  305. package/carbon/src/client/pages/admin/Organizations.tsx +306 -0
  306. package/carbon/src/client/pages/admin/Settings.tsx +314 -0
  307. package/carbon/src/client/pages/admin/Theme.tsx +465 -0
  308. package/carbon/src/client/pages/admin/Users.tsx +365 -0
  309. package/carbon/src/client/pages/api-docs.css +156 -0
  310. package/carbon/src/client/pages/organizations/Details.tsx +200 -0
  311. package/carbon/src/client/pages/organizations/Members.tsx +402 -0
  312. package/carbon/src/client/pages/settings/Billing.tsx +473 -0
  313. package/carbon/src/client/pages/settings/Profile.tsx +160 -0
  314. package/carbon/src/client/pages/settings/Security.tsx +341 -0
  315. package/carbon/src/client/public/favicon.svg +19 -0
  316. package/carbon/src/client/public/robots.txt +8 -0
  317. package/carbon/src/server/billing/index.ts +104 -0
  318. package/carbon/src/server/billing/provider.ts +81 -0
  319. package/carbon/src/server/billing/providers/paddle.ts +314 -0
  320. package/carbon/src/server/billing/providers/polar.ts +325 -0
  321. package/carbon/src/server/billing/providers/stripe.ts +233 -0
  322. package/carbon/src/server/emails/templates.ts +116 -0
  323. package/carbon/src/server/index.ts +554 -0
  324. package/carbon/src/server/lib/auth.ts +6 -0
  325. package/carbon/src/server/lib/email.ts +64 -0
  326. package/carbon/src/server/lib/env.ts +112 -0
  327. package/carbon/src/server/lib/errors.ts +21 -0
  328. package/carbon/src/server/lib/logger.ts +17 -0
  329. package/carbon/src/server/lib/rate-limiter.ts +288 -0
  330. package/carbon/src/server/lib/request.ts +34 -0
  331. package/carbon/src/server/lib/stripe.ts +42 -0
  332. package/carbon/src/server/lib/supabase.ts +65 -0
  333. package/carbon/src/server/middleware/requirePlan.ts +80 -0
  334. package/carbon/src/server/routes/_internal/services-status.ts +958 -0
  335. package/carbon/src/server/routes/_internal/verify-role.ts +185 -0
  336. package/carbon/src/server/routes/health.ts +48 -0
  337. package/carbon/src/server/routes/v1/admin/contact.ts +128 -0
  338. package/carbon/src/server/routes/v1/admin/jobs.ts +171 -0
  339. package/carbon/src/server/routes/v1/admin/newsletter.ts +237 -0
  340. package/carbon/src/server/routes/v1/auth.ts +390 -0
  341. package/carbon/src/server/routes/v1/billing.ts +718 -0
  342. package/carbon/src/server/routes/v1/contact.ts +93 -0
  343. package/carbon/src/server/routes/v1/index.ts +1333 -0
  344. package/carbon/src/server/routes/v1/newsletter.ts +181 -0
  345. package/carbon/src/server/routes/v1/performance.ts +157 -0
  346. package/carbon/src/server/routes/v1/stats.ts +170 -0
  347. package/carbon/src/server/routes/v1/theme.ts +106 -0
  348. package/carbon/src/server/routes/webhooks/billing.ts +376 -0
  349. package/carbon/src/server/routes/webhooks/stripe.ts +276 -0
  350. package/carbon/src/server/types.ts +11 -0
  351. package/carbon/src/shared/pricing.ts +155 -0
  352. package/carbon/src/shared/types.ts +338 -0
  353. package/carbon/supabase/migrations/00001_init.sql +717 -0
  354. package/carbon/supabase/migrations/00002_theme_settings.sql +13 -0
  355. package/carbon/supabase/migrations/00003_pg_cron.sql +121 -0
  356. package/carbon/supabase/migrations/00004_contact_newsletter.sql +81 -0
  357. package/carbon/supabase/migrations/00005_localization_languages.sql +22 -0
  358. package/carbon/supabase/seed.sql +16 -0
  359. package/carbon/tests/_helpers/app.ts +45 -0
  360. package/carbon/tests/_helpers/env.ts +37 -0
  361. package/carbon/tests/_helpers/factories.ts +69 -0
  362. package/carbon/tests/_helpers/jwt.ts +23 -0
  363. package/carbon/tests/_helpers/setup-integration.ts +20 -0
  364. package/carbon/tests/_helpers/setup-rtl.ts +12 -0
  365. package/carbon/tests/component/ErrorBoundary.test.tsx +53 -0
  366. package/carbon/tests/component/use-auth-settings.test.tsx +119 -0
  367. package/carbon/tests/integration/server/routes/contact.test.ts +162 -0
  368. package/carbon/tests/integration/server/routes/health.test.ts +61 -0
  369. package/carbon/tests/structural/i18n-parity.test.ts +42 -0
  370. package/carbon/tests/unit/client/utils.test.ts +49 -0
  371. package/carbon/tests/unit/shared/pricing.test.ts +93 -0
  372. package/carbon/tsconfig.json +27 -0
  373. package/carbon/tsconfig.server.json +27 -0
  374. package/carbon/tsconfig.test.json +9 -0
  375. package/carbon/vite.config.ts +110 -0
  376. package/carbon/vitest.config.ts +74 -0
  377. package/carbon/volumes/db/jwt.sql +57 -0
  378. package/carbon/volumes/db/metabase-init.sh +29 -0
  379. package/carbon/volumes/db/n8n-init.sh +25 -0
  380. package/carbon/volumes/db/realtime.sql +33 -0
  381. package/carbon/volumes/db/roles.sql +93 -0
  382. package/carbon/volumes/db/set-passwords.sh +12 -0
  383. package/carbon/volumes/db/super-admin.dev.sql +113 -0
  384. package/carbon/volumes/db/super-admin.generated.sql +113 -0
  385. package/carbon/volumes/db/super-admin.sql +114 -0
  386. package/carbon/volumes/grafana/dashboards/logs.json +179 -0
  387. package/carbon/volumes/grafana/dashboards/overview.json +523 -0
  388. package/carbon/volumes/grafana/dashboards/postgresql.json +337 -0
  389. package/carbon/volumes/grafana/dashboards.dev/logs.json +179 -0
  390. package/carbon/volumes/grafana/dashboards.dev/overview.json +156 -0
  391. package/carbon/volumes/grafana/dashboards.dev/postgresql.json +337 -0
  392. package/carbon/volumes/grafana/provisioning/dashboards/dashboards.dev.yml +16 -0
  393. package/carbon/volumes/grafana/provisioning/dashboards/dashboards.yml +16 -0
  394. package/carbon/volumes/grafana/provisioning/datasources/datasources.yml +43 -0
  395. package/carbon/volumes/kong/docker-entrypoint.sh +9 -0
  396. package/carbon/volumes/kong/kong.yml +208 -0
  397. package/carbon/volumes/loki/loki-config.yml +58 -0
  398. package/carbon/volumes/n8n/hooks.js +131 -0
  399. package/carbon/volumes/n8n/scripts/setup.sh +66 -0
  400. package/carbon/volumes/prometheus/prometheus.yml +43 -0
  401. package/carbon/volumes/promtail/promtail-config.yml +64 -0
  402. package/carbon/volumes/traefik/middlewares.dev.yml +83 -0
  403. package/carbon/volumes/traefik/middlewares.yml +95 -0
  404. package/carbon/volumes/traefik/vite-dev.yml +20 -0
  405. package/package.json +95 -0
  406. package/src/access.js +354 -0
  407. package/src/activate.js +187 -0
  408. package/src/add.js +718 -0
  409. package/src/backup.js +786 -0
  410. package/src/cli.js +350 -0
  411. package/src/configure.js +967 -0
  412. package/src/console.js +155 -0
  413. package/src/create.js +1499 -0
  414. package/src/deploy.js +311 -0
  415. package/src/destroy.js +2033 -0
  416. package/src/diagnose.js +735 -0
  417. package/src/down.js +80 -0
  418. package/src/failover.js +1032 -0
  419. package/src/lib/backup-s3.js +179 -0
  420. package/src/lib/build.js +33 -0
  421. package/src/lib/checksum.js +28 -0
  422. package/src/lib/ci-setup.js +666 -0
  423. package/src/lib/cli/help.js +129 -0
  424. package/src/lib/cli/parse-flags.js +160 -0
  425. package/src/lib/cli/select-action.js +65 -0
  426. package/src/lib/cli/select-environment.js +108 -0
  427. package/src/lib/cli/tty-guard.js +75 -0
  428. package/src/lib/cloudflare.js +447 -0
  429. package/src/lib/colors.js +52 -0
  430. package/src/lib/command.js +361 -0
  431. package/src/lib/config.js +359 -0
  432. package/src/lib/cost.js +103 -0
  433. package/src/lib/deploy/bundle.js +231 -0
  434. package/src/lib/deploy/compose/acme-verify.js +121 -0
  435. package/src/lib/deploy/compose/build-args.js +78 -0
  436. package/src/lib/deploy/compose/ha.js +1874 -0
  437. package/src/lib/deploy/compose/index.js +1294 -0
  438. package/src/lib/deploy/compose/reconcile.js +74 -0
  439. package/src/lib/deploy/github.js +382 -0
  440. package/src/lib/deploy/image.js +191 -0
  441. package/src/lib/deploy/index.js +119 -0
  442. package/src/lib/deploy/k8s/LICENSE +99 -0
  443. package/src/lib/deploy/k8s/gitops-deploy.js +298 -0
  444. package/src/lib/deploy/k8s/ha/index.js +1000 -0
  445. package/src/lib/deploy/k8s/index.js +62 -0
  446. package/src/lib/deploy/k8s/k3s.js +2515 -0
  447. package/src/lib/deploy/orchestrator.js +1401 -0
  448. package/src/lib/deploy/prompts.js +545 -0
  449. package/src/lib/deploy/remote-build.js +130 -0
  450. package/src/lib/deploy/state.js +120 -0
  451. package/src/lib/deploy/utils.js +328 -0
  452. package/src/lib/deploy-logger.js +93 -0
  453. package/src/lib/dns-propagation.js +48 -0
  454. package/src/lib/environment.js +58 -0
  455. package/src/lib/fetch-retry.js +103 -0
  456. package/src/lib/github-environments.js +335 -0
  457. package/src/lib/hetzner-dns.js +377 -0
  458. package/src/lib/hetzner-guided-setup.js +275 -0
  459. package/src/lib/host-keys.js +37 -0
  460. package/src/lib/iac/cloud-init.js +52 -0
  461. package/src/lib/iac/index.js +325 -0
  462. package/src/lib/iac/programs/hetzner-compose.js +130 -0
  463. package/src/lib/iac/programs/hetzner-k8s.js +320 -0
  464. package/src/lib/kubectl.js +81 -0
  465. package/src/lib/licensing/index.js +259 -0
  466. package/src/lib/licensing/tiers.js +181 -0
  467. package/src/lib/licensing/validator.js +171 -0
  468. package/src/lib/merge-package-json.js +90 -0
  469. package/src/lib/operator-ip.js +381 -0
  470. package/src/lib/package-manager.js +111 -0
  471. package/src/lib/perf.js +71 -0
  472. package/src/lib/project-guard.js +39 -0
  473. package/src/lib/project.js +334 -0
  474. package/src/lib/providers/base.js +276 -0
  475. package/src/lib/providers/hetzner-s3.js +656 -0
  476. package/src/lib/providers/hetzner.js +755 -0
  477. package/src/lib/providers/index.js +164 -0
  478. package/src/lib/s3.js +510 -0
  479. package/src/lib/secret-scan.js +583 -0
  480. package/src/lib/secrets.js +63 -0
  481. package/src/lib/server-types.js +195 -0
  482. package/src/lib/shell.js +91 -0
  483. package/src/lib/ssh.js +241 -0
  484. package/src/lib/tracker.js +242 -0
  485. package/src/lib/upgrade-policy.js +170 -0
  486. package/src/lib/validators.js +105 -0
  487. package/src/lib/version.js +5 -0
  488. package/src/remove.js +292 -0
  489. package/src/reset.js +97 -0
  490. package/src/restore.js +871 -0
  491. package/src/scale.js +1734 -0
  492. package/src/shell.js +222 -0
  493. package/src/status.js +981 -0
  494. package/src/up.js +264 -0
  495. package/src/upgrade.js +721 -0
@@ -0,0 +1,99 @@
1
+ Elastic License 2.0 (ELv2)
2
+
3
+ ## Acceptance
4
+
5
+ By using the Software, you agree to all of the terms and conditions below.
6
+
7
+ ## Copyright License
8
+
9
+ The licensor grants you a non-exclusive, royalty-free, worldwide,
10
+ non-sublicensable, non-transferable license to use, copy, distribute, make
11
+ available, and prepare derivative works of the Software, in each case subject
12
+ to the limitations and conditions below.
13
+
14
+ ## Limitations
15
+
16
+ You may not provide the Software to third parties as a hosted or managed
17
+ service, where the service provides users with access to any substantial set
18
+ of the features or functionality of the Software.
19
+
20
+ You may not move, change, disable, or circumvent the license key functionality
21
+ in the Software, and you may not remove or obscure any functionality in the
22
+ Software that is protected by the license key.
23
+
24
+ You may not alter, remove, or obscure any licensing, copyright, or other
25
+ notices of the licensor in the Software. Any use of the licensor's trademarks
26
+ is subject to applicable law.
27
+
28
+ ## Patents
29
+
30
+ The licensor grants you a license, under any patent claims the licensor can
31
+ license, or becomes able to license, to make, have made, use, sell, offer for
32
+ sale, import and have imported the Software, in each case subject to the
33
+ limitations and conditions in this license. This license does not cover any
34
+ patent claims that you cause to be infringed by modifications or additions to
35
+ the Software. If you or your company make any written claim that the Software
36
+ infringes or contributes to infringement of any patent, your patent license
37
+ for the Software granted under these terms ends immediately. If your company
38
+ makes such a claim, your patent license ends immediately for work on behalf of
39
+ your company.
40
+
41
+ ## Notices
42
+
43
+ You must ensure that anyone who gets a copy of any part of the Software from
44
+ you also gets a copy of these terms.
45
+
46
+ If you modify the Software, you must include in any modified copies of the
47
+ Software prominent notices stating that you have modified the Software.
48
+
49
+ ## No Other Rights
50
+
51
+ These terms do not imply any licenses other than those expressly granted in
52
+ these terms.
53
+
54
+ ## Termination
55
+
56
+ If you use the Software in violation of these terms, such use is not licensed,
57
+ and your licenses will automatically terminate. If the licensor provides you
58
+ with a notice of your violation, and you cease all violation of this license
59
+ no later than 30 days after you receive that notice, your licenses will be
60
+ reinstated retroactively. However, if you violate these terms after such
61
+ reinstatement, any additional violation of these terms will cause your
62
+ licenses to terminate automatically and permanently.
63
+
64
+ ## No Liability
65
+
66
+ As far as the law allows, the Software comes as is, without any warranty or
67
+ condition, and the licensor will not be liable to you for any damages arising
68
+ out of these terms or the use or nature of the Software, under any kind of
69
+ legal claim.
70
+
71
+ ## Definitions
72
+
73
+ The "licensor" is the entity offering these terms, Vibecarbon.
74
+
75
+ The "Software" is the software the licensor makes available under these terms,
76
+ including any portion of it.
77
+
78
+ "You" refers to the individual or entity agreeing to these terms.
79
+
80
+ "Your company" is any legal entity, sole proprietorship, or other kind of
81
+ organization that you work for, plus all organizations that have control over,
82
+ are under the control of, or are under common control with that organization.
83
+ "Control" means ownership of substantially all the assets of an entity, or the
84
+ power to direct its management and policies by vote, contract, or otherwise.
85
+ Control can be direct or indirect.
86
+
87
+ "Your licenses" are all the licenses granted to you for the Software under
88
+ these terms.
89
+
90
+ "Use" means anything you do with the Software requiring one of your licenses.
91
+
92
+ "Trademark" means trademarks, service marks, and similar rights.
93
+
94
+ ---
95
+
96
+ Copyright (c) 2026 Vibecarbon
97
+
98
+ For the full Elastic License 2.0 text, see:
99
+ https://www.elastic.co/licensing/elastic-license
@@ -0,0 +1,272 @@
1
+ # Vibecarbon Kubernetes Deployment (Fullerene Tier)
2
+
3
+ > **Note**: Kubernetes deployment requires a Vibecarbon Fullerene license. For compose-based deployments (including HA with PostgreSQL replication), see the [Hetzner deployment guide](../../docs/deploy-hetzner.md).
4
+
5
+ This directory contains Kubernetes manifests for deploying Vibecarbon with enterprise-grade autoscaling and high availability.
6
+
7
+ ## Architecture Overview
8
+
9
+ ```
10
+ Cloudflare DNS
11
+ (health checks, failover)
12
+ |
13
+ +---------------+---------------+
14
+ | |
15
+ Hetzner LB (nbg1) Hetzner LB (hel1)
16
+ | |
17
+ k3s Cluster k3s Cluster
18
+ +--------------+ +--------------+
19
+ | app: 2-10 | | app: 0 (standby)
20
+ | kong: 2 | WAL repl | kong: 0
21
+ | rest: 2-5 | <-----------> | rest: 0
22
+ | PostgreSQL | | PostgreSQL (replica)
23
+ | PRIMARY | | HOT STANDBY
24
+ +--------------+ +--------------+
25
+ ```
26
+
27
+ ## Directory Structure
28
+
29
+ ```
30
+ k8s/
31
+ ├── base/ # Base Kubernetes manifests
32
+ │ ├── namespace.yaml
33
+ │ ├── network-policy.yaml # Default-deny NetworkPolicy
34
+ │ ├── secrets/ # Secrets and ConfigMaps
35
+ │ ├── hetzner-ccm/ # Hetzner Cloud Controller
36
+ │ ├── hetzner-csi/ # Hetzner CSI Driver
37
+ │ ├── app/ # Vibecarbon application
38
+ │ │ ├── deployment.yaml
39
+ │ │ ├── local-registry.yaml # Local OCI registry for k3s image distribution
40
+ │ │ └── rbac.yaml # ServiceAccount for pod listing
41
+ │ ├── supabase/ # Supabase services
42
+ │ │ ├── postgres/
43
+ │ │ ├── kong/
44
+ │ │ ├── auth/
45
+ │ │ ├── rest/
46
+ │ │ ├── realtime/
47
+ │ │ ├── storage/
48
+ │ │ ├── imgproxy/
49
+ │ │ ├── meta/
50
+ │ │ └── studio/
51
+ │ └── traefik/ # Ingress controller
52
+ ├── infra/ # Infrastructure-level resources (applied once)
53
+ │ └── cert-manager-resources/ # ClusterIssuers for TLS certificates
54
+ ├── overlays/ # Environment-specific patches
55
+ │ ├── production-nbg1/ # Primary region (Nuremberg)
56
+ │ └── production-hel1/ # Standby region (Helsinki)
57
+ └── flux/ # GitOps configuration
58
+ └── clusters/
59
+ ├── primary/
60
+ └── standby/
61
+ ```
62
+
63
+ ## Prerequisites
64
+
65
+ 1. **Hetzner Cloud Account** with API token
66
+ 2. **Cloudflare Account** with API token and domain
67
+ 3. **kubectl** installed locally
68
+ 4. **kustomize** installed (or use `kubectl -k`)
69
+ 5. **Flux CLI** (optional, for GitOps)
70
+
71
+ ## Deployment Steps
72
+
73
+ ### Step 1: Provision Infrastructure
74
+
75
+ `vibecarbon deploy <env>` provisions the Hetzner servers, network, firewall,
76
+ and floating IP via Pulumi (Automation API; no Pulumi CLI required). Stack
77
+ state is stored in your Hetzner S3 bucket — there are no `.tf` files or
78
+ local state to manage.
79
+
80
+ ```bash
81
+ vibecarbon deploy production
82
+ ```
83
+
84
+ For HA (two regions), pass `--ha`. The command writes the resulting
85
+ kubeconfig(s) to `~/.vibecarbon/kubeconfig-<env>-<region>.yaml`.
86
+
87
+ ### Step 2: Get Kubeconfig
88
+
89
+ ```bash
90
+ export KUBECONFIG=~/.vibecarbon/kubeconfig-production-nbg1.yaml
91
+
92
+ # For HA, the standby kubeconfig is alongside it:
93
+ # ~/.vibecarbon/kubeconfig-production-hel1.yaml
94
+ ```
95
+
96
+ ### Step 3: Deploy Secrets
97
+
98
+ Before deploying, update the secrets with real values:
99
+
100
+ ```bash
101
+ # Create secrets manually (recommended for initial setup)
102
+ kubectl create secret generic vibecarbon-secrets \
103
+ --namespace=vibecarbon \
104
+ --from-literal=DB_PASSWORD=<your-password> \
105
+ --from-literal=JWT_SECRET=<your-jwt-secret> \
106
+ --from-literal=ANON_KEY=<your-anon-key> \
107
+ --from-literal=SERVICE_ROLE_KEY=<your-service-key> \
108
+ --from-literal=REALTIME_SECRET=<your-realtime-secret> \
109
+ --from-literal=VAULT_ENC_KEY=<your-vault-key> \
110
+ --from-literal=PG_META_CRYPTO_KEY=<your-meta-key> \
111
+ --from-literal=LOGFLARE_API_KEY=<your-logflare-key>
112
+
113
+ kubectl create secret generic hcloud-token \
114
+ --namespace=vibecarbon \
115
+ --from-literal=token=<your-hetzner-token>
116
+ ```
117
+
118
+ ### Step 4: Deploy to Primary Cluster
119
+
120
+ ```bash
121
+ export KUBECONFIG=kubeconfig-nbg1.yaml
122
+
123
+ # Using kustomize
124
+ kubectl apply -k overlays/production-nbg1
125
+
126
+ # Or using kubectl
127
+ kustomize build overlays/production-nbg1 | kubectl apply -f -
128
+ ```
129
+
130
+ ### Step 5: Deploy to Standby Cluster
131
+
132
+ ```bash
133
+ export KUBECONFIG=kubeconfig-hel1.yaml
134
+ kubectl apply -k overlays/production-hel1
135
+ ```
136
+
137
+ ### Step 6: Verify Deployment
138
+
139
+ ```bash
140
+ # Check pods
141
+ kubectl get pods -n vibecarbon
142
+
143
+ # Check HPA
144
+ kubectl get hpa -n vibecarbon
145
+
146
+ # Check services
147
+ kubectl get svc -n vibecarbon
148
+
149
+ # Check ingress/load balancer
150
+ kubectl get svc traefik -n vibecarbon
151
+ ```
152
+
153
+ ## Autoscaling
154
+
155
+ ### Horizontal Pod Autoscaler (HPA)
156
+
157
+ The following services have HPA configured:
158
+
159
+ | Service | Min Replicas | Max Replicas | CPU Target |
160
+ |---------|--------------|--------------|------------|
161
+ | app | 2 | 10 | 70% |
162
+ | rest | 2 | 5 | 70% |
163
+
164
+ Worker VMs are provisioned via `vibecarbon deploy --min-workers N --max-workers M` (default `min=1, max=3`). The static floor is Pulumi-managed; cluster-autoscaler spawns and reaps additional workers (up to `max - min`) based on pending-pod pressure. See the Cluster Autoscaler section below.
165
+
166
+ ### Cluster Autoscaler (VPS-level)
167
+
168
+ VPS-level autoscaling is on by default with a bounded ceiling — every k8s deploy installs cluster-autoscaler against the Hetzner Cloud API.
169
+
170
+ **Defaults**
171
+
172
+ - `min=1, max=3` — one static worker, plus up to two CA-spawned workers on demand.
173
+
174
+ **Deploy-time bounds**
175
+
176
+ ```bash
177
+ # Override the default bounds at deploy
178
+ vibecarbon deploy prod --k8s --min-workers 2 --max-workers 10
179
+ ```
180
+
181
+ **Re-tuning bounds without a full deploy**
182
+
183
+ ```bash
184
+ # Change the upper bound only — no Pulumi run needed for the CA-managed pool
185
+ vibecarbon scale prod --max-workers 8
186
+
187
+ # Or both bounds at once
188
+ vibecarbon scale prod --min-workers 2 --max-workers 8
189
+ ```
190
+
191
+ **Static floor + CA-on-top model**
192
+
193
+ | Layer | Managed by | Server name pattern |
194
+ |-------|-----------|---------------------|
195
+ | Static floor (`minWorkers` nodes) | Pulumi | `<cluster>-worker-N` (deterministic) |
196
+ | CA-spawned (0 to `max - min` extra nodes) | cluster-autoscaler via Hetzner Cloud API | `worker-pool-<rand>` |
197
+
198
+ The static floor is what your project quota is reserved for; CA scales additional workers on top of it as pending pods appear, then reaps them when CPU pressure subsides.
199
+
200
+ **HA mode symmetry**
201
+
202
+ In `--ha` mode both clusters use the same `--min-workers/--max-workers` bounds — the standby is kept failover-ready (its scaler doesn't bring up additional workers while the cluster is dormant, but the bounds are pre-configured so failover is instant).
203
+
204
+ **Hetzner project quota**
205
+
206
+ Trial Hetzner Cloud projects cap at ~50 servers across all resource types; verified accounts get higher limits. If you set `--max-workers` aggressively, make sure your project quota covers the worst case across all clusters in the project (master + supabase + workers + CA-spawned, x2 in HA).
207
+
208
+ **Token requirement: Read+Write**
209
+
210
+ The Hetzner Cloud API token in your `hcloud-token` secret must have **Read+Write** permissions on the project. Read-only tokens cannot create servers, and CA scale-up will fail silently with permission errors in the cluster-autoscaler pod logs. Verify with:
211
+
212
+ ```bash
213
+ kubectl logs -n kube-system -l app=cluster-autoscaler --tail=200 | grep -i 'permission\|forbidden\|unauthor'
214
+ ```
215
+
216
+ ## Failover
217
+
218
+ Cloudflare DNS health checks monitor both regions every 60 seconds. When the primary region fails, initiate failover with one command:
219
+
220
+ ```bash
221
+ vibecarbon failover prod
222
+ ```
223
+
224
+ This promotes the standby database to primary, scales up services in the standby region, and updates DNS to point to the new primary.
225
+
226
+ ### Manual Failover (kubectl)
227
+
228
+ To failover manually with kubectl:
229
+
230
+ ```bash
231
+ # Scale up standby
232
+ export KUBECONFIG=kubeconfig-hel1.yaml
233
+ kubectl scale deployment app --replicas=2 -n vibecarbon
234
+ kubectl scale deployment kong --replicas=2 -n vibecarbon
235
+ kubectl scale deployment auth --replicas=2 -n vibecarbon
236
+ kubectl scale deployment rest --replicas=2 -n vibecarbon
237
+ kubectl scale deployment realtime --replicas=2 -n vibecarbon
238
+ ```
239
+
240
+ ## Monitoring (Optional)
241
+
242
+ To enable Prometheus + Grafana monitoring:
243
+
244
+ ```bash
245
+ kubectl apply -k base/monitoring/ # If monitoring manifests exist
246
+ ```
247
+
248
+ ## Troubleshooting
249
+
250
+ ### Pods not starting
251
+
252
+ ```bash
253
+ kubectl describe pod <pod-name> -n vibecarbon
254
+ kubectl logs <pod-name> -n vibecarbon
255
+ ```
256
+
257
+ ### Load Balancer not created
258
+
259
+ ```bash
260
+ kubectl describe svc traefik -n vibecarbon
261
+ kubectl logs -l app=hcloud-cloud-controller-manager -n kube-system
262
+ ```
263
+
264
+ ## Cost Estimate
265
+
266
+ | Component | Monthly Cost (EUR) |
267
+ |-----------|-------------------|
268
+ | k3s master x2 | 8.70 |
269
+ | k3s workers (1-10) | 4-44 |
270
+ | Hetzner LB x2 | 10.78 |
271
+ | Hetzner volumes | ~2 |
272
+ | **Total** | **~25-65** |
@@ -0,0 +1,130 @@
1
+ apiVersion: apps/v1
2
+ kind: Deployment
3
+ metadata:
4
+ name: app
5
+ labels:
6
+ app: vibecarbon-app
7
+ component: application
8
+ spec:
9
+ replicas: 2
10
+ # 900s (15m) — cold k8s deploys race the rollout window: `kubectl set image`
11
+ # triggers the rollout BEFORE `helm install supabase --wait` returns, and the
12
+ # app's readiness probe (/api/health/ready) stays 503 until kong is up. On
13
+ # the slow HA path the sideload + helm install consumed >29m before kong was
14
+ # reachable; the old 120s deadline tripped before kong existed and the
15
+ # subsequent `kubectl rollout status` failed even though pods were healthy
16
+ # by then. 900s covers worst-observed cold path; warm rollouts still finish
17
+ # in <60s so this only matters on the cold cycle.
18
+ progressDeadlineSeconds: 900
19
+ strategy:
20
+ type: RollingUpdate
21
+ rollingUpdate:
22
+ maxUnavailable: 0
23
+ maxSurge: 1
24
+ selector:
25
+ matchLabels:
26
+ app: vibecarbon-app
27
+ template:
28
+ metadata:
29
+ labels:
30
+ app: vibecarbon-app
31
+ component: application
32
+ spec:
33
+ terminationGracePeriodSeconds: 30
34
+ serviceAccountName: vibecarbon-app
35
+ containers:
36
+ - name: app
37
+ image: ghcr.io/{{GITHUB_OWNER}}/{{PROJECT_NAME}}:main
38
+ imagePullPolicy: IfNotPresent
39
+ securityContext:
40
+ runAsNonRoot: true
41
+ runAsUser: 1000
42
+ runAsGroup: 1000
43
+ readOnlyRootFilesystem: true
44
+ allowPrivilegeEscalation: false
45
+ capabilities:
46
+ drop:
47
+ - ALL
48
+ ports:
49
+ - containerPort: 3000
50
+ name: http
51
+ envFrom:
52
+ - configMapRef:
53
+ name: vibecarbon-config
54
+ env:
55
+ - name: NODE_ENV
56
+ value: production
57
+ - name: SUPABASE_URL
58
+ valueFrom:
59
+ configMapKeyRef:
60
+ name: vibecarbon-config
61
+ key: KONG_URL
62
+ - name: SITE_URL
63
+ valueFrom:
64
+ configMapKeyRef:
65
+ name: vibecarbon-config
66
+ key: SITE_URL
67
+ - name: SUPABASE_ANON_KEY
68
+ valueFrom:
69
+ secretKeyRef:
70
+ name: vibecarbon-secrets
71
+ key: ANON_KEY
72
+ - name: SUPABASE_SERVICE_ROLE_KEY
73
+ valueFrom:
74
+ secretKeyRef:
75
+ name: vibecarbon-secrets
76
+ key: SERVICE_ROLE_KEY
77
+ resources:
78
+ requests:
79
+ cpu: 100m
80
+ memory: 256Mi
81
+ limits:
82
+ cpu: 1000m
83
+ memory: 512Mi
84
+ startupProbe:
85
+ httpGet:
86
+ path: /api/health
87
+ port: http
88
+ failureThreshold: 5
89
+ periodSeconds: 1
90
+ livenessProbe:
91
+ httpGet:
92
+ path: /api/health
93
+ port: http
94
+ initialDelaySeconds: 10
95
+ periodSeconds: 30
96
+ timeoutSeconds: 5
97
+ failureThreshold: 5
98
+ readinessProbe:
99
+ httpGet:
100
+ path: /api/health/ready
101
+ port: http
102
+ initialDelaySeconds: 0
103
+ periodSeconds: 3
104
+ timeoutSeconds: 3
105
+ failureThreshold: 3
106
+ lifecycle:
107
+ preStop:
108
+ exec:
109
+ command:
110
+ - sh
111
+ - -c
112
+ - sleep 5
113
+ volumeMounts:
114
+ - name: tmp
115
+ mountPath: /tmp
116
+ volumes:
117
+ - name: tmp
118
+ emptyDir: {}
119
+ affinity:
120
+ podAntiAffinity:
121
+ preferredDuringSchedulingIgnoredDuringExecution:
122
+ - weight: 100
123
+ podAffinityTerm:
124
+ labelSelector:
125
+ matchLabels:
126
+ app: vibecarbon-app
127
+ topologyKey: kubernetes.io/hostname
128
+ securityContext:
129
+ seccompProfile:
130
+ type: RuntimeDefault
@@ -0,0 +1,44 @@
1
+ apiVersion: autoscaling/v2
2
+ kind: HorizontalPodAutoscaler
3
+ metadata:
4
+ name: app
5
+ labels:
6
+ app: vibecarbon-app
7
+ component: application
8
+ spec:
9
+ scaleTargetRef:
10
+ apiVersion: apps/v1
11
+ kind: Deployment
12
+ name: app
13
+ minReplicas: 2
14
+ maxReplicas: 10
15
+ metrics:
16
+ - type: Resource
17
+ resource:
18
+ name: cpu
19
+ target:
20
+ type: Utilization
21
+ averageUtilization: 70
22
+ - type: Resource
23
+ resource:
24
+ name: memory
25
+ target:
26
+ type: Utilization
27
+ averageUtilization: 80
28
+ behavior:
29
+ scaleUp:
30
+ stabilizationWindowSeconds: 60
31
+ policies:
32
+ - type: Pods
33
+ value: 4
34
+ periodSeconds: 60
35
+ - type: Percent
36
+ value: 100
37
+ periodSeconds: 60
38
+ selectPolicy: Max
39
+ scaleDown:
40
+ stabilizationWindowSeconds: 300
41
+ policies:
42
+ - type: Pods
43
+ value: 1
44
+ periodSeconds: 120
@@ -0,0 +1,10 @@
1
+ apiVersion: kustomize.config.k8s.io/v1beta1
2
+ kind: Kustomization
3
+
4
+ resources:
5
+ - deployment.yaml
6
+ - service.yaml
7
+ - hpa.yaml
8
+ - pdb.yaml
9
+ - rbac.yaml
10
+ - network-policy.yaml
@@ -0,0 +1,124 @@
1
+ apiVersion: networking.k8s.io/v1
2
+ kind: NetworkPolicy
3
+ metadata:
4
+ name: app-policy
5
+ namespace: vibecarbon
6
+ spec:
7
+ podSelector:
8
+ matchLabels:
9
+ app: vibecarbon-app
10
+ policyTypes:
11
+ - Ingress
12
+ - Egress
13
+ ingress:
14
+ # Allow traffic from Traefik ingress controller (runs in same namespace)
15
+ - from:
16
+ - podSelector:
17
+ matchLabels:
18
+ app: vibecarbon-traefik
19
+ ports:
20
+ - protocol: TCP
21
+ port: 3000
22
+ egress:
23
+ # Allow connection to Kong (Supabase API gateway)
24
+ - to:
25
+ - podSelector:
26
+ matchLabels:
27
+ app: vibecarbon-kong
28
+ ports:
29
+ - protocol: TCP
30
+ port: 8000
31
+ # Allow connection to database (direct queries)
32
+ - to:
33
+ - podSelector:
34
+ matchLabels:
35
+ app: vibecarbon-postgres
36
+ ports:
37
+ - protocol: TCP
38
+ port: 5432
39
+ # Allow access to Kubernetes API server for reading pod logs (admin dashboard)
40
+ # 10.43.0.1:443 = ClusterIP via kube-proxy DNAT (works on worker nodes)
41
+ - to:
42
+ - ipBlock:
43
+ cidr: 10.43.0.1/32
44
+ ports:
45
+ - protocol: TCP
46
+ port: 443
47
+ # 0.0.0.0/0:6443 = apiserver, dial-anywhere on apiserver-protocol port.
48
+ # See carbon/k8s/base/traefik/network-policy.yaml for the full RCA. tl;dr:
49
+ # kube-proxy DNATs 10.43.0.1 to the master's node IP at the OUTPUT chain
50
+ # BEFORE the CNI evaluates egress, so the policy sees the post-NAT IP.
51
+ # With --node-ip=public (master-init.sh) and the CCM HCLOUD_NETWORK patch
52
+ # reverted (kubelet cert SAN), the master IP is public — outside any
53
+ # private CIDR we could list. Allow any destination on 6443; deny-by-
54
+ # default is preserved on every other port.
55
+ - to:
56
+ - ipBlock:
57
+ cidr: 0.0.0.0/0
58
+ ports:
59
+ - protocol: TCP
60
+ port: 6443
61
+ # Allow outbound HTTPS (Stripe, SMTP provider, external APIs)
62
+ - to:
63
+ - ipBlock:
64
+ cidr: 0.0.0.0/0
65
+ except:
66
+ - 10.0.0.0/8
67
+ - 172.16.0.0/12
68
+ - 192.168.0.0/16
69
+ ports:
70
+ - protocol: TCP
71
+ port: 443
72
+ # Allow connection to Redis (if configured)
73
+ - to:
74
+ - podSelector:
75
+ matchLabels:
76
+ app: redis
77
+ ports:
78
+ - protocol: TCP
79
+ port: 6379
80
+ # Allow health checks to optional services (n8n, metabase, observability)
81
+ # These are only used for the admin services-status API; unused rules are harmless.
82
+ - to:
83
+ - podSelector:
84
+ matchLabels:
85
+ app: vibecarbon-n8n
86
+ ports:
87
+ - protocol: TCP
88
+ port: 5678
89
+ - to:
90
+ - podSelector:
91
+ matchLabels:
92
+ app: metabase
93
+ ports:
94
+ - protocol: TCP
95
+ port: 3000
96
+ - to:
97
+ - podSelector:
98
+ matchLabels:
99
+ app: vibecarbon-prometheus
100
+ ports:
101
+ - protocol: TCP
102
+ port: 9090
103
+ - to:
104
+ - podSelector:
105
+ matchLabels:
106
+ app: vibecarbon-grafana
107
+ ports:
108
+ - protocol: TCP
109
+ port: 3000
110
+ - to:
111
+ - podSelector:
112
+ matchLabels:
113
+ app: vibecarbon-loki
114
+ ports:
115
+ - protocol: TCP
116
+ port: 3100
117
+ # Allow health checks to Studio (for admin services-status API)
118
+ - to:
119
+ - podSelector:
120
+ matchLabels:
121
+ app: vibecarbon-studio
122
+ ports:
123
+ - protocol: TCP
124
+ port: 3000
@@ -0,0 +1,14 @@
1
+ apiVersion: policy/v1
2
+ kind: PodDisruptionBudget
3
+ metadata:
4
+ name: app
5
+ labels:
6
+ app: vibecarbon-app
7
+ component: application
8
+ spec:
9
+ # Ensure at least 1 pod is available during voluntary disruptions
10
+ # (e.g., node upgrades, cluster maintenance, kubectl drain)
11
+ minAvailable: 1
12
+ selector:
13
+ matchLabels:
14
+ app: vibecarbon-app