diff --git a/README.md b/README.md index 7f7f0520d..757e70493 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,8 @@ Checkmate has been stress-tested with 1000+ active monitors without any particul - [📦 Demo](#-demo) - [🔗 User's guide](#-users-guide) -- [🛠️ Installation](#️-installation) +- [🛠️ Installation](#️-installation) +- [🚀 Deploying Checkmate with Helm](#-deploying-checkmate-with-helm) - [🏁 Translations](#-translations) - [🚀 Performance](#-performance) - [💚 Questions & Ideas](#-questions--ideas) @@ -50,7 +51,10 @@ Usage instructions can be found [here](https://docs.checkmate.so/checkmate-2.1). ## 🛠️ Installation -See installation instructions in [Checkmate documentation portal](https://docs.checkmate.so/checkmate-2.1/users-guide/quickstart). Alternatively, you can also use [Coolify](https://coolify.io/), [Elestio](https://elest.io/open-source/checkmate) or [Pikapods](https://www.pikapods.com/) to quickly spin off a Checkmate instance. If you would like to monitor your server infrastructure, you'll need [Capture agent](https://github.com/bluewave-labs/capture). Capture repository also contains the installation instructions. +See installation instructions in [Checkmate documentation portal](https://docs.checkmate.so/checkmate-2.1/users-guide/quickstart). + +Alternatively, you can also use [Coolify](https://coolify.io/), [Elestio](https://elest.io/open-source/checkmate), [K8s](./charts/helm/checkmate/INSTALLATION.md) or [Pikapods](https://www.pikapods.com/) to quickly spin off a Checkmate instance. If you would like to monitor your server infrastructure, you'll need [Capture agent](https://github.com/bluewave-labs/capture). Capture repository also contains the installation instructions. + ## 🏁 Translations diff --git a/charts/helm/checkmate/.helmignore b/charts/helm/checkmate/.helmignore new file mode 100644 index 000000000..21846e965 --- /dev/null +++ b/charts/helm/checkmate/.helmignore @@ -0,0 +1,17 @@ +.DS_Store +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +*.swp +*.bak +*.tmp +*.orig +*~ +.project +.idea/ +*.tmproj +.vscode/ diff --git a/charts/helm/checkmate/Chart.yaml b/charts/helm/checkmate/Chart.yaml new file mode 100644 index 000000000..97f320e68 --- /dev/null +++ b/charts/helm/checkmate/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +name: checkmate-chart +description: A Helm chart for Checkmate App +type: application +version: 0.1.0 +appVersion: "2.3" diff --git a/charts/helm/checkmate/INSTALLATION.md b/charts/helm/checkmate/INSTALLATION.md new file mode 100644 index 000000000..9ca321ad3 --- /dev/null +++ b/charts/helm/checkmate/INSTALLATION.md @@ -0,0 +1,39 @@ +# Kubernetes Installation Guide for Checkmate + +This guide walks you through deploying Checkmate on your Kubernetes cluster using Helm. + +## Prerequisites + +- A running Kubernetes cluster +- Helm CLI installed and configured +- `kubectl` configured to access your cluster + +## Steps + +### 1. Clone the repo and navigate to the Helm chart + +```bash +git clone https://github.com/bluewave-labs/checkmate.git +cd checkmate/charts/helm/checkmate +``` + +### 2. Customize values.yaml +Edit `values.yaml` to update: +- `client.ingress.host` and `server.ingress.host` with your domain names +- `server.protocol` (usually http or https) +- Secrets under the `secrets` section (`JWT_SECRET`, email credentials, API keys, etc.) — replace all change_me values + +### 3. Deploy the Helm chart +```bash +helm install checkmate ./charts/helm/checkmate +``` +This will deploy the client, server, MongoDB, and Redis components. + +### 4. Verify the deployment +Check pods and services: +```bash +kubectl get pods +kubectl get svc +``` + +Once all pods are `Running` and `Ready`, you can access Checkmate via the configured ingress hosts. diff --git a/charts/helm/checkmate/templates/_prechecks.yaml b/charts/helm/checkmate/templates/_prechecks.yaml new file mode 100644 index 000000000..870ab5c77 --- /dev/null +++ b/charts/helm/checkmate/templates/_prechecks.yaml @@ -0,0 +1,12 @@ +{{- if eq .Values.client.ingress.host "change_me" }} + {{- fail "client.ingress.host must be overridden and not set to 'change_me'" }} +{{- end }} + +{{- if eq .Values.server.ingress.host "change_me" }} + {{- fail "server.ingress.host must be overridden and not set to 'change_me'" }} +{{- end }} + +{{- $protocol := .Values.server.protocol }} +{{- if not (or (eq $protocol "http") (eq $protocol "https")) }} + {{- fail "server.protocol must be either 'http' or 'https'" }} +{{- end }} diff --git a/charts/helm/checkmate/templates/client-deployment.yaml b/charts/helm/checkmate/templates/client-deployment.yaml new file mode 100644 index 000000000..6c1f70fd7 --- /dev/null +++ b/charts/helm/checkmate/templates/client-deployment.yaml @@ -0,0 +1,22 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: client +spec: + replicas: 1 + selector: + matchLabels: + app: client + template: + metadata: + labels: + app: client + spec: + containers: + - name: client + image: {{ .Values.client.image }} + ports: + - containerPort: {{ .Values.client.port }} + env: + - name: UPTIME_APP_API_BASE_URL + value: "{{ .Values.server.protocol }}://{{ .Values.server.ingress.host }}/api/v1" diff --git a/charts/helm/checkmate/templates/client-ingress.yaml b/charts/helm/checkmate/templates/client-ingress.yaml new file mode 100644 index 000000000..da059a863 --- /dev/null +++ b/charts/helm/checkmate/templates/client-ingress.yaml @@ -0,0 +1,20 @@ +{{- if .Values.client.ingress.enabled }} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: client-ingress + annotations: + nginx.ingress.kubernetes.io/rewrite-target: / +spec: + rules: + - host: {{ .Values.client.ingress.host }} + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: client + port: + number: {{ .Values.client.port }} +{{- end }} diff --git a/charts/helm/checkmate/templates/client-service.yaml b/charts/helm/checkmate/templates/client-service.yaml new file mode 100644 index 000000000..afb88188c --- /dev/null +++ b/charts/helm/checkmate/templates/client-service.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Service +metadata: + name: client +spec: + selector: + app: client + ports: + - port: {{ .Values.client.port }} diff --git a/charts/helm/checkmate/templates/mongodb-deployment.yaml b/charts/helm/checkmate/templates/mongodb-deployment.yaml new file mode 100644 index 000000000..4c906fe09 --- /dev/null +++ b/charts/helm/checkmate/templates/mongodb-deployment.yaml @@ -0,0 +1,27 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: mongodb +spec: + replicas: 1 + selector: + matchLabels: + app: mongodb + template: + metadata: + labels: + app: mongodb + spec: + containers: + - name: mongodb + image: {{ .Values.mongodb.image }} + ports: + - containerPort: {{ .Values.mongodb.port }} + command: ["mongod", "--quiet", "--bind_ip_all"] + volumeMounts: + - name: mongodb-data + mountPath: /data/db + volumes: + - name: mongodb-data + persistentVolumeClaim: + claimName: mongodb-pvc \ No newline at end of file diff --git a/charts/helm/checkmate/templates/mongodb-pvc.yaml b/charts/helm/checkmate/templates/mongodb-pvc.yaml new file mode 100644 index 000000000..435b662e6 --- /dev/null +++ b/charts/helm/checkmate/templates/mongodb-pvc.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: mongodb-pvc +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .Values.persistence.mongodbSize }} \ No newline at end of file diff --git a/charts/helm/checkmate/templates/mongodb-service.yaml b/charts/helm/checkmate/templates/mongodb-service.yaml new file mode 100644 index 000000000..2911dc3eb --- /dev/null +++ b/charts/helm/checkmate/templates/mongodb-service.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Service +metadata: + name: mongodb +spec: + selector: + app: mongodb + ports: + - port: {{ .Values.mongodb.port }} \ No newline at end of file diff --git a/charts/helm/checkmate/templates/redis-deployment.yaml b/charts/helm/checkmate/templates/redis-deployment.yaml new file mode 100644 index 000000000..cc9ffdaf9 --- /dev/null +++ b/charts/helm/checkmate/templates/redis-deployment.yaml @@ -0,0 +1,26 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: redis +spec: + replicas: 1 + selector: + matchLabels: + app: redis + template: + metadata: + labels: + app: redis + spec: + containers: + - name: redis + image: {{ .Values.redis.image }} + ports: + - containerPort: {{ .Values.redis.port }} + volumeMounts: + - name: redis-data + mountPath: /data + volumes: + - name: redis-data + persistentVolumeClaim: + claimName: redis-pvc diff --git a/charts/helm/checkmate/templates/redis-pvc.yaml b/charts/helm/checkmate/templates/redis-pvc.yaml new file mode 100644 index 000000000..2f0d81960 --- /dev/null +++ b/charts/helm/checkmate/templates/redis-pvc.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: redis-pvc +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .Values.persistence.redisSize }} \ No newline at end of file diff --git a/charts/helm/checkmate/templates/redis-service.yaml b/charts/helm/checkmate/templates/redis-service.yaml new file mode 100644 index 000000000..f29fa46de --- /dev/null +++ b/charts/helm/checkmate/templates/redis-service.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Service +metadata: + name: redis +spec: + selector: + app: redis + ports: + - port: {{ .Values.redis.port }} diff --git a/charts/helm/checkmate/templates/secrets.yaml b/charts/helm/checkmate/templates/secrets.yaml new file mode 100644 index 000000000..42e7c6047 --- /dev/null +++ b/charts/helm/checkmate/templates/secrets.yaml @@ -0,0 +1,19 @@ +{{- $secrets := .Values.secrets }} + +{{- if or (not $secrets.JWT_SECRET) (eq $secrets.JWT_SECRET "change_me") }} + {{- fail "secrets.JWT_SECRET must be overridden and cannot be 'change_me'" }} +{{- end }} + +{{- if or (not $secrets.REFRESH_TOKEN_SECRET) (eq $secrets.REFRESH_TOKEN_SECRET "change_me") }} + {{- fail "secrets.REFRESH_TOKEN_SECRET must be overridden and cannot be 'change_me'" }} +{{- end }} + +apiVersion: v1 +kind: Secret +metadata: + name: checkmate-secrets +type: Opaque +stringData: +{{- range $key, $value := := $secrets }} + {{ $key }}: {{ $value | quote }} +{{- end }} \ No newline at end of file diff --git a/charts/helm/checkmate/templates/server-deployment.yaml b/charts/helm/checkmate/templates/server-deployment.yaml new file mode 100644 index 000000000..8548495dd --- /dev/null +++ b/charts/helm/checkmate/templates/server-deployment.yaml @@ -0,0 +1,30 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: server +spec: + replicas: 1 + selector: + matchLabels: + app: server + template: + metadata: + labels: + app: server + spec: + containers: + - name: server + image: {{ .Values.server.image }} + ports: + - containerPort: {{ .Values.server.port }} + envFrom: + - secretRef: + name: checkmate-secrets + volumeMounts: + - name: docker-sock + mountPath: /var/run/docker.sock + volumes: + - name: docker-sock + hostPath: + path: /var/run/docker.sock + type: Socket diff --git a/charts/helm/checkmate/templates/server-ingress.yaml b/charts/helm/checkmate/templates/server-ingress.yaml new file mode 100644 index 000000000..acf64f95f --- /dev/null +++ b/charts/helm/checkmate/templates/server-ingress.yaml @@ -0,0 +1,20 @@ +{{- if .Values.server.ingress.enabled }} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: server-ingress + annotations: + nginx.ingress.kubernetes.io/rewrite-target: / +spec: + rules: + - host: {{ .Values.server.ingress.host }} + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: server + port: + number: {{ .Values.server.port }} +{{- end }} diff --git a/charts/helm/checkmate/templates/server-service.yaml b/charts/helm/checkmate/templates/server-service.yaml new file mode 100644 index 000000000..64494ff90 --- /dev/null +++ b/charts/helm/checkmate/templates/server-service.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Service +metadata: + name: server +spec: + selector: + app: server + ports: + - port: {{ .Values.server.port }} diff --git a/charts/helm/checkmate/values.yaml b/charts/helm/checkmate/values.yaml new file mode 100644 index 000000000..79c77a49e --- /dev/null +++ b/charts/helm/checkmate/values.yaml @@ -0,0 +1,41 @@ +client: + image: ghcr.io/bluewave-labs/checkmate-client:v2.3 + port: 80 + ingress: + enabled: true + host: change_me + +server: + image: ghcr.io/bluewave-labs/checkmate-backend:v2.3 + port: 52345 + protocol: change_me + ingress: + enabled: true + host: change_me + +redis: + image: redis:7.2 + port: 6379 + +mongodb: + image: mongo:7.0 + port: 27017 + +secrets: + JWT_SECRET: change_me + REFRESH_TOKEN_SECRET: change_me + SYSTEM_EMAIL_ADDRESS: test@example.com + SYSTEM_EMAIL_PASSWORD: change_me + SYSTEM_EMAIL_HOST: smtp.example.com + SYSTEM_EMAIL_PORT: "587" + PAGESPEED_API_KEY: change_me + DB_CONNECTION_STRING: mongodb://mongodb:27017/uptime_db + REDIS_HOST: redis + REDIS_PORT: "6379" + DB_TYPE: MongoDB + TOKEN_TTL: 99d + REFRESH_TOKEN_TTL: 99d + +persistence: + mongodbSize: 5Gi + redisSize: 1Gi \ No newline at end of file