added cal.com

This commit is contained in:
2026-01-08 16:05:58 +01:00
parent 83261d9609
commit cbd954d656
2 changed files with 535 additions and 0 deletions
+22
View File
@@ -856,3 +856,25 @@ spec:
- CreateNamespace=true - CreateNamespace=true
- PruneLast=true - PruneLast=true
--- ---
# Booking (Cal.com)
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: booking
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: homelab
source:
repoURL: https://gitea.dooplex.hu/admin/homelab-manifests.git
targetRevision: main
path: booking-system
destination:
server: https://kubernetes.default.svc
namespace: booking-system
syncPolicy:
syncOptions:
- CreateNamespace=true
- PruneLast=true
---
+513
View File
@@ -0,0 +1,513 @@
---
# Cal.com - Open-source scheduling infrastructure
# https://cal.com/
#
# Features:
# - Stripe payment integration (native)
# - Configurable time slots
# - Cancellation policies with fees
# - Google Calendar sync
# - Email notifications
# - Multiple event types
# - Booking notes
# - White-label capable
# - OIDC/SAML SSO support (Authentik integration!)
#
# Prerequisites:
# 1. Create databases in shared PostgreSQL:
# kubectl exec -it postgresql-1 -n database-system -- psql -U postgres
#
# -- Main database
# CREATE DATABASE calcom;
# CREATE USER calcom WITH PASSWORD 'your-secure-password';
# GRANT ALL PRIVILEGES ON DATABASE calcom TO calcom;
# \c calcom
# GRANT ALL ON SCHEMA public TO calcom;
#
# -- SSO/SAML database (required for OIDC!)
# CREATE DATABASE calcom_saml;
# GRANT ALL PRIVILEGES ON DATABASE calcom_saml TO calcom;
# \c calcom_saml
# GRANT ALL ON SCHEMA public TO calcom;
#
# 2. Set up Stripe account at https://stripe.com (Hungary supported)
# Get API keys from Dashboard -> Developers -> API keys
#
# 3. Set up Authentik OIDC provider:
# - Create OAuth2/OpenID Provider in Authentik
# - Client type: Confidential
# - Redirect URIs: https://booking.dooplex.hu/api/auth/callback/oidc
# - Note the Client ID, Client Secret
# - Well-known URL: https://authentik.dooplex.hu/application/o/<slug>/.well-known/openid-configuration
#
# 4. (Optional) Set up Google OAuth for calendar sync:
# https://console.cloud.google.com/apis/credentials
#
# After deployment:
# 1. Access https://booking.dooplex.hu
# 2. Create first user with email matching SAML_ADMINS
# 3. Go to Settings → Security → SSO
# 4. Click "Configure SSO with OIDC"
# 5. Enter Client ID, Client Secret, Well-known URL from Authentik
# 6. Configure event types, availability, and Stripe integration
---
apiVersion: v1
kind: Namespace
metadata:
name: booking-system
labels:
app.kubernetes.io/name: calcom
---
# Redis for Cal.com (required for sessions, rate limiting, etc.)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: calcom-redis
namespace: booking-system
labels:
app.kubernetes.io/instance: calcom
app.kubernetes.io/name: redis
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 1Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: calcom-redis
namespace: booking-system
labels:
app.kubernetes.io/instance: calcom
app.kubernetes.io/name: redis
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app.kubernetes.io/instance: calcom
app.kubernetes.io/name: redis
template:
metadata:
labels:
app.kubernetes.io/instance: calcom
app.kubernetes.io/name: redis
spec:
containers:
- name: redis
image: redis:7-alpine
imagePullPolicy: IfNotPresent
args:
- redis-server
- --appendonly
- "yes"
- --maxmemory
- "256mb"
- --maxmemory-policy
- "allkeys-lru"
ports:
- containerPort: 6379
name: redis
protocol: TCP
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 200m
memory: 256Mi
volumeMounts:
- name: data
mountPath: /data
livenessProbe:
exec:
command:
- redis-cli
- ping
initialDelaySeconds: 10
periodSeconds: 10
readinessProbe:
exec:
command:
- redis-cli
- ping
initialDelaySeconds: 5
periodSeconds: 5
volumes:
- name: data
persistentVolumeClaim:
claimName: calcom-redis
---
apiVersion: v1
kind: Service
metadata:
name: calcom-redis
namespace: booking-system
labels:
app.kubernetes.io/instance: calcom
app.kubernetes.io/name: redis
spec:
type: ClusterIP
ports:
- port: 6379
targetPort: redis
protocol: TCP
name: redis
selector:
app.kubernetes.io/instance: calcom
app.kubernetes.io/name: redis
---
# Cal.com Web Application
apiVersion: apps/v1
kind: Deployment
metadata:
name: calcom
namespace: booking-system
labels:
app.kubernetes.io/instance: calcom
app.kubernetes.io/name: calcom
app.kubernetes.io/version: "v6.0.8"
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app.kubernetes.io/instance: calcom
app.kubernetes.io/name: calcom
template:
metadata:
labels:
app.kubernetes.io/instance: calcom
app.kubernetes.io/name: calcom
app.kubernetes.io/version: "v6.0.8"
spec:
initContainers:
# Wait for PostgreSQL
- name: wait-for-db
image: busybox:1.36
command:
- sh
- -c
- |
echo "Waiting for PostgreSQL..."
until nc -z postgresql-rw.database-system.svc.cluster.local 5432; do
echo "PostgreSQL not ready, waiting..."
sleep 2
done
echo "PostgreSQL is ready!"
# Wait for Redis
- name: wait-for-redis
image: busybox:1.36
command:
- sh
- -c
- |
echo "Waiting for Redis..."
until nc -z calcom-redis 6379; do
echo "Redis not ready, waiting..."
sleep 2
done
echo "Redis is ready!"
containers:
- name: calcom
image: calcom/cal.com:v6.0.8
imagePullPolicy: IfNotPresent
env:
# License (empty for AGPL, set key for enterprise features)
- name: CALCOM_LICENSE_KEY
value: ""
# Telemetry
- name: NEXT_PUBLIC_IS_E2E
value: "false"
- name: CALCOM_TELEMETRY_DISABLED
value: "1"
# URLs
- name: NEXT_PUBLIC_WEBAPP_URL
value: "https://booking.dooplex.hu"
- name: NEXTAUTH_URL
value: "https://booking.dooplex.hu/api/auth"
- name: NEXT_PUBLIC_API_V2_URL
value: "https://booking.dooplex.hu/api/v2"
# Database - using shared PostgreSQL
- name: DATABASE_URL
value: "postgresql://$(DB_USER):$(DB_PASS)@postgresql-rw.database-system.svc.cluster.local:5432/calcom"
- name: DATABASE_DIRECT_URL
value: "postgresql://$(DB_USER):$(DB_PASS)@postgresql-rw.database-system.svc.cluster.local:5432/calcom"
- name: DB_USER
valueFrom:
secretKeyRef:
name: calcom-db
key: username
- name: DB_PASS
valueFrom:
secretKeyRef:
name: calcom-db
key: password
# Redis
- name: REDIS_URL
value: "redis://calcom-redis:6379"
# SSO/OIDC Configuration (for Authentik integration)
# Requires separate database - see prerequisites
- name: SAML_DATABASE_URL
value: "postgresql://$(DB_USER):$(DB_PASS)@postgresql-rw.database-system.svc.cluster.local:5432/calcom_saml"
# Admin email(s) who can configure SSO in the UI
# Must match the email used when creating the first user
- name: SAML_ADMINS
valueFrom:
secretKeyRef:
name: calcom-app
key: saml-admin-email
# Auth secrets
- name: NEXTAUTH_SECRET
valueFrom:
secretKeyRef:
name: calcom-app
key: nextauth-secret
- name: CALENDSO_ENCRYPTION_KEY
valueFrom:
secretKeyRef:
name: calcom-app
key: calendso-encryption-key
# Email/SMTP
- name: EMAIL_FROM
valueFrom:
secretKeyRef:
name: smtp-credentials
key: from-address
- name: EMAIL_SERVER_HOST
valueFrom:
secretKeyRef:
name: smtp-credentials
key: host
- name: EMAIL_SERVER_PORT
valueFrom:
secretKeyRef:
name: smtp-credentials
key: port
- name: EMAIL_SERVER_USER
valueFrom:
secretKeyRef:
name: smtp-credentials
key: username
- name: EMAIL_SERVER_PASSWORD
valueFrom:
secretKeyRef:
name: smtp-credentials
key: password
# Stripe (optional - for payments)
- name: STRIPE_API_KEY
valueFrom:
secretKeyRef:
name: calcom-app
key: stripe-api-key
- name: STRIPE_WEBHOOK_SECRET
valueFrom:
secretKeyRef:
name: calcom-app
key: stripe-webhook-secret
- name: NEXT_PUBLIC_STRIPE_PUBLIC_KEY
valueFrom:
secretKeyRef:
name: calcom-app
key: next-public-stripe-key
- name: PAYMENT_FEE_PERCENTAGE
value: "0"
- name: PAYMENT_FEE_FIXED
value: "0"
# Google Calendar (optional)
- name: GOOGLE_API_CREDENTIALS
valueFrom:
secretKeyRef:
name: calcom-app
key: google-client-id
optional: true
# Timezone
- name: TZ
value: "Europe/Budapest"
# Misc
- name: NODE_ENV
value: "production"
- name: NODE_TLS_REJECT_UNAUTHORIZED
value: "0"
# Allow signup (set to "false" after creating your account if you want to restrict)
- name: NEXT_PUBLIC_DISABLE_SIGNUP
value: "false"
# CSP - needed for embedded iframes if you want to embed booking widget
- name: CSP_POLICY
value: ""
ports:
- containerPort: 3000
name: http
protocol: TCP
resources:
requests:
cpu: 200m
memory: 512Mi
limits:
cpu: "2"
memory: 2Gi
livenessProbe:
httpGet:
path: /api/health
port: http
initialDelaySeconds: 120
periodSeconds: 30
timeoutSeconds: 10
failureThreshold: 5
readinessProbe:
httpGet:
path: /api/health
port: http
initialDelaySeconds: 60
periodSeconds: 15
timeoutSeconds: 10
failureThreshold: 3
startupProbe:
httpGet:
path: /api/health
port: http
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 10
failureThreshold: 30
---
apiVersion: v1
kind: Service
metadata:
name: calcom
namespace: booking-system
labels:
app.kubernetes.io/instance: calcom
app.kubernetes.io/name: calcom
spec:
type: ClusterIP
ports:
- port: 3000
targetPort: http
protocol: TCP
name: http
selector:
app.kubernetes.io/instance: calcom
app.kubernetes.io/name: calcom
---
# Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: calcom
namespace: booking-system
labels:
app.kubernetes.io/instance: calcom
app.kubernetes.io/name: calcom
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
external-dns.alpha.kubernetes.io/hostname: booking.dooplex.hu,booking.home
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/proxy-body-size: "64m"
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
# Required for WebSocket connections (if using Cal.com video)
nginx.ingress.kubernetes.io/proxy-http-version: "1.1"
nginx.ingress.kubernetes.io/proxy-set-headers: "booking-system/calcom-proxy-headers"
spec:
ingressClassName: nginx-internal
rules:
- host: booking.dooplex.hu
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: calcom
port:
number: 3000
- host: booking.home
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: calcom
port:
number: 3000
tls:
- hosts:
- booking.dooplex.hu
secretName: calcom-tls
---
# ConfigMap for nginx proxy headers (WebSocket support)
apiVersion: v1
kind: ConfigMap
metadata:
name: calcom-proxy-headers
namespace: booking-system
data:
Upgrade: "$http_upgrade"
Connection: "upgrade"
---
# Optional: Prisma Studio for database management/first user creation
# Uncomment if you need direct database access
# Access via port-forward: kubectl port-forward svc/calcom-prisma-studio 5555:5555 -n booking-system
# ---
# apiVersion: apps/v1
# kind: Deployment
# metadata:
# name: calcom-prisma-studio
# namespace: booking-system
# labels:
# app.kubernetes.io/instance: calcom
# app.kubernetes.io/name: prisma-studio
# spec:
# replicas: 1
# selector:
# matchLabels:
# app.kubernetes.io/instance: calcom
# app.kubernetes.io/name: prisma-studio
# template:
# metadata:
# labels:
# app.kubernetes.io/instance: calcom
# app.kubernetes.io/name: prisma-studio
# spec:
# containers:
# - name: prisma-studio
# image: calcom/cal.com:v5.9.15
# command: ["npx", "prisma", "studio"]
# env:
# - name: DATABASE_URL
# value: "postgresql://calcom:YOUR_PASSWORD@postgresql-rw.database-system.svc.cluster.local:5432/calcom"
# ports:
# - containerPort: 5555
# name: http
# ---
# apiVersion: v1
# kind: Service
# metadata:
# name: calcom-prisma-studio
# namespace: booking-system
# spec:
# type: ClusterIP
# ports:
# - port: 5555
# targetPort: 5555
# selector:
# app.kubernetes.io/instance: calcom
# app.kubernetes.io/name: prisma-studio