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.
- package/LICENSE +663 -0
- package/README.md +188 -0
- package/carbon/.claude/hooks/task-completed-gate.sh +19 -0
- package/carbon/.claude/hooks/teammate-idle-gate.sh +29 -0
- package/carbon/.claude/settings.json +29 -0
- package/carbon/.cursor/rules/vibecarbon.mdc +6 -0
- package/carbon/.dockerignore +57 -0
- package/carbon/.env.example +219 -0
- package/carbon/.github/copilot-instructions.md +3 -0
- package/carbon/.github/workflows/deploy.yml +346 -0
- package/carbon/.github/workflows/vibecarbon-build.yml +81 -0
- package/carbon/.windsurfrules +74 -0
- package/carbon/AGENTS.md +422 -0
- package/carbon/CLAUDE.md +3 -0
- package/carbon/DEVELOPMENT.md +187 -0
- package/carbon/Dockerfile +98 -0
- package/carbon/LICENSE +21 -0
- package/carbon/PRODUCTION.md +364 -0
- package/carbon/README.md +193 -0
- package/carbon/TESTING.md +138 -0
- package/carbon/backup/Dockerfile +75 -0
- package/carbon/backup/backup.sh +95 -0
- package/carbon/backup/compose-backup.sh +140 -0
- package/carbon/biome.json +83 -0
- package/carbon/cloud-init/docker-ce-setup.yaml +55 -0
- package/carbon/cloud-init/k3s/master-init.sh +215 -0
- package/carbon/cloud-init/k3s/supabase-init.sh +167 -0
- package/carbon/cloud-init/k3s/worker-init.sh +147 -0
- package/carbon/components.json +24 -0
- package/carbon/content/blog/authentication-guide.mdx +34 -0
- package/carbon/content/blog/getting-started.mdx +41 -0
- package/carbon/content/changelog/v0-1-0.mdx +40 -0
- package/carbon/content/docs/analytics.mdx +90 -0
- package/carbon/content/docs/authentication.mdx +231 -0
- package/carbon/content/docs/background-jobs.mdx +116 -0
- package/carbon/content/docs/cli.mdx +630 -0
- package/carbon/content/docs/database.mdx +236 -0
- package/carbon/content/docs/deployment.mdx +227 -0
- package/carbon/content/docs/development.mdx +238 -0
- package/carbon/content/docs/environments.mdx +84 -0
- package/carbon/content/docs/getting-started.mdx +112 -0
- package/carbon/content/docs/legal/privacy-policy.mdx +89 -0
- package/carbon/content/docs/legal/terms-of-service.mdx +99 -0
- package/carbon/content/docs/optional-services.mdx +160 -0
- package/carbon/db/Dockerfile +23 -0
- package/carbon/docker-compose.dev-init.yml +5 -0
- package/carbon/docker-compose.metabase.override.yml +14 -0
- package/carbon/docker-compose.metabase.prod.yml +28 -0
- package/carbon/docker-compose.metabase.yml +84 -0
- package/carbon/docker-compose.n8n.override.yml +14 -0
- package/carbon/docker-compose.n8n.prod.yml +31 -0
- package/carbon/docker-compose.n8n.yml +97 -0
- package/carbon/docker-compose.observability.override.yml +18 -0
- package/carbon/docker-compose.observability.prod.yml +28 -0
- package/carbon/docker-compose.observability.yml +125 -0
- package/carbon/docker-compose.override.yml +28 -0
- package/carbon/docker-compose.prod.yml +294 -0
- package/carbon/docker-compose.yml +508 -0
- package/carbon/docker-entrypoint.sh +12 -0
- package/carbon/ha/activate-standby.sh +52 -0
- package/carbon/ha/primary-init.sql +36 -0
- package/carbon/ha/standby-init.sh +74 -0
- package/carbon/k8s/LICENSE +99 -0
- package/carbon/k8s/README.md +272 -0
- package/carbon/k8s/base/app/deployment.yaml +130 -0
- package/carbon/k8s/base/app/hpa.yaml +44 -0
- package/carbon/k8s/base/app/kustomization.yaml +10 -0
- package/carbon/k8s/base/app/network-policy.yaml +124 -0
- package/carbon/k8s/base/app/pdb.yaml +14 -0
- package/carbon/k8s/base/app/rbac.yaml +36 -0
- package/carbon/k8s/base/app/service.yaml +16 -0
- package/carbon/k8s/base/backup/cronjob.yaml +120 -0
- package/carbon/k8s/base/backup/kustomization.yaml +7 -0
- package/carbon/k8s/base/backup/network-policy.yaml +31 -0
- package/carbon/k8s/base/backup/rbac.yaml +7 -0
- package/carbon/k8s/base/cluster-autoscaler/deployment.yaml +103 -0
- package/carbon/k8s/base/cluster-autoscaler/kustomization.yaml +17 -0
- package/carbon/k8s/base/cluster-autoscaler/rbac.yaml +109 -0
- package/carbon/k8s/base/config/configmap.yaml +48 -0
- package/carbon/k8s/base/config/kustomization.yaml +8 -0
- package/carbon/k8s/base/hetzner-ccm/kustomization.yaml +9 -0
- package/carbon/k8s/base/hetzner-csi/kustomization.yaml +9 -0
- package/carbon/k8s/base/kustomization.yaml +43 -0
- package/carbon/k8s/base/namespace.yaml +7 -0
- package/carbon/k8s/base/network-policies.yaml +95 -0
- package/carbon/k8s/base/registry/kustomization.yaml +5 -0
- package/carbon/k8s/base/registry/local-registry.yaml +193 -0
- package/carbon/k8s/base/traefik/certificate.yaml +21 -0
- package/carbon/k8s/base/traefik/configmap.yaml +13 -0
- package/carbon/k8s/base/traefik/deployment.yaml +165 -0
- package/carbon/k8s/base/traefik/ingressroute.yaml +141 -0
- package/carbon/k8s/base/traefik/kustomization.yaml +11 -0
- package/carbon/k8s/base/traefik/middleware.yaml +109 -0
- package/carbon/k8s/base/traefik/network-policy.yaml +92 -0
- package/carbon/k8s/base/traefik/service.yaml +38 -0
- package/carbon/k8s/flux/README.md +49 -0
- package/carbon/k8s/flux/clusters/primary/vibecarbon.yaml +128 -0
- package/carbon/k8s/flux/clusters/standby/vibecarbon.yaml +83 -0
- package/carbon/k8s/gitops/cert-manager-webhook-hetzner/helm-release.yaml +38 -0
- package/carbon/k8s/gitops/cert-manager-webhook-hetzner/helm-repository.yaml +16 -0
- package/carbon/k8s/gitops/cert-manager-webhook-hetzner/kustomization.yaml +10 -0
- package/carbon/k8s/gitops/supabase/helm-release.yaml +66 -0
- package/carbon/k8s/gitops/supabase/helm-repository.yaml +18 -0
- package/carbon/k8s/gitops/supabase/kustomization.yaml +33 -0
- package/carbon/k8s/infra/cert-manager-resources/cluster-issuers-cloudflare.yaml +51 -0
- package/carbon/k8s/infra/cert-manager-resources/cluster-issuers-hetzner.yaml +59 -0
- package/carbon/k8s/infra/cert-manager-resources/cluster-issuers-manual.yaml +43 -0
- package/carbon/k8s/infra/cert-manager-resources/kustomization.yaml +15 -0
- package/carbon/k8s/infra/kustomization.yaml +21 -0
- package/carbon/k8s/infra/traefik-crds/kustomization.yaml +10 -0
- package/carbon/k8s/overlays/local/configmap.yaml +23 -0
- package/carbon/k8s/overlays/local/ingressroute-studio.yaml +104 -0
- package/carbon/k8s/overlays/local/kustomization.yaml +215 -0
- package/carbon/k8s/overlays/local/namespace.yaml +8 -0
- package/carbon/k8s/overlays/local/secrets.yaml +32 -0
- package/carbon/k8s/overlays/production/kustomization.yaml +34 -0
- package/carbon/k8s/test-local.sh +318 -0
- package/carbon/k8s/values/supabase.values.yaml +133 -0
- package/carbon/package.json +154 -0
- package/carbon/runtime.Dockerfile +17 -0
- package/carbon/scripts/_dev-jwt.mjs +45 -0
- package/carbon/scripts/check-rls.ts +53 -0
- package/carbon/scripts/dev-init.js +191 -0
- package/carbon/scripts/dev.js +191 -0
- package/carbon/scripts/docker-down.js +63 -0
- package/carbon/scripts/docker-logs.js +59 -0
- package/carbon/scripts/docker-up.js +222 -0
- package/carbon/scripts/generate-dev-configs.sh +131 -0
- package/carbon/scripts/generate-rss.ts +116 -0
- package/carbon/scripts/generate-sitemap.ts +102 -0
- package/carbon/scripts/k8s-apply.js +71 -0
- package/carbon/scripts/k8s-delete.js +75 -0
- package/carbon/scripts/lib/manifest.js +176 -0
- package/carbon/scripts/secret-scan.mjs +278 -0
- package/carbon/scripts/validate-dev-configs.sh +101 -0
- package/carbon/src/client/App.tsx +202 -0
- package/carbon/src/client/assets/hyperformant-dark.svg +29 -0
- package/carbon/src/client/assets/hyperformant-light.svg +29 -0
- package/carbon/src/client/assets/logos/aider.svg +1 -0
- package/carbon/src/client/assets/logos/antigravity.svg +1 -0
- package/carbon/src/client/assets/logos/bolt.svg +1 -0
- package/carbon/src/client/assets/logos/claude-code.svg +1 -0
- package/carbon/src/client/assets/logos/copilot.svg +1 -0
- package/carbon/src/client/assets/logos/cursor.svg +1 -0
- package/carbon/src/client/assets/logos/gemini-cli.svg +1 -0
- package/carbon/src/client/assets/logos/lovable.svg +1 -0
- package/carbon/src/client/assets/logos/openai-codex.svg +1 -0
- package/carbon/src/client/assets/logos/v0.svg +1 -0
- package/carbon/src/client/assets/logos/windsurf.svg +1 -0
- package/carbon/src/client/assets/vibecarbon-icon.svg +19 -0
- package/carbon/src/client/assets/vibecarbon-logo-dark.svg +29 -0
- package/carbon/src/client/assets/vibecarbon-logo-light.svg +29 -0
- package/carbon/src/client/components/AIIntegrationSection.tsx +120 -0
- package/carbon/src/client/components/AppSidebar.tsx +760 -0
- package/carbon/src/client/components/ArchitectureSection.tsx +46 -0
- package/carbon/src/client/components/CTAFooter.tsx +59 -0
- package/carbon/src/client/components/ComparisonSection.tsx +132 -0
- package/carbon/src/client/components/ContentPanel.tsx +66 -0
- package/carbon/src/client/components/ContentSkeleton.tsx +21 -0
- package/carbon/src/client/components/ErrorBoundary.tsx +46 -0
- package/carbon/src/client/components/FAQSection.tsx +76 -0
- package/carbon/src/client/components/FileUpload.tsx +210 -0
- package/carbon/src/client/components/HeaderActions.tsx +17 -0
- package/carbon/src/client/components/Hero.tsx +608 -0
- package/carbon/src/client/components/ImpersonationBanner.tsx +31 -0
- package/carbon/src/client/components/LanguageSwitcher.tsx +67 -0
- package/carbon/src/client/components/Logo.tsx +87 -0
- package/carbon/src/client/components/LogoStrip.tsx +76 -0
- package/carbon/src/client/components/MetricsStrip.tsx +48 -0
- package/carbon/src/client/components/Nav.tsx +195 -0
- package/carbon/src/client/components/NewsletterSignup.tsx +147 -0
- package/carbon/src/client/components/NotificationDrawer.tsx +171 -0
- package/carbon/src/client/components/PageHeader.tsx +24 -0
- package/carbon/src/client/components/PlanGate.tsx +36 -0
- package/carbon/src/client/components/PricingSection.tsx +371 -0
- package/carbon/src/client/components/SEO.tsx +34 -0
- package/carbon/src/client/components/SmoothScroll.tsx +45 -0
- package/carbon/src/client/components/TechStackSection.tsx +165 -0
- package/carbon/src/client/components/WorkflowSection.tsx +604 -0
- package/carbon/src/client/components/admin/DockerLogs.tsx +276 -0
- package/carbon/src/client/components/admin/PerformanceMetrics.tsx +230 -0
- package/carbon/src/client/components/admin/ServiceCard.tsx +45 -0
- package/carbon/src/client/components/admin/ServicesStatus.tsx +296 -0
- package/carbon/src/client/components/architecture/ArchitectureDiagram.tsx +413 -0
- package/carbon/src/client/components/auth/AuthProvider.tsx +466 -0
- package/carbon/src/client/components/effects/FilmGrainOverlay.tsx +35 -0
- package/carbon/src/client/components/effects/FresnelEdge.tsx +49 -0
- package/carbon/src/client/components/effects/GlowTracker.tsx +46 -0
- package/carbon/src/client/components/effects/SparkBurst.tsx +145 -0
- package/carbon/src/client/components/effects/VGlowEffect.tsx +83 -0
- package/carbon/src/client/components/effects/index.ts +2 -0
- package/carbon/src/client/components/layouts/SidebarLayout.tsx +20 -0
- package/carbon/src/client/components/scroll/ScrollSection.tsx +76 -0
- package/carbon/src/client/components/scroll/ScrollytellingProvider.tsx +81 -0
- package/carbon/src/client/components/scroll/index.ts +2 -0
- package/carbon/src/client/components/ui/accordion.tsx +71 -0
- package/carbon/src/client/components/ui/alert-dialog.tsx +162 -0
- package/carbon/src/client/components/ui/alert.tsx +73 -0
- package/carbon/src/client/components/ui/aspect-ratio.tsx +22 -0
- package/carbon/src/client/components/ui/avatar.tsx +91 -0
- package/carbon/src/client/components/ui/badge.tsx +50 -0
- package/carbon/src/client/components/ui/breadcrumb.tsx +100 -0
- package/carbon/src/client/components/ui/button-group.tsx +78 -0
- package/carbon/src/client/components/ui/button.tsx +120 -0
- package/carbon/src/client/components/ui/calendar.tsx +182 -0
- package/carbon/src/client/components/ui/card.tsx +85 -0
- package/carbon/src/client/components/ui/carousel.tsx +227 -0
- package/carbon/src/client/components/ui/chart.tsx +357 -0
- package/carbon/src/client/components/ui/checkbox.tsx +27 -0
- package/carbon/src/client/components/ui/collapsible.tsx +15 -0
- package/carbon/src/client/components/ui/command.tsx +178 -0
- package/carbon/src/client/components/ui/context-menu.tsx +233 -0
- package/carbon/src/client/components/ui/dialog.tsx +132 -0
- package/carbon/src/client/components/ui/drawer.tsx +118 -0
- package/carbon/src/client/components/ui/dropdown-menu.tsx +242 -0
- package/carbon/src/client/components/ui/empty.tsx +94 -0
- package/carbon/src/client/components/ui/field.tsx +226 -0
- package/carbon/src/client/components/ui/hover-card.tsx +44 -0
- package/carbon/src/client/components/ui/input-group.tsx +146 -0
- package/carbon/src/client/components/ui/input-otp.tsx +83 -0
- package/carbon/src/client/components/ui/input.tsx +20 -0
- package/carbon/src/client/components/ui/item.tsx +188 -0
- package/carbon/src/client/components/ui/kbd.tsx +26 -0
- package/carbon/src/client/components/ui/label.tsx +21 -0
- package/carbon/src/client/components/ui/menubar.tsx +250 -0
- package/carbon/src/client/components/ui/navigation-menu.tsx +155 -0
- package/carbon/src/client/components/ui/pagination.tsx +102 -0
- package/carbon/src/client/components/ui/popover.tsx +75 -0
- package/carbon/src/client/components/ui/progress.tsx +66 -0
- package/carbon/src/client/components/ui/radio-group.tsx +36 -0
- package/carbon/src/client/components/ui/resizable.tsx +46 -0
- package/carbon/src/client/components/ui/scroll-area.tsx +48 -0
- package/carbon/src/client/components/ui/select.tsx +186 -0
- package/carbon/src/client/components/ui/separator.tsx +21 -0
- package/carbon/src/client/components/ui/sheet.tsx +124 -0
- package/carbon/src/client/components/ui/sidebar.tsx +702 -0
- package/carbon/src/client/components/ui/skeleton.tsx +13 -0
- package/carbon/src/client/components/ui/slider.tsx +57 -0
- package/carbon/src/client/components/ui/sonner.tsx +45 -0
- package/carbon/src/client/components/ui/spinner.tsx +15 -0
- package/carbon/src/client/components/ui/switch.tsx +30 -0
- package/carbon/src/client/components/ui/table.tsx +89 -0
- package/carbon/src/client/components/ui/tabs.tsx +73 -0
- package/carbon/src/client/components/ui/textarea.tsx +18 -0
- package/carbon/src/client/components/ui/toggle-group.tsx +87 -0
- package/carbon/src/client/components/ui/toggle.tsx +44 -0
- package/carbon/src/client/components/ui/tooltip.tsx +56 -0
- package/carbon/src/client/hooks/api/index.ts +14 -0
- package/carbon/src/client/hooks/api/useAuthSettings.ts +80 -0
- package/carbon/src/client/hooks/api/useSubscription.ts +87 -0
- package/carbon/src/client/hooks/use-mobile.ts +21 -0
- package/carbon/src/client/hooks/useMousePosition.ts +91 -0
- package/carbon/src/client/hooks/useNotifications.tsx +124 -0
- package/carbon/src/client/hooks/useOrganizationMembers.ts +127 -0
- package/carbon/src/client/hooks/useOrganizations.tsx +230 -0
- package/carbon/src/client/hooks/usePackageManager.ts +69 -0
- package/carbon/src/client/hooks/useReducedMotion.ts +20 -0
- package/carbon/src/client/hooks/useRunningServices.ts +114 -0
- package/carbon/src/client/hooks/useScrollProgress.ts +56 -0
- package/carbon/src/client/index.css +467 -0
- package/carbon/src/client/index.html +56 -0
- package/carbon/src/client/lib/admin-services.ts +151 -0
- package/carbon/src/client/lib/api.ts +32 -0
- package/carbon/src/client/lib/blog.ts +35 -0
- package/carbon/src/client/lib/changelog.ts +33 -0
- package/carbon/src/client/lib/docs-search.ts +101 -0
- package/carbon/src/client/lib/docs.ts +37 -0
- package/carbon/src/client/lib/i18n.ts +32 -0
- package/carbon/src/client/lib/supabase.ts +72 -0
- package/carbon/src/client/lib/tailwind-colors.ts +357 -0
- package/carbon/src/client/lib/theme.ts +117 -0
- package/carbon/src/client/lib/utils.ts +22 -0
- package/carbon/src/client/locales/de.json +529 -0
- package/carbon/src/client/locales/en.json +461 -0
- package/carbon/src/client/locales/es.json +529 -0
- package/carbon/src/client/locales/fr.json +529 -0
- package/carbon/src/client/locales/pt.json +529 -0
- package/carbon/src/client/main.tsx +56 -0
- package/carbon/src/client/mdx.d.ts +13 -0
- package/carbon/src/client/pages/ApiDocs.tsx +76 -0
- package/carbon/src/client/pages/AuthCallback.tsx +34 -0
- package/carbon/src/client/pages/Blog.tsx +167 -0
- package/carbon/src/client/pages/Changelog.tsx +171 -0
- package/carbon/src/client/pages/Charts.tsx +388 -0
- package/carbon/src/client/pages/Checkout.tsx +227 -0
- package/carbon/src/client/pages/Contact.tsx +174 -0
- package/carbon/src/client/pages/Dashboard.tsx +368 -0
- package/carbon/src/client/pages/Docs.tsx +372 -0
- package/carbon/src/client/pages/ForgotPassword.tsx +111 -0
- package/carbon/src/client/pages/Home.tsx +187 -0
- package/carbon/src/client/pages/Legal.tsx +100 -0
- package/carbon/src/client/pages/Login.tsx +408 -0
- package/carbon/src/client/pages/MFAVerify.tsx +156 -0
- package/carbon/src/client/pages/NotFound.tsx +21 -0
- package/carbon/src/client/pages/Onboarding.tsx +246 -0
- package/carbon/src/client/pages/ResetPassword.tsx +200 -0
- package/carbon/src/client/pages/UIComponents.tsx +390 -0
- package/carbon/src/client/pages/admin/ContactSubmissions.tsx +220 -0
- package/carbon/src/client/pages/admin/Dashboard.tsx +24 -0
- package/carbon/src/client/pages/admin/Infrastructure.tsx +257 -0
- package/carbon/src/client/pages/admin/Jobs.tsx +225 -0
- package/carbon/src/client/pages/admin/Logs.tsx +18 -0
- package/carbon/src/client/pages/admin/Newsletter.tsx +300 -0
- package/carbon/src/client/pages/admin/Notifications.tsx +603 -0
- package/carbon/src/client/pages/admin/Organizations.tsx +306 -0
- package/carbon/src/client/pages/admin/Settings.tsx +314 -0
- package/carbon/src/client/pages/admin/Theme.tsx +465 -0
- package/carbon/src/client/pages/admin/Users.tsx +365 -0
- package/carbon/src/client/pages/api-docs.css +156 -0
- package/carbon/src/client/pages/organizations/Details.tsx +200 -0
- package/carbon/src/client/pages/organizations/Members.tsx +402 -0
- package/carbon/src/client/pages/settings/Billing.tsx +473 -0
- package/carbon/src/client/pages/settings/Profile.tsx +160 -0
- package/carbon/src/client/pages/settings/Security.tsx +341 -0
- package/carbon/src/client/public/favicon.svg +19 -0
- package/carbon/src/client/public/robots.txt +8 -0
- package/carbon/src/server/billing/index.ts +104 -0
- package/carbon/src/server/billing/provider.ts +81 -0
- package/carbon/src/server/billing/providers/paddle.ts +314 -0
- package/carbon/src/server/billing/providers/polar.ts +325 -0
- package/carbon/src/server/billing/providers/stripe.ts +233 -0
- package/carbon/src/server/emails/templates.ts +116 -0
- package/carbon/src/server/index.ts +554 -0
- package/carbon/src/server/lib/auth.ts +6 -0
- package/carbon/src/server/lib/email.ts +64 -0
- package/carbon/src/server/lib/env.ts +112 -0
- package/carbon/src/server/lib/errors.ts +21 -0
- package/carbon/src/server/lib/logger.ts +17 -0
- package/carbon/src/server/lib/rate-limiter.ts +288 -0
- package/carbon/src/server/lib/request.ts +34 -0
- package/carbon/src/server/lib/stripe.ts +42 -0
- package/carbon/src/server/lib/supabase.ts +65 -0
- package/carbon/src/server/middleware/requirePlan.ts +80 -0
- package/carbon/src/server/routes/_internal/services-status.ts +958 -0
- package/carbon/src/server/routes/_internal/verify-role.ts +185 -0
- package/carbon/src/server/routes/health.ts +48 -0
- package/carbon/src/server/routes/v1/admin/contact.ts +128 -0
- package/carbon/src/server/routes/v1/admin/jobs.ts +171 -0
- package/carbon/src/server/routes/v1/admin/newsletter.ts +237 -0
- package/carbon/src/server/routes/v1/auth.ts +390 -0
- package/carbon/src/server/routes/v1/billing.ts +718 -0
- package/carbon/src/server/routes/v1/contact.ts +93 -0
- package/carbon/src/server/routes/v1/index.ts +1333 -0
- package/carbon/src/server/routes/v1/newsletter.ts +181 -0
- package/carbon/src/server/routes/v1/performance.ts +157 -0
- package/carbon/src/server/routes/v1/stats.ts +170 -0
- package/carbon/src/server/routes/v1/theme.ts +106 -0
- package/carbon/src/server/routes/webhooks/billing.ts +376 -0
- package/carbon/src/server/routes/webhooks/stripe.ts +276 -0
- package/carbon/src/server/types.ts +11 -0
- package/carbon/src/shared/pricing.ts +155 -0
- package/carbon/src/shared/types.ts +338 -0
- package/carbon/supabase/migrations/00001_init.sql +717 -0
- package/carbon/supabase/migrations/00002_theme_settings.sql +13 -0
- package/carbon/supabase/migrations/00003_pg_cron.sql +121 -0
- package/carbon/supabase/migrations/00004_contact_newsletter.sql +81 -0
- package/carbon/supabase/migrations/00005_localization_languages.sql +22 -0
- package/carbon/supabase/seed.sql +16 -0
- package/carbon/tests/_helpers/app.ts +45 -0
- package/carbon/tests/_helpers/env.ts +37 -0
- package/carbon/tests/_helpers/factories.ts +69 -0
- package/carbon/tests/_helpers/jwt.ts +23 -0
- package/carbon/tests/_helpers/setup-integration.ts +20 -0
- package/carbon/tests/_helpers/setup-rtl.ts +12 -0
- package/carbon/tests/component/ErrorBoundary.test.tsx +53 -0
- package/carbon/tests/component/use-auth-settings.test.tsx +119 -0
- package/carbon/tests/integration/server/routes/contact.test.ts +162 -0
- package/carbon/tests/integration/server/routes/health.test.ts +61 -0
- package/carbon/tests/structural/i18n-parity.test.ts +42 -0
- package/carbon/tests/unit/client/utils.test.ts +49 -0
- package/carbon/tests/unit/shared/pricing.test.ts +93 -0
- package/carbon/tsconfig.json +27 -0
- package/carbon/tsconfig.server.json +27 -0
- package/carbon/tsconfig.test.json +9 -0
- package/carbon/vite.config.ts +110 -0
- package/carbon/vitest.config.ts +74 -0
- package/carbon/volumes/db/jwt.sql +57 -0
- package/carbon/volumes/db/metabase-init.sh +29 -0
- package/carbon/volumes/db/n8n-init.sh +25 -0
- package/carbon/volumes/db/realtime.sql +33 -0
- package/carbon/volumes/db/roles.sql +93 -0
- package/carbon/volumes/db/set-passwords.sh +12 -0
- package/carbon/volumes/db/super-admin.dev.sql +113 -0
- package/carbon/volumes/db/super-admin.generated.sql +113 -0
- package/carbon/volumes/db/super-admin.sql +114 -0
- package/carbon/volumes/grafana/dashboards/logs.json +179 -0
- package/carbon/volumes/grafana/dashboards/overview.json +523 -0
- package/carbon/volumes/grafana/dashboards/postgresql.json +337 -0
- package/carbon/volumes/grafana/dashboards.dev/logs.json +179 -0
- package/carbon/volumes/grafana/dashboards.dev/overview.json +156 -0
- package/carbon/volumes/grafana/dashboards.dev/postgresql.json +337 -0
- package/carbon/volumes/grafana/provisioning/dashboards/dashboards.dev.yml +16 -0
- package/carbon/volumes/grafana/provisioning/dashboards/dashboards.yml +16 -0
- package/carbon/volumes/grafana/provisioning/datasources/datasources.yml +43 -0
- package/carbon/volumes/kong/docker-entrypoint.sh +9 -0
- package/carbon/volumes/kong/kong.yml +208 -0
- package/carbon/volumes/loki/loki-config.yml +58 -0
- package/carbon/volumes/n8n/hooks.js +131 -0
- package/carbon/volumes/n8n/scripts/setup.sh +66 -0
- package/carbon/volumes/prometheus/prometheus.yml +43 -0
- package/carbon/volumes/promtail/promtail-config.yml +64 -0
- package/carbon/volumes/traefik/middlewares.dev.yml +83 -0
- package/carbon/volumes/traefik/middlewares.yml +95 -0
- package/carbon/volumes/traefik/vite-dev.yml +20 -0
- package/package.json +95 -0
- package/src/access.js +354 -0
- package/src/activate.js +187 -0
- package/src/add.js +718 -0
- package/src/backup.js +786 -0
- package/src/cli.js +350 -0
- package/src/configure.js +967 -0
- package/src/console.js +155 -0
- package/src/create.js +1499 -0
- package/src/deploy.js +311 -0
- package/src/destroy.js +2033 -0
- package/src/diagnose.js +735 -0
- package/src/down.js +80 -0
- package/src/failover.js +1032 -0
- package/src/lib/backup-s3.js +179 -0
- package/src/lib/build.js +33 -0
- package/src/lib/checksum.js +28 -0
- package/src/lib/ci-setup.js +666 -0
- package/src/lib/cli/help.js +129 -0
- package/src/lib/cli/parse-flags.js +160 -0
- package/src/lib/cli/select-action.js +65 -0
- package/src/lib/cli/select-environment.js +108 -0
- package/src/lib/cli/tty-guard.js +75 -0
- package/src/lib/cloudflare.js +447 -0
- package/src/lib/colors.js +52 -0
- package/src/lib/command.js +361 -0
- package/src/lib/config.js +359 -0
- package/src/lib/cost.js +103 -0
- package/src/lib/deploy/bundle.js +231 -0
- package/src/lib/deploy/compose/acme-verify.js +121 -0
- package/src/lib/deploy/compose/build-args.js +78 -0
- package/src/lib/deploy/compose/ha.js +1874 -0
- package/src/lib/deploy/compose/index.js +1294 -0
- package/src/lib/deploy/compose/reconcile.js +74 -0
- package/src/lib/deploy/github.js +382 -0
- package/src/lib/deploy/image.js +191 -0
- package/src/lib/deploy/index.js +119 -0
- package/src/lib/deploy/k8s/LICENSE +99 -0
- package/src/lib/deploy/k8s/gitops-deploy.js +298 -0
- package/src/lib/deploy/k8s/ha/index.js +1000 -0
- package/src/lib/deploy/k8s/index.js +62 -0
- package/src/lib/deploy/k8s/k3s.js +2515 -0
- package/src/lib/deploy/orchestrator.js +1401 -0
- package/src/lib/deploy/prompts.js +545 -0
- package/src/lib/deploy/remote-build.js +130 -0
- package/src/lib/deploy/state.js +120 -0
- package/src/lib/deploy/utils.js +328 -0
- package/src/lib/deploy-logger.js +93 -0
- package/src/lib/dns-propagation.js +48 -0
- package/src/lib/environment.js +58 -0
- package/src/lib/fetch-retry.js +103 -0
- package/src/lib/github-environments.js +335 -0
- package/src/lib/hetzner-dns.js +377 -0
- package/src/lib/hetzner-guided-setup.js +275 -0
- package/src/lib/host-keys.js +37 -0
- package/src/lib/iac/cloud-init.js +52 -0
- package/src/lib/iac/index.js +325 -0
- package/src/lib/iac/programs/hetzner-compose.js +130 -0
- package/src/lib/iac/programs/hetzner-k8s.js +320 -0
- package/src/lib/kubectl.js +81 -0
- package/src/lib/licensing/index.js +259 -0
- package/src/lib/licensing/tiers.js +181 -0
- package/src/lib/licensing/validator.js +171 -0
- package/src/lib/merge-package-json.js +90 -0
- package/src/lib/operator-ip.js +381 -0
- package/src/lib/package-manager.js +111 -0
- package/src/lib/perf.js +71 -0
- package/src/lib/project-guard.js +39 -0
- package/src/lib/project.js +334 -0
- package/src/lib/providers/base.js +276 -0
- package/src/lib/providers/hetzner-s3.js +656 -0
- package/src/lib/providers/hetzner.js +755 -0
- package/src/lib/providers/index.js +164 -0
- package/src/lib/s3.js +510 -0
- package/src/lib/secret-scan.js +583 -0
- package/src/lib/secrets.js +63 -0
- package/src/lib/server-types.js +195 -0
- package/src/lib/shell.js +91 -0
- package/src/lib/ssh.js +241 -0
- package/src/lib/tracker.js +242 -0
- package/src/lib/upgrade-policy.js +170 -0
- package/src/lib/validators.js +105 -0
- package/src/lib/version.js +5 -0
- package/src/remove.js +292 -0
- package/src/reset.js +97 -0
- package/src/restore.js +871 -0
- package/src/scale.js +1734 -0
- package/src/shell.js +222 -0
- package/src/status.js +981 -0
- package/src/up.js +264 -0
- package/src/upgrade.js +721 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
apiVersion: v1
|
|
2
|
+
kind: ServiceAccount
|
|
3
|
+
metadata:
|
|
4
|
+
name: vibecarbon-app
|
|
5
|
+
# Pull secrets are attached to the `default` SA by deploy.js at runtime
|
|
6
|
+
# (dockerhub-pull-secret for Supabase images, ghcr-pull-secret for the app
|
|
7
|
+
# image). This app SA inherits the same set so the app Deployment — which
|
|
8
|
+
# uses serviceAccountName: vibecarbon-app — can pull the private ghcr image.
|
|
9
|
+
imagePullSecrets:
|
|
10
|
+
- name: dockerhub-pull-secret
|
|
11
|
+
- name: ghcr-pull-secret
|
|
12
|
+
---
|
|
13
|
+
apiVersion: rbac.authorization.k8s.io/v1
|
|
14
|
+
kind: Role
|
|
15
|
+
metadata:
|
|
16
|
+
name: vibecarbon-app-logs
|
|
17
|
+
rules:
|
|
18
|
+
- apiGroups: [""]
|
|
19
|
+
resources: ["pods"]
|
|
20
|
+
verbs: ["list", "get"]
|
|
21
|
+
- apiGroups: [""]
|
|
22
|
+
resources: ["pods/log"]
|
|
23
|
+
verbs: ["get"]
|
|
24
|
+
---
|
|
25
|
+
apiVersion: rbac.authorization.k8s.io/v1
|
|
26
|
+
kind: RoleBinding
|
|
27
|
+
metadata:
|
|
28
|
+
name: vibecarbon-app-logs
|
|
29
|
+
roleRef:
|
|
30
|
+
apiGroup: rbac.authorization.k8s.io
|
|
31
|
+
kind: Role
|
|
32
|
+
name: vibecarbon-app-logs
|
|
33
|
+
subjects:
|
|
34
|
+
- kind: ServiceAccount
|
|
35
|
+
name: vibecarbon-app
|
|
36
|
+
namespace: vibecarbon
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
apiVersion: v1
|
|
2
|
+
kind: Service
|
|
3
|
+
metadata:
|
|
4
|
+
name: app
|
|
5
|
+
labels:
|
|
6
|
+
app: vibecarbon-app
|
|
7
|
+
component: application
|
|
8
|
+
spec:
|
|
9
|
+
type: ClusterIP
|
|
10
|
+
ports:
|
|
11
|
+
- port: 3000
|
|
12
|
+
targetPort: http
|
|
13
|
+
protocol: TCP
|
|
14
|
+
name: http
|
|
15
|
+
selector:
|
|
16
|
+
app: vibecarbon-app
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
apiVersion: batch/v1
|
|
2
|
+
kind: CronJob
|
|
3
|
+
metadata:
|
|
4
|
+
name: backup
|
|
5
|
+
labels:
|
|
6
|
+
app: vibecarbon-backup
|
|
7
|
+
component: backup
|
|
8
|
+
spec:
|
|
9
|
+
schedule: 0 2 * * *
|
|
10
|
+
concurrencyPolicy: Forbid
|
|
11
|
+
successfulJobsHistoryLimit: 3
|
|
12
|
+
failedJobsHistoryLimit: 3
|
|
13
|
+
jobTemplate:
|
|
14
|
+
spec:
|
|
15
|
+
activeDeadlineSeconds: 3600
|
|
16
|
+
backoffLimit: 2
|
|
17
|
+
template:
|
|
18
|
+
metadata:
|
|
19
|
+
labels:
|
|
20
|
+
app: vibecarbon-backup
|
|
21
|
+
component: backup
|
|
22
|
+
spec:
|
|
23
|
+
restartPolicy: OnFailure
|
|
24
|
+
serviceAccountName: backup-sa
|
|
25
|
+
containers:
|
|
26
|
+
- name: backup
|
|
27
|
+
image: ghcr.io/{{GITHUB_OWNER}}/{{PROJECT_NAME}}-backup:latest
|
|
28
|
+
imagePullPolicy: Always
|
|
29
|
+
env:
|
|
30
|
+
- name: PGHOST
|
|
31
|
+
valueFrom:
|
|
32
|
+
configMapKeyRef:
|
|
33
|
+
name: vibecarbon-config
|
|
34
|
+
key: DB_HOST
|
|
35
|
+
- name: PGPORT
|
|
36
|
+
valueFrom:
|
|
37
|
+
configMapKeyRef:
|
|
38
|
+
name: vibecarbon-config
|
|
39
|
+
key: DB_PORT
|
|
40
|
+
- name: PGUSER
|
|
41
|
+
value: supabase_admin
|
|
42
|
+
- name: PGDATABASE
|
|
43
|
+
valueFrom:
|
|
44
|
+
configMapKeyRef:
|
|
45
|
+
name: vibecarbon-config
|
|
46
|
+
key: DB_NAME
|
|
47
|
+
- name: PGPASSWORD
|
|
48
|
+
valueFrom:
|
|
49
|
+
secretKeyRef:
|
|
50
|
+
name: vibecarbon-secrets
|
|
51
|
+
key: DB_PASSWORD
|
|
52
|
+
- name: S3_ACCESS_KEY
|
|
53
|
+
valueFrom:
|
|
54
|
+
secretKeyRef:
|
|
55
|
+
name: vibecarbon-secrets
|
|
56
|
+
key: S3_ACCESS_KEY
|
|
57
|
+
optional: true
|
|
58
|
+
- name: S3_SECRET_KEY
|
|
59
|
+
valueFrom:
|
|
60
|
+
secretKeyRef:
|
|
61
|
+
name: vibecarbon-secrets
|
|
62
|
+
key: S3_SECRET_KEY
|
|
63
|
+
optional: true
|
|
64
|
+
- name: S3_BUCKET
|
|
65
|
+
valueFrom:
|
|
66
|
+
secretKeyRef:
|
|
67
|
+
name: vibecarbon-secrets
|
|
68
|
+
key: S3_BUCKET
|
|
69
|
+
optional: true
|
|
70
|
+
- name: S3_ENDPOINT
|
|
71
|
+
valueFrom:
|
|
72
|
+
secretKeyRef:
|
|
73
|
+
name: vibecarbon-secrets
|
|
74
|
+
key: S3_ENDPOINT
|
|
75
|
+
optional: true
|
|
76
|
+
- name: S3_REGION
|
|
77
|
+
valueFrom:
|
|
78
|
+
secretKeyRef:
|
|
79
|
+
name: vibecarbon-secrets
|
|
80
|
+
key: S3_REGION
|
|
81
|
+
optional: true
|
|
82
|
+
- name: S3_BACKUP_BUCKET
|
|
83
|
+
valueFrom:
|
|
84
|
+
secretKeyRef:
|
|
85
|
+
name: vibecarbon-secrets
|
|
86
|
+
key: S3_BACKUP_BUCKET
|
|
87
|
+
optional: true
|
|
88
|
+
- name: BACKUP_RETENTION_DAYS
|
|
89
|
+
valueFrom:
|
|
90
|
+
configMapKeyRef:
|
|
91
|
+
name: vibecarbon-config
|
|
92
|
+
key: BACKUP_RETENTION_DAYS
|
|
93
|
+
optional: true
|
|
94
|
+
- name: STORAGE_BACKEND
|
|
95
|
+
value: file
|
|
96
|
+
# Use pg_dump (network protocol) instead of WAL-G in this
|
|
97
|
+
# CronJob — WAL-G's backup-push needs direct filesystem access
|
|
98
|
+
# to PGDATA, which only the supabase-db pod has. The backup
|
|
99
|
+
# pod runs separately and connects via PGHOST, so it has to
|
|
100
|
+
# use the libpq-based pg_dump path. Switching WAL-G on for
|
|
101
|
+
# k8s would require a sidecar inside supabase-db.
|
|
102
|
+
- name: BACKUP_MODE
|
|
103
|
+
value: pg_dump
|
|
104
|
+
- name: PROJECT_NAME
|
|
105
|
+
valueFrom:
|
|
106
|
+
configMapKeyRef:
|
|
107
|
+
name: vibecarbon-config
|
|
108
|
+
key: PROJECT_NAME
|
|
109
|
+
resources:
|
|
110
|
+
requests:
|
|
111
|
+
cpu: 100m
|
|
112
|
+
memory: 256Mi
|
|
113
|
+
limits:
|
|
114
|
+
cpu: 500m
|
|
115
|
+
memory: 512Mi
|
|
116
|
+
securityContext:
|
|
117
|
+
allowPrivilegeEscalation: false
|
|
118
|
+
securityContext:
|
|
119
|
+
seccompProfile:
|
|
120
|
+
type: RuntimeDefault
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
apiVersion: networking.k8s.io/v1
|
|
2
|
+
kind: NetworkPolicy
|
|
3
|
+
metadata:
|
|
4
|
+
name: backup-policy
|
|
5
|
+
namespace: vibecarbon
|
|
6
|
+
spec:
|
|
7
|
+
podSelector:
|
|
8
|
+
matchLabels:
|
|
9
|
+
app: vibecarbon-backup
|
|
10
|
+
policyTypes:
|
|
11
|
+
- Egress
|
|
12
|
+
egress:
|
|
13
|
+
# Connect to PostgreSQL for pg_dump
|
|
14
|
+
- to:
|
|
15
|
+
- podSelector:
|
|
16
|
+
matchLabels:
|
|
17
|
+
app: vibecarbon-postgres
|
|
18
|
+
ports:
|
|
19
|
+
- protocol: TCP
|
|
20
|
+
port: 5432
|
|
21
|
+
# Upload to S3 (external HTTPS)
|
|
22
|
+
- to:
|
|
23
|
+
- ipBlock:
|
|
24
|
+
cidr: 0.0.0.0/0
|
|
25
|
+
except:
|
|
26
|
+
- 10.0.0.0/8
|
|
27
|
+
- 172.16.0.0/12
|
|
28
|
+
- 192.168.0.0/16
|
|
29
|
+
ports:
|
|
30
|
+
- protocol: TCP
|
|
31
|
+
port: 443
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
apiVersion: apps/v1
|
|
2
|
+
kind: Deployment
|
|
3
|
+
metadata:
|
|
4
|
+
name: cluster-autoscaler
|
|
5
|
+
namespace: kube-system
|
|
6
|
+
labels:
|
|
7
|
+
app: cluster-autoscaler
|
|
8
|
+
spec:
|
|
9
|
+
replicas: 1
|
|
10
|
+
strategy:
|
|
11
|
+
type: Recreate
|
|
12
|
+
selector:
|
|
13
|
+
matchLabels:
|
|
14
|
+
app: cluster-autoscaler
|
|
15
|
+
template:
|
|
16
|
+
metadata:
|
|
17
|
+
labels:
|
|
18
|
+
app: cluster-autoscaler
|
|
19
|
+
spec:
|
|
20
|
+
serviceAccountName: cluster-autoscaler
|
|
21
|
+
priorityClassName: system-cluster-critical
|
|
22
|
+
hostNetwork: true
|
|
23
|
+
dnsPolicy: ClusterFirstWithHostNet
|
|
24
|
+
tolerations:
|
|
25
|
+
- key: node-role.kubernetes.io/control-plane
|
|
26
|
+
operator: Exists
|
|
27
|
+
effect: NoSchedule
|
|
28
|
+
nodeSelector:
|
|
29
|
+
node-role.kubernetes.io/control-plane: "true"
|
|
30
|
+
securityContext:
|
|
31
|
+
seccompProfile:
|
|
32
|
+
type: RuntimeDefault
|
|
33
|
+
containers:
|
|
34
|
+
- name: cluster-autoscaler
|
|
35
|
+
image: registry.k8s.io/autoscaling/cluster-autoscaler:v1.32.7
|
|
36
|
+
imagePullPolicy: IfNotPresent
|
|
37
|
+
securityContext:
|
|
38
|
+
runAsNonRoot: true
|
|
39
|
+
allowPrivilegeEscalation: false
|
|
40
|
+
readOnlyRootFilesystem: true
|
|
41
|
+
capabilities:
|
|
42
|
+
drop:
|
|
43
|
+
- ALL
|
|
44
|
+
command:
|
|
45
|
+
- ./cluster-autoscaler
|
|
46
|
+
args:
|
|
47
|
+
- --cloud-provider=hetzner
|
|
48
|
+
- --nodes={{CA_NODES_SPEC}}
|
|
49
|
+
- --scale-down-delay-after-add=10m
|
|
50
|
+
- --scale-down-delay-after-delete=1m
|
|
51
|
+
- --scale-down-delay-after-failure=3m
|
|
52
|
+
- --scale-down-unneeded-time=10m
|
|
53
|
+
- --scale-down-utilization-threshold=0.5
|
|
54
|
+
- --skip-nodes-with-local-storage=false
|
|
55
|
+
- --skip-nodes-with-system-pods=false
|
|
56
|
+
- --balance-similar-node-groups=true
|
|
57
|
+
- --expander=least-waste
|
|
58
|
+
- --v=4
|
|
59
|
+
env:
|
|
60
|
+
- name: HCLOUD_TOKEN
|
|
61
|
+
valueFrom:
|
|
62
|
+
secretKeyRef:
|
|
63
|
+
name: hcloud-cluster-config
|
|
64
|
+
key: token
|
|
65
|
+
- name: HCLOUD_NETWORK
|
|
66
|
+
value: '{{CLUSTER_NAME}}-network'
|
|
67
|
+
- name: HCLOUD_FIREWALL
|
|
68
|
+
value: '{{CLUSTER_NAME}}-firewall'
|
|
69
|
+
- name: HCLOUD_SSH_KEY
|
|
70
|
+
value: '{{CLUSTER_NAME}}-{{REGION}}-key'
|
|
71
|
+
# cluster-autoscaler v1.32.x reads the config inline from
|
|
72
|
+
# HCLOUD_CLUSTER_CONFIG, not HCLOUD_CLUSTER_CONFIG_FILE — the
|
|
73
|
+
# _FILE variant landed on master post-1.33 and is not in 1.32.7.
|
|
74
|
+
# Sourcing from the Secret data.cluster-config.json gives us the
|
|
75
|
+
# decoded JSON payload as the env value (same Secret keeps both
|
|
76
|
+
# the token and the cluster-config under separate keys).
|
|
77
|
+
# Surfaced k8s e2e fanout5 2026-05-01: autoscaler crashed
|
|
78
|
+
# on every restart with "HCLOUD_CLUSTER_CONFIG or HCLOUD_CLOUD_INIT
|
|
79
|
+
# is not specified" despite _FILE pointing at a real path.
|
|
80
|
+
- name: HCLOUD_CLUSTER_CONFIG
|
|
81
|
+
valueFrom:
|
|
82
|
+
secretKeyRef:
|
|
83
|
+
name: hcloud-cluster-config
|
|
84
|
+
key: cluster-config.json
|
|
85
|
+
resources:
|
|
86
|
+
requests:
|
|
87
|
+
cpu: 100m
|
|
88
|
+
memory: 128Mi
|
|
89
|
+
limits:
|
|
90
|
+
cpu: 500m
|
|
91
|
+
memory: 384Mi
|
|
92
|
+
volumeMounts:
|
|
93
|
+
- name: ssl-certs
|
|
94
|
+
mountPath: /etc/ssl/certs/ca-certificates.crt
|
|
95
|
+
readOnly: true
|
|
96
|
+
- name: tmp-vol-0
|
|
97
|
+
mountPath: /tmp
|
|
98
|
+
volumes:
|
|
99
|
+
- name: ssl-certs
|
|
100
|
+
hostPath:
|
|
101
|
+
path: /etc/ssl/certs/ca-certificates.crt
|
|
102
|
+
- name: tmp-vol-0
|
|
103
|
+
emptyDir: {}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
apiVersion: kustomize.config.k8s.io/v1beta1
|
|
2
|
+
kind: Kustomization
|
|
3
|
+
|
|
4
|
+
# Cluster-autoscaler must live in `kube-system`. The parent
|
|
5
|
+
# `carbon/k8s/base/kustomization.yaml` sets `namespace: vibecarbon`,
|
|
6
|
+
# whose namespace transformer overrides every namespaced resource
|
|
7
|
+
# below it — including ours. Phase 5 (`applyK3sManifests`) therefore
|
|
8
|
+
# applies this kustomization standalone via
|
|
9
|
+
# `kubectl apply -k carbon/k8s/base/cluster-autoscaler/` so the
|
|
10
|
+
# `namespace: kube-system` directive below takes effect, mirroring
|
|
11
|
+
# the CCM/CSI pattern (those are listed in `base/kustomization.yaml`
|
|
12
|
+
# only as comments and applied separately from cloud-init).
|
|
13
|
+
namespace: kube-system
|
|
14
|
+
|
|
15
|
+
resources:
|
|
16
|
+
- deployment.yaml
|
|
17
|
+
- rbac.yaml
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
apiVersion: v1
|
|
2
|
+
kind: ServiceAccount
|
|
3
|
+
metadata:
|
|
4
|
+
name: cluster-autoscaler
|
|
5
|
+
namespace: kube-system
|
|
6
|
+
labels:
|
|
7
|
+
app: cluster-autoscaler
|
|
8
|
+
---
|
|
9
|
+
apiVersion: rbac.authorization.k8s.io/v1
|
|
10
|
+
kind: ClusterRole
|
|
11
|
+
metadata:
|
|
12
|
+
name: cluster-autoscaler
|
|
13
|
+
labels:
|
|
14
|
+
app: cluster-autoscaler
|
|
15
|
+
rules:
|
|
16
|
+
- apiGroups: [""]
|
|
17
|
+
resources: ["events", "endpoints"]
|
|
18
|
+
verbs: ["create", "patch"]
|
|
19
|
+
- apiGroups: [""]
|
|
20
|
+
resources: ["pods/eviction"]
|
|
21
|
+
verbs: ["create"]
|
|
22
|
+
- apiGroups: [""]
|
|
23
|
+
resources: ["pods/status"]
|
|
24
|
+
verbs: ["update"]
|
|
25
|
+
- apiGroups: [""]
|
|
26
|
+
resources: ["endpoints"]
|
|
27
|
+
resourceNames: ["cluster-autoscaler"]
|
|
28
|
+
verbs: ["get", "update"]
|
|
29
|
+
- apiGroups: [""]
|
|
30
|
+
resources: ["nodes"]
|
|
31
|
+
verbs: ["watch", "list", "get", "update"]
|
|
32
|
+
- apiGroups: [""]
|
|
33
|
+
resources: ["namespaces", "pods", "services", "replicationcontrollers", "persistentvolumeclaims", "persistentvolumes"]
|
|
34
|
+
verbs: ["watch", "list", "get"]
|
|
35
|
+
- apiGroups: ["batch"]
|
|
36
|
+
resources: ["jobs", "cronjobs"]
|
|
37
|
+
verbs: ["watch", "list", "get"]
|
|
38
|
+
- apiGroups: ["batch", "extensions"]
|
|
39
|
+
resources: ["jobs"]
|
|
40
|
+
verbs: ["get", "list", "patch", "watch"]
|
|
41
|
+
- apiGroups: ["extensions"]
|
|
42
|
+
resources: ["replicasets", "daemonsets"]
|
|
43
|
+
verbs: ["watch", "list", "get"]
|
|
44
|
+
- apiGroups: ["policy"]
|
|
45
|
+
resources: ["poddisruptionbudgets"]
|
|
46
|
+
verbs: ["watch", "list"]
|
|
47
|
+
- apiGroups: ["apps"]
|
|
48
|
+
resources: ["daemonsets", "replicasets", "statefulsets"]
|
|
49
|
+
verbs: ["watch", "list", "get"]
|
|
50
|
+
- apiGroups: ["storage.k8s.io"]
|
|
51
|
+
resources: ["storageclasses", "csinodes", "csidrivers", "csistoragecapacities"]
|
|
52
|
+
verbs: ["watch", "list", "get"]
|
|
53
|
+
- apiGroups: [""]
|
|
54
|
+
resources: ["configmaps"]
|
|
55
|
+
verbs: ["list", "watch"]
|
|
56
|
+
- apiGroups: ["coordination.k8s.io"]
|
|
57
|
+
resources: ["leases"]
|
|
58
|
+
verbs: ["create"]
|
|
59
|
+
- apiGroups: ["coordination.k8s.io"]
|
|
60
|
+
resourceNames: ["cluster-autoscaler"]
|
|
61
|
+
resources: ["leases"]
|
|
62
|
+
verbs: ["get", "update"]
|
|
63
|
+
---
|
|
64
|
+
apiVersion: rbac.authorization.k8s.io/v1
|
|
65
|
+
kind: ClusterRoleBinding
|
|
66
|
+
metadata:
|
|
67
|
+
name: cluster-autoscaler
|
|
68
|
+
labels:
|
|
69
|
+
app: cluster-autoscaler
|
|
70
|
+
roleRef:
|
|
71
|
+
apiGroup: rbac.authorization.k8s.io
|
|
72
|
+
kind: ClusterRole
|
|
73
|
+
name: cluster-autoscaler
|
|
74
|
+
subjects:
|
|
75
|
+
- kind: ServiceAccount
|
|
76
|
+
name: cluster-autoscaler
|
|
77
|
+
namespace: kube-system
|
|
78
|
+
---
|
|
79
|
+
apiVersion: rbac.authorization.k8s.io/v1
|
|
80
|
+
kind: Role
|
|
81
|
+
metadata:
|
|
82
|
+
name: cluster-autoscaler
|
|
83
|
+
namespace: kube-system
|
|
84
|
+
labels:
|
|
85
|
+
app: cluster-autoscaler
|
|
86
|
+
rules:
|
|
87
|
+
- apiGroups: [""]
|
|
88
|
+
resources: ["configmaps"]
|
|
89
|
+
verbs: ["create", "list", "watch"]
|
|
90
|
+
- apiGroups: [""]
|
|
91
|
+
resources: ["configmaps"]
|
|
92
|
+
resourceNames: ["cluster-autoscaler-status", "cluster-autoscaler-priority-expander"]
|
|
93
|
+
verbs: ["delete", "get", "update", "watch"]
|
|
94
|
+
---
|
|
95
|
+
apiVersion: rbac.authorization.k8s.io/v1
|
|
96
|
+
kind: RoleBinding
|
|
97
|
+
metadata:
|
|
98
|
+
name: cluster-autoscaler
|
|
99
|
+
namespace: kube-system
|
|
100
|
+
labels:
|
|
101
|
+
app: cluster-autoscaler
|
|
102
|
+
roleRef:
|
|
103
|
+
apiGroup: rbac.authorization.k8s.io
|
|
104
|
+
kind: Role
|
|
105
|
+
name: cluster-autoscaler
|
|
106
|
+
subjects:
|
|
107
|
+
- kind: ServiceAccount
|
|
108
|
+
name: cluster-autoscaler
|
|
109
|
+
namespace: kube-system
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Non-secret runtime configuration consumed by Supabase + app containers.
|
|
2
|
+
# Committed to git; safe to reconcile via Flux.
|
|
3
|
+
#
|
|
4
|
+
# The vibecarbon-secrets Secret that used to live next to this file is
|
|
5
|
+
# now created at deploy time — either by the vibecarbon CLI (imperative
|
|
6
|
+
# deploy) or by the GitHub Actions deploy workflow
|
|
7
|
+
# (.github/workflows/deploy.yml, GitOps deploy). That Secret is NOT
|
|
8
|
+
# reconciled by Flux — it's owned by field-manager=github-actions-deploy
|
|
9
|
+
# (workflow) or field-manager=kubectl-client-side-apply (CLI), and Flux
|
|
10
|
+
# leaves it alone. This lets us rotate secrets via `gh secret set --env
|
|
11
|
+
# prod KEY=value` without a git commit.
|
|
12
|
+
---
|
|
13
|
+
apiVersion: v1
|
|
14
|
+
kind: ConfigMap
|
|
15
|
+
metadata:
|
|
16
|
+
name: vibecarbon-config
|
|
17
|
+
data:
|
|
18
|
+
# Site Configuration — SITE_URL is patched in by deploy code once the
|
|
19
|
+
# real domain is known (before-domain-known default is the placeholder
|
|
20
|
+
# below; deploy patches to https://<domain> via kubectlPatch).
|
|
21
|
+
SITE_URL: "https://app.example.com"
|
|
22
|
+
PROJECT_NAME: "vibecarbon"
|
|
23
|
+
|
|
24
|
+
# Database (in-cluster service names). The Supabase community Helm chart
|
|
25
|
+
# gives every component a `supabase-supabase-<name>` service via its
|
|
26
|
+
# release-name + chart-name pattern — `db` lives at supabase-supabase-db.
|
|
27
|
+
# Consumed by app/deployment.yaml + backup/cronjob.yaml; the chart's
|
|
28
|
+
# subcharts have their own internal wiring and do NOT read this map.
|
|
29
|
+
# Plain "postgres" silently falls back to no-such-host: backup pods print
|
|
30
|
+
# "could not translate host name 'postgres'" and pg_dump exits 1 (observed
|
|
31
|
+
# 2026-04-27 k8s-ha matrix #6).
|
|
32
|
+
DB_HOST: "supabase-supabase-db"
|
|
33
|
+
DB_PORT: "5432"
|
|
34
|
+
DB_NAME: "postgres"
|
|
35
|
+
|
|
36
|
+
# Internal Service URLs. Supabase community chart gives each subchart a
|
|
37
|
+
# fullnameOverride of `supabase-supabase-<name>`, so these are the ACTUAL
|
|
38
|
+
# in-cluster service names as of supabase-community chart v0.5.5.
|
|
39
|
+
KONG_URL: "http://supabase-supabase-kong:8000"
|
|
40
|
+
AUTH_URL: "http://supabase-supabase-auth:9999"
|
|
41
|
+
REST_URL: "http://supabase-supabase-rest:3000"
|
|
42
|
+
REALTIME_URL: "http://supabase-supabase-realtime:4000"
|
|
43
|
+
STORAGE_URL: "http://supabase-supabase-storage:5000"
|
|
44
|
+
META_URL: "http://supabase-supabase-meta:8080"
|
|
45
|
+
IMGPROXY_URL: "http://supabase-supabase-imgproxy:5001"
|
|
46
|
+
|
|
47
|
+
# Backup Configuration
|
|
48
|
+
BACKUP_RETENTION_DAYS: "7"
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
apiVersion: kustomize.config.k8s.io/v1beta1
|
|
2
|
+
kind: Kustomization
|
|
3
|
+
|
|
4
|
+
# Hetzner Cloud Controller Manager
|
|
5
|
+
# This enables automatic Load Balancer provisioning and node lifecycle management
|
|
6
|
+
# Official repo: https://github.com/hetznercloud/hcloud-cloud-controller-manager
|
|
7
|
+
|
|
8
|
+
resources:
|
|
9
|
+
- https://github.com/hetznercloud/hcloud-cloud-controller-manager/releases/download/v1.20.0/ccm-networks.yaml
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
apiVersion: kustomize.config.k8s.io/v1beta1
|
|
2
|
+
kind: Kustomization
|
|
3
|
+
|
|
4
|
+
# Hetzner CSI Driver
|
|
5
|
+
# This enables automatic Hetzner Volume provisioning for PersistentVolumeClaims
|
|
6
|
+
# Official repo: https://github.com/hetznercloud/csi-driver
|
|
7
|
+
|
|
8
|
+
resources:
|
|
9
|
+
- https://raw.githubusercontent.com/hetznercloud/csi-driver/v2.9.0/deploy/kubernetes/hcloud-csi.yml
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
apiVersion: kustomize.config.k8s.io/v1beta1
|
|
2
|
+
kind: Kustomization
|
|
3
|
+
|
|
4
|
+
namespace: vibecarbon
|
|
5
|
+
|
|
6
|
+
resources:
|
|
7
|
+
- namespace.yaml
|
|
8
|
+
- network-policies.yaml
|
|
9
|
+
# `config/` holds the vibecarbon-config ConfigMap (non-secret runtime
|
|
10
|
+
# settings — service URLs, retention days, etc.). The previous
|
|
11
|
+
# `secrets/` dir which bundled a Secret alongside the ConfigMap is
|
|
12
|
+
# gone — the Secret is now applied at deploy time by either the
|
|
13
|
+
# vibecarbon CLI or the .github/workflows/deploy.yml GitHub Action,
|
|
14
|
+
# with field-manager=github-actions-deploy so Flux doesn't touch it.
|
|
15
|
+
# See /home/brandon/.claude/plans/after-12-hours-of-goofy-snail.md.
|
|
16
|
+
- config/
|
|
17
|
+
# Note: hetzner-ccm and hetzner-csi are installed via cloud-init (master-init.sh)
|
|
18
|
+
# Note: cert-manager is installed separately via infra/ kustomization
|
|
19
|
+
# Note: Supabase (postgres, kong, auth, rest, realtime, storage, imgproxy,
|
|
20
|
+
# meta, studio, supavisor, edge-functions) is installed via the community
|
|
21
|
+
# Helm chart — see the helm step in src/lib/deploy/k8s/k3s.js. Values come
|
|
22
|
+
# from k8s/values/supabase.values.yaml, rendered at deploy time with our
|
|
23
|
+
# secrets.
|
|
24
|
+
- app/
|
|
25
|
+
- backup/
|
|
26
|
+
# `registry/` runs an S3-backed image registry on the master node (hostPort
|
|
27
|
+
# 5000 on the private network). Sideload remains primary for static workers,
|
|
28
|
+
# but cluster-autoscaler-spawned workers don't exist at sideload time —
|
|
29
|
+
# they pull from this registry on first schedule via the registries.yaml
|
|
30
|
+
# mirror config laid down in cloud-init.
|
|
31
|
+
- registry/
|
|
32
|
+
# Note: cluster-autoscaler is installed separately by applyK3sManifests
|
|
33
|
+
# (Phase 5) because it lives in `kube-system`, not `vibecarbon` — listing
|
|
34
|
+
# it here would let this kustomization's `namespace: vibecarbon`
|
|
35
|
+
# transformer rewrite its ServiceAccount/Role/RoleBinding/Deployment
|
|
36
|
+
# into the wrong namespace. Apply with:
|
|
37
|
+
# kubectl apply -k carbon/k8s/base/cluster-autoscaler/
|
|
38
|
+
# Mirrors the CCM/CSI pattern above.
|
|
39
|
+
- traefik/
|
|
40
|
+
|
|
41
|
+
labels:
|
|
42
|
+
- pairs:
|
|
43
|
+
app.kubernetes.io/part-of: vibecarbon
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# VIBECARBON NETWORK POLICIES (CLUSTER BASELINE)
|
|
3
|
+
# =============================================================================
|
|
4
|
+
# These policies implement a "deny by default" approach with explicit allowlists
|
|
5
|
+
# for required communication paths.
|
|
6
|
+
#
|
|
7
|
+
# Security Principle: Pods can only communicate with explicitly allowed targets.
|
|
8
|
+
# =============================================================================
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
# Default deny all INGRESS for the namespace. We don't deny egress by
|
|
12
|
+
# default — that broke the Supabase community chart whose subcharts
|
|
13
|
+
# (auth, rest, realtime, storage, analytics) init-container against the
|
|
14
|
+
# `supabase-supabase-db` service and don't have vibecarbon-app labels
|
|
15
|
+
# our specific allow-policies matched.
|
|
16
|
+
#
|
|
17
|
+
# The chart-internal east/west traffic is fine inside the namespace;
|
|
18
|
+
# external egress restrictions are enforced by the Hetzner firewall
|
|
19
|
+
# (no outbound from cluster-public nets to arbitrary ports anyway).
|
|
20
|
+
apiVersion: networking.k8s.io/v1
|
|
21
|
+
kind: NetworkPolicy
|
|
22
|
+
metadata:
|
|
23
|
+
name: default-deny-all
|
|
24
|
+
namespace: vibecarbon
|
|
25
|
+
spec:
|
|
26
|
+
podSelector: {}
|
|
27
|
+
policyTypes:
|
|
28
|
+
- Ingress
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
# Allow ALL ingress from other pods in the same namespace. Chart
|
|
32
|
+
# subcharts need to reach the db / kong / each other without us
|
|
33
|
+
# having to enumerate every label combination the chart might use.
|
|
34
|
+
# External ingress still gates through traefik-policy + app-policy etc.
|
|
35
|
+
apiVersion: networking.k8s.io/v1
|
|
36
|
+
kind: NetworkPolicy
|
|
37
|
+
metadata:
|
|
38
|
+
name: allow-intra-namespace
|
|
39
|
+
namespace: vibecarbon
|
|
40
|
+
spec:
|
|
41
|
+
podSelector: {}
|
|
42
|
+
policyTypes:
|
|
43
|
+
- Ingress
|
|
44
|
+
ingress:
|
|
45
|
+
- from:
|
|
46
|
+
- namespaceSelector:
|
|
47
|
+
matchLabels:
|
|
48
|
+
kubernetes.io/metadata.name: vibecarbon
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
# Allow egress to pods in the same namespace. Symmetric with the
|
|
52
|
+
# allow-intra-namespace ingress policy above. Required because
|
|
53
|
+
# `allow-dns` below selects all pods with Egress policyType, which
|
|
54
|
+
# implicitly switches the namespace to default-deny-egress for those
|
|
55
|
+
# pods. Without this, the Supabase subchart init containers can resolve
|
|
56
|
+
# `supabase-supabase-db` via DNS but the TCP connect to :5432 is
|
|
57
|
+
# dropped, causing a 25-minute wait-for-db loop on every cold install.
|
|
58
|
+
apiVersion: networking.k8s.io/v1
|
|
59
|
+
kind: NetworkPolicy
|
|
60
|
+
metadata:
|
|
61
|
+
name: allow-intra-namespace-egress
|
|
62
|
+
namespace: vibecarbon
|
|
63
|
+
spec:
|
|
64
|
+
podSelector: {}
|
|
65
|
+
policyTypes:
|
|
66
|
+
- Egress
|
|
67
|
+
egress:
|
|
68
|
+
- to:
|
|
69
|
+
- namespaceSelector:
|
|
70
|
+
matchLabels:
|
|
71
|
+
kubernetes.io/metadata.name: vibecarbon
|
|
72
|
+
---
|
|
73
|
+
# Allow DNS resolution for all pods
|
|
74
|
+
apiVersion: networking.k8s.io/v1
|
|
75
|
+
kind: NetworkPolicy
|
|
76
|
+
metadata:
|
|
77
|
+
name: allow-dns
|
|
78
|
+
namespace: vibecarbon
|
|
79
|
+
spec:
|
|
80
|
+
podSelector: {}
|
|
81
|
+
policyTypes:
|
|
82
|
+
- Egress
|
|
83
|
+
egress:
|
|
84
|
+
- to:
|
|
85
|
+
# Use namespaceSelector only (no podSelector) so kustomize commonLabels doesn't
|
|
86
|
+
# add environment/region/role labels to the selector, which would exclude CoreDNS
|
|
87
|
+
# pods (managed by k3s, they only have k8s-app: kube-dns, not overlay labels).
|
|
88
|
+
- namespaceSelector:
|
|
89
|
+
matchLabels:
|
|
90
|
+
kubernetes.io/metadata.name: kube-system
|
|
91
|
+
ports:
|
|
92
|
+
- protocol: UDP
|
|
93
|
+
port: 53
|
|
94
|
+
- protocol: TCP
|
|
95
|
+
port: 53
|