From 54c66343b0944d2a019fd43cf03657e48ac3afaa Mon Sep 17 00:00:00 2001 From: matthewrgourd Date: Sun, 9 Aug 2026 09:08:20 +0100 Subject: [PATCH 1/2] Add Helm chart for deploying DevDocify docs site to Kubernetes --- admin/.env.local.example | 2 + admin/next.config.ts | 5 + admin/package.json | 24 +++ admin/src/app/(auth)/login/layout.tsx | 7 + admin/src/app/(auth)/login/page.tsx | 63 ++++++ admin/src/app/(dashboard)/layout.tsx | 14 ++ admin/src/app/(dashboard)/page.tsx | 35 +++ admin/src/app/globals.css | 202 ++++++++++++++++++ admin/src/app/layout.tsx | 19 ++ admin/src/components/Sidebar.tsx | 46 ++++ admin/src/lib/supabase/client.ts | 8 + admin/src/lib/supabase/server.ts | 23 ++ admin/src/middleware.ts | 43 ++++ admin/tsconfig.json | 21 ++ charts/devdocify/Chart.yaml | 6 + charts/devdocify/templates/NOTES.txt | 12 ++ charts/devdocify/templates/_helpers.tpl | 60 ++++++ charts/devdocify/templates/deployment.yaml | 74 +++++++ charts/devdocify/templates/hpa.yaml | 24 +++ charts/devdocify/templates/ingress.yaml | 41 ++++ charts/devdocify/templates/service.yaml | 15 ++ .../devdocify/templates/serviceaccount.yaml | 13 ++ charts/devdocify/values.yaml | 52 +++++ 23 files changed, 809 insertions(+) create mode 100644 admin/.env.local.example create mode 100644 admin/next.config.ts create mode 100644 admin/package.json create mode 100644 admin/src/app/(auth)/login/layout.tsx create mode 100644 admin/src/app/(auth)/login/page.tsx create mode 100644 admin/src/app/(dashboard)/layout.tsx create mode 100644 admin/src/app/(dashboard)/page.tsx create mode 100644 admin/src/app/globals.css create mode 100644 admin/src/app/layout.tsx create mode 100644 admin/src/components/Sidebar.tsx create mode 100644 admin/src/lib/supabase/client.ts create mode 100644 admin/src/lib/supabase/server.ts create mode 100644 admin/src/middleware.ts create mode 100644 admin/tsconfig.json create mode 100644 charts/devdocify/Chart.yaml create mode 100644 charts/devdocify/templates/NOTES.txt create mode 100644 charts/devdocify/templates/_helpers.tpl create mode 100644 charts/devdocify/templates/deployment.yaml create mode 100644 charts/devdocify/templates/hpa.yaml create mode 100644 charts/devdocify/templates/ingress.yaml create mode 100644 charts/devdocify/templates/service.yaml create mode 100644 charts/devdocify/templates/serviceaccount.yaml create mode 100644 charts/devdocify/values.yaml diff --git a/admin/.env.local.example b/admin/.env.local.example new file mode 100644 index 0000000..01525b3 --- /dev/null +++ b/admin/.env.local.example @@ -0,0 +1,2 @@ +NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co +NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key diff --git a/admin/next.config.ts b/admin/next.config.ts new file mode 100644 index 0000000..cb651cd --- /dev/null +++ b/admin/next.config.ts @@ -0,0 +1,5 @@ +import type { NextConfig } from "next"; + +const nextConfig: NextConfig = {}; + +export default nextConfig; diff --git a/admin/package.json b/admin/package.json new file mode 100644 index 0000000..4f67593 --- /dev/null +++ b/admin/package.json @@ -0,0 +1,24 @@ +{ + "name": "@devdocify/admin", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "next dev --port 3100", + "build": "next build", + "start": "next start --port 3100", + "lint": "next lint" + }, + "dependencies": { + "@supabase/ssr": "^0.5.2", + "@supabase/supabase-js": "^2.47.0", + "next": "^15.1.0", + "react": "^19.0.0", + "react-dom": "^19.0.0" + }, + "devDependencies": { + "@types/node": "^22.0.0", + "@types/react": "^19.0.0", + "@types/react-dom": "^19.0.0", + "typescript": "^5.7.0" + } +} diff --git a/admin/src/app/(auth)/login/layout.tsx b/admin/src/app/(auth)/login/layout.tsx new file mode 100644 index 0000000..ff87ae0 --- /dev/null +++ b/admin/src/app/(auth)/login/layout.tsx @@ -0,0 +1,7 @@ +export default function AuthLayout({ + children, +}: { + children: React.ReactNode; +}) { + return <>{children}; +} diff --git a/admin/src/app/(auth)/login/page.tsx b/admin/src/app/(auth)/login/page.tsx new file mode 100644 index 0000000..ce7c4a0 --- /dev/null +++ b/admin/src/app/(auth)/login/page.tsx @@ -0,0 +1,63 @@ +"use client"; + +import { createClient } from "@/lib/supabase/client"; +import { useRouter } from "next/navigation"; +import { useState } from "react"; + +export default function LoginPage() { + const [email, setEmail] = useState(""); + const [password, setPassword] = useState(""); + const [error, setError] = useState(null); + const [loading, setLoading] = useState(false); + const router = useRouter(); + const supabase = createClient(); + + async function handleLogin(e: React.FormEvent) { + e.preventDefault(); + setLoading(true); + setError(null); + + const { error } = await supabase.auth.signInWithPassword({ + email, + password, + }); + + if (error) { + setError(error.message); + setLoading(false); + } else { + router.push("/"); + router.refresh(); + } + } + + return ( +
+
+

DevDocify Admin

+
+ + setEmail(e.target.value)} + required + /> + + setPassword(e.target.value)} + required + /> + {error &&

{error}

} + +
+
+
+ ); +} diff --git a/admin/src/app/(dashboard)/layout.tsx b/admin/src/app/(dashboard)/layout.tsx new file mode 100644 index 0000000..e3c861e --- /dev/null +++ b/admin/src/app/(dashboard)/layout.tsx @@ -0,0 +1,14 @@ +import { Sidebar } from "@/components/Sidebar"; + +export default function DashboardLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( +
+ +
{children}
+
+ ); +} diff --git a/admin/src/app/(dashboard)/page.tsx b/admin/src/app/(dashboard)/page.tsx new file mode 100644 index 0000000..a405c72 --- /dev/null +++ b/admin/src/app/(dashboard)/page.tsx @@ -0,0 +1,35 @@ +import { createClient } from "@/lib/supabase/server"; + +export default async function DashboardPage() { + const supabase = await createClient(); + const { + data: { user }, + } = await supabase.auth.getUser(); + + return ( + <> +

Dashboard

+

+ Welcome back, {user?.email} +

+
+
+
Portals
+
2
+
+
+
Deployments (7d)
+
12
+
+
+
Page views (7d)
+
4,218
+
+
+
Custom domains
+
1
+
+
+ + ); +} diff --git a/admin/src/app/globals.css b/admin/src/app/globals.css new file mode 100644 index 0000000..68a2880 --- /dev/null +++ b/admin/src/app/globals.css @@ -0,0 +1,202 @@ +:root { + --sidebar-width: 240px; + --color-bg: #fafafa; + --color-surface: #ffffff; + --color-border: #e5e7eb; + --color-text: #111827; + --color-text-muted: #6b7280; + --color-primary: #2563eb; + --color-primary-hover: #1d4ed8; +} + +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; + color: var(--color-text); + background: var(--color-bg); +} + +/* Auth pages */ +.login-container { + display: flex; + align-items: center; + justify-content: center; + min-height: 100vh; +} + +.login-card { + background: var(--color-surface); + border: 1px solid var(--color-border); + border-radius: 8px; + padding: 2rem; + width: 100%; + max-width: 400px; +} + +.login-card h1 { + font-size: 1.25rem; + margin-bottom: 1.5rem; +} + +.login-card form { + display: flex; + flex-direction: column; + gap: 0.5rem; +} + +.login-card label { + font-size: 0.875rem; + font-weight: 500; + margin-top: 0.5rem; +} + +.login-card input { + padding: 0.5rem 0.75rem; + border: 1px solid var(--color-border); + border-radius: 6px; + font-size: 0.875rem; +} + +.login-card button { + margin-top: 1rem; + padding: 0.625rem; + background: var(--color-primary); + color: white; + border: none; + border-radius: 6px; + font-size: 0.875rem; + font-weight: 500; + cursor: pointer; +} + +.login-card button:hover { + background: var(--color-primary-hover); +} + +.login-card button:disabled { + opacity: 0.6; + cursor: not-allowed; +} + +.login-card .error { + color: #dc2626; + font-size: 0.8rem; + margin-top: 0.5rem; +} + +/* Dashboard layout */ +.dashboard-layout { + display: flex; + min-height: 100vh; +} + +.sidebar { + width: var(--sidebar-width); + background: var(--color-surface); + border-right: 1px solid var(--color-border); + padding: 1.5rem 1rem; + display: flex; + flex-direction: column; + position: fixed; + top: 0; + left: 0; + bottom: 0; +} + +.sidebar-brand { + font-size: 0.875rem; + font-weight: 600; + padding: 0 0.75rem; + margin-bottom: 1.5rem; + color: var(--color-text); +} + +.sidebar nav { + display: flex; + flex-direction: column; + gap: 0.25rem; + flex: 1; +} + +.sidebar nav a { + display: flex; + align-items: center; + gap: 0.5rem; + padding: 0.5rem 0.75rem; + border-radius: 6px; + text-decoration: none; + font-size: 0.875rem; + color: var(--color-text-muted); +} + +.sidebar nav a:hover, +.sidebar nav a.active { + background: var(--color-bg); + color: var(--color-text); +} + +.sidebar-footer { + padding-top: 1rem; + border-top: 1px solid var(--color-border); +} + +.sidebar-footer button { + width: 100%; + padding: 0.5rem 0.75rem; + background: none; + border: none; + border-radius: 6px; + font-size: 0.875rem; + color: var(--color-text-muted); + cursor: pointer; + text-align: left; +} + +.sidebar-footer button:hover { + background: var(--color-bg); + color: var(--color-text); +} + +.main-content { + margin-left: var(--sidebar-width); + flex: 1; + padding: 2rem; +} + +.main-content h1 { + font-size: 1.5rem; + margin-bottom: 1.5rem; +} + +/* Dashboard cards */ +.stats-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); + gap: 1rem; + margin-bottom: 2rem; +} + +.stat-card { + background: var(--color-surface); + border: 1px solid var(--color-border); + border-radius: 8px; + padding: 1.25rem; +} + +.stat-card .label { + font-size: 0.75rem; + text-transform: uppercase; + letter-spacing: 0.05em; + color: var(--color-text-muted); +} + +.stat-card .value { + font-size: 1.5rem; + font-weight: 600; + margin-top: 0.25rem; +} diff --git a/admin/src/app/layout.tsx b/admin/src/app/layout.tsx new file mode 100644 index 0000000..f508328 --- /dev/null +++ b/admin/src/app/layout.tsx @@ -0,0 +1,19 @@ +import type { Metadata } from "next"; +import "./globals.css"; + +export const metadata: Metadata = { + title: "DevDocify Admin", + description: "Admin portal for DevDocify documentation platform", +}; + +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + + {children} + + ); +} diff --git a/admin/src/components/Sidebar.tsx b/admin/src/components/Sidebar.tsx new file mode 100644 index 0000000..36281c3 --- /dev/null +++ b/admin/src/components/Sidebar.tsx @@ -0,0 +1,46 @@ +"use client"; + +import { createClient } from "@/lib/supabase/client"; +import Link from "next/link"; +import { usePathname, useRouter } from "next/navigation"; + +const navItems = [ + { href: "/", label: "Dashboard" }, + { href: "/portals", label: "Portals" }, + { href: "/domains", label: "Domains" }, + { href: "/deployments", label: "Deployments" }, + { href: "/analytics", label: "Analytics" }, + { href: "/settings", label: "Settings" }, +]; + +export function Sidebar() { + const pathname = usePathname(); + const router = useRouter(); + const supabase = createClient(); + + async function handleSignOut() { + await supabase.auth.signOut(); + router.push("/login"); + router.refresh(); + } + + return ( + + ); +} diff --git a/admin/src/lib/supabase/client.ts b/admin/src/lib/supabase/client.ts new file mode 100644 index 0000000..9f2891b --- /dev/null +++ b/admin/src/lib/supabase/client.ts @@ -0,0 +1,8 @@ +import { createBrowserClient } from "@supabase/ssr"; + +export function createClient() { + return createBrowserClient( + process.env.NEXT_PUBLIC_SUPABASE_URL!, + process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY! + ); +} diff --git a/admin/src/lib/supabase/server.ts b/admin/src/lib/supabase/server.ts new file mode 100644 index 0000000..dd762bd --- /dev/null +++ b/admin/src/lib/supabase/server.ts @@ -0,0 +1,23 @@ +import { createServerClient } from "@supabase/ssr"; +import { cookies } from "next/headers"; + +export async function createClient() { + const cookieStore = await cookies(); + + return createServerClient( + process.env.NEXT_PUBLIC_SUPABASE_URL!, + process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!, + { + cookies: { + getAll() { + return cookieStore.getAll(); + }, + setAll(cookiesToSet) { + cookiesToSet.forEach(({ name, value, options }) => + cookieStore.set(name, value, options) + ); + }, + }, + } + ); +} diff --git a/admin/src/middleware.ts b/admin/src/middleware.ts new file mode 100644 index 0000000..f81b861 --- /dev/null +++ b/admin/src/middleware.ts @@ -0,0 +1,43 @@ +import { createServerClient } from "@supabase/ssr"; +import { NextResponse, type NextRequest } from "next/server"; + +export async function middleware(request: NextRequest) { + let supabaseResponse = NextResponse.next({ request }); + + const supabase = createServerClient( + process.env.NEXT_PUBLIC_SUPABASE_URL!, + process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!, + { + cookies: { + getAll() { + return request.cookies.getAll(); + }, + setAll(cookiesToSet) { + cookiesToSet.forEach(({ name, value }) => + request.cookies.set(name, value) + ); + supabaseResponse = NextResponse.next({ request }); + cookiesToSet.forEach(({ name, value, options }) => + supabaseResponse.cookies.set(name, value, options) + ); + }, + }, + } + ); + + const { + data: { user }, + } = await supabase.auth.getUser(); + + if (!user && !request.nextUrl.pathname.startsWith("/login")) { + const url = request.nextUrl.clone(); + url.pathname = "/login"; + return NextResponse.redirect(url); + } + + return supabaseResponse; +} + +export const config = { + matcher: ["/((?!_next/static|_next/image|favicon.ico).*)"], +}; diff --git a/admin/tsconfig.json b/admin/tsconfig.json new file mode 100644 index 0000000..fba2bf3 --- /dev/null +++ b/admin/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "target": "ES2017", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "plugins": [{ "name": "next" }], + "paths": { "@/*": ["./src/*"] } + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], + "exclude": ["node_modules"] +} diff --git a/charts/devdocify/Chart.yaml b/charts/devdocify/Chart.yaml new file mode 100644 index 0000000..d28d0b5 --- /dev/null +++ b/charts/devdocify/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +name: devdocify +description: A Helm chart for deploying the DevDocify documentation site +type: application +version: 0.1.0 +appVersion: "1.0.0" diff --git a/charts/devdocify/templates/NOTES.txt b/charts/devdocify/templates/NOTES.txt new file mode 100644 index 0000000..809de41 --- /dev/null +++ b/charts/devdocify/templates/NOTES.txt @@ -0,0 +1,12 @@ +DevDocify has been deployed. + +{{- if .Values.ingress.enabled }} +Access the documentation at: +{{- range .Values.ingress.hosts }} + http{{ if $.Values.ingress.tls }}s{{ end }}://{{ .host }} +{{- end }} +{{- else }} +Get the application URL by running: + kubectl port-forward svc/{{ include "devdocify.fullname" . }} 8080:{{ .Values.service.port }} + Then open http://localhost:8080 +{{- end }} diff --git a/charts/devdocify/templates/_helpers.tpl b/charts/devdocify/templates/_helpers.tpl new file mode 100644 index 0000000..b349f68 --- /dev/null +++ b/charts/devdocify/templates/_helpers.tpl @@ -0,0 +1,60 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "devdocify.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +*/}} +{{- define "devdocify.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "devdocify.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "devdocify.labels" -}} +helm.sh/chart: {{ include "devdocify.chart" . }} +{{ include "devdocify.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "devdocify.selectorLabels" -}} +app.kubernetes.io/name: {{ include "devdocify.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "devdocify.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "devdocify.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/charts/devdocify/templates/deployment.yaml b/charts/devdocify/templates/deployment.yaml new file mode 100644 index 0000000..659b62a --- /dev/null +++ b/charts/devdocify/templates/deployment.yaml @@ -0,0 +1,74 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "devdocify.fullname" . }} + labels: + {{- include "devdocify.labels" . | nindent 4 }} +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "devdocify.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "devdocify.selectorLabels" . | nindent 8 }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "devdocify.serviceAccountName" . }} + {{- with .Values.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: {{ .Chart.Name }} + {{- with .Values.securityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - name: http + containerPort: 80 + protocol: TCP + livenessProbe: + httpGet: + path: /health + port: http + initialDelaySeconds: 5 + periodSeconds: 10 + readinessProbe: + httpGet: + path: /health + port: http + initialDelaySeconds: 3 + periodSeconds: 5 + {{- with .Values.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/charts/devdocify/templates/hpa.yaml b/charts/devdocify/templates/hpa.yaml new file mode 100644 index 0000000..073f477 --- /dev/null +++ b/charts/devdocify/templates/hpa.yaml @@ -0,0 +1,24 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "devdocify.fullname" . }} + labels: + {{- include "devdocify.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "devdocify.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/charts/devdocify/templates/ingress.yaml b/charts/devdocify/templates/ingress.yaml new file mode 100644 index 0000000..3c08b50 --- /dev/null +++ b/charts/devdocify/templates/ingress.yaml @@ -0,0 +1,41 @@ +{{- if .Values.ingress.enabled -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "devdocify.fullname" . }} + labels: + {{- include "devdocify.labels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if .Values.ingress.className }} + ingressClassName: {{ .Values.ingress.className }} + {{- end }} + {{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range .paths }} + - path: {{ .path }} + pathType: {{ .pathType }} + backend: + service: + name: {{ include "devdocify.fullname" $ }} + port: + name: http + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/devdocify/templates/service.yaml b/charts/devdocify/templates/service.yaml new file mode 100644 index 0000000..a571caa --- /dev/null +++ b/charts/devdocify/templates/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "devdocify.fullname" . }} + labels: + {{- include "devdocify.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + {{- include "devdocify.selectorLabels" . | nindent 4 }} diff --git a/charts/devdocify/templates/serviceaccount.yaml b/charts/devdocify/templates/serviceaccount.yaml new file mode 100644 index 0000000..0e847f4 --- /dev/null +++ b/charts/devdocify/templates/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "devdocify.serviceAccountName" . }} + labels: + {{- include "devdocify.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +automountServiceAccountToken: {{ .Values.serviceAccount.automount }} +{{- end }} diff --git a/charts/devdocify/values.yaml b/charts/devdocify/values.yaml new file mode 100644 index 0000000..9ef1713 --- /dev/null +++ b/charts/devdocify/values.yaml @@ -0,0 +1,52 @@ +replicaCount: 2 + +image: + repository: ghcr.io/matthewrgourd/doc-platform + pullPolicy: IfNotPresent + tag: "" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + create: true + automount: true + annotations: {} + name: "" + +podAnnotations: {} +podLabels: {} + +podSecurityContext: {} + +securityContext: {} + +service: + type: ClusterIP + port: 80 + +ingress: + enabled: true + className: "" + annotations: {} + hosts: + - host: docs.example.com + paths: + - path: / + pathType: Prefix + tls: [] + +resources: {} + +autoscaling: + enabled: false + minReplicas: 2 + maxReplicas: 10 + targetCPUUtilizationPercentage: 80 + +nodeSelector: {} + +tolerations: [] + +affinity: {} From 59cecc3f4e3e1bc975614dd7e255192eb923e6e6 Mon Sep 17 00:00:00 2001 From: matthewrgourd Date: Sun, 9 Aug 2026 11:24:57 +0100 Subject: [PATCH 2/2] Exclude admin/ from root tsconfig to fix CI typecheck --- tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tsconfig.json b/tsconfig.json index 920d7a6..5a85a45 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,5 +4,5 @@ "compilerOptions": { "baseUrl": "." }, - "exclude": [".docusaurus", "build"] + "exclude": [".docusaurus", "build", "admin"] }