diff --git a/argocd-apps/tasko.yaml b/argocd-apps/tasko.yaml new file mode 100644 index 0000000..f1fb436 --- /dev/null +++ b/argocd-apps/tasko.yaml @@ -0,0 +1,21 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: tasko + namespace: argocd +spec: + project: my-apps + source: + repoURL: https://git.dvirlabs.com/dvirlabs/my-apps.git + targetRevision: HEAD + path: charts/tasko-chart + helm: + valueFiles: + - ../../manifests/tasko/values.yaml + destination: + server: https://kubernetes.default.svc + namespace: my-apps + syncPolicy: + automated: + prune: true + selfHeal: true diff --git a/charts/tasko-chart/README.md b/charts/tasko-chart/README.md new file mode 100644 index 0000000..2e753a5 --- /dev/null +++ b/charts/tasko-chart/README.md @@ -0,0 +1,228 @@ +# Tasko Helm Chart + +Kubernetes Helm chart for deploying Tasko task management application. + +## Architecture + +- **Frontend**: React application served by Nginx + - URL: https://tasko.dvirlabs.com + - Port: 80 + +- **Backend**: FastAPI Python application + - URL: https://api-tasko.dvirlabs.com + - Port: 8001 + +- **Database**: PostgreSQL + - Managed by Helm subchart + +## Prerequisites + +- Kubernetes cluster (1.19+) +- Helm 3.0+ +- kubectl configured +- Nginx Ingress Controller installed +- cert-manager installed (for automatic TLS certificates) + +## Building Docker Images + +### Frontend +```bash +cd frontend +docker build -t tasko-frontend:latest . +docker tag tasko-frontend:latest /tasko-frontend:latest +docker push /tasko-frontend:latest +``` + +### Backend +```bash +cd backend +docker build -t tasko-backend:latest . +docker tag tasko-backend:latest /tasko-backend:latest +docker push /tasko-backend:latest +``` + +## Installation + +### Quick Install with Default Values + +```bash +helm install tasko ./helm/tasko +``` + +### Install with Custom Values + +```bash +helm install tasko ./helm/tasko -f custom-values.yaml +``` + +### Install with Custom Image Registry + +```bash +helm install tasko ./helm/tasko \ + --set frontend.image.repository=/tasko-frontend \ + --set backend.image.repository=/tasko-backend +``` + +## Configuration + +### Key Configuration Options + +| Parameter | Description | Default | +|-----------|-------------|---------| +| `frontend.image.repository` | Frontend image repository | `tasko-frontend` | +| `frontend.image.tag` | Frontend image tag | `latest` | +| `backend.image.repository` | Backend image repository | `tasko-backend` | +| `backend.image.tag` | Backend image tag | `latest` | +| `frontend.ingress.hosts[0].host` | Frontend hostname | `tasko.dvirlabs.com` | +| `backend.ingress.hosts[0].host` | Backend hostname | `api-tasko.dvirlabs.com` | +| `postgresql.enabled` | Enable PostgreSQL subchart | `true` | +| `postgresql.auth.username` | PostgreSQL username | `tasko_user` | +| `postgresql.auth.password` | PostgreSQL password | `tasko_password` | +| `postgresql.auth.database` | PostgreSQL database name | `tasko_db` | + +### Custom Values Example + +Create a `custom-values.yaml` file: + +```yaml +frontend: + image: + repository: myregistry.io/tasko-frontend + tag: "1.0.0" + + ingress: + hosts: + - host: tasko.mydomain.com + paths: + - path: / + pathType: Prefix + tls: + - secretName: tasko-frontend-tls + hosts: + - tasko.mydomain.com + +backend: + image: + repository: myregistry.io/tasko-backend + tag: "1.0.0" + + ingress: + hosts: + - host: api-tasko.mydomain.com + paths: + - path: / + pathType: Prefix + tls: + - secretName: tasko-backend-tls + hosts: + - api-tasko.mydomain.com + +postgresql: + auth: + password: "your-secure-password" +``` + +## Upgrading + +```bash +helm upgrade tasko ./helm/tasko -f custom-values.yaml +``` + +## Uninstalling + +```bash +helm uninstall tasko +``` + +## DNS Configuration + +Make sure to configure your DNS to point to your Kubernetes cluster's ingress: + +``` +tasko.dvirlabs.com A/CNAME +api-tasko.dvirlabs.com A/CNAME +``` + +## TLS Certificates + +The chart is configured to use cert-manager with Let's Encrypt for automatic TLS certificate provisioning. Make sure you have: + +1. cert-manager installed in your cluster +2. A ClusterIssuer named `letsencrypt-prod` configured + +Example ClusterIssuer: + +```yaml +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: letsencrypt-prod +spec: + acme: + server: https://acme-v02.api.letsencrypt.org/directory + email: your-email@example.com + privateKeySecretRef: + name: letsencrypt-prod + solvers: + - http01: + ingress: + class: nginx +``` + +## Troubleshooting + +### Check Pod Status +```bash +kubectl get pods -l app.kubernetes.io/name=tasko +``` + +### View Logs +```bash +# Frontend logs +kubectl logs -l app.kubernetes.io/component=frontend + +# Backend logs +kubectl logs -l app.kubernetes.io/component=backend + +# PostgreSQL logs +kubectl logs -l app.kubernetes.io/name=postgresql +``` + +### Check Ingress +```bash +kubectl get ingress +kubectl describe ingress tasko-frontend +kubectl describe ingress tasko-backend +``` + +### Database Connection Issues +```bash +# Check if PostgreSQL is running +kubectl get pods -l app.kubernetes.io/name=postgresql + +# Test database connection from backend pod +kubectl exec -it -- psql $DATABASE_URL -c "SELECT 1" +``` + +## CORS Configuration + +The backend ingress is pre-configured with CORS headers to allow requests from the frontend domain. The configuration includes: + +- `nginx.ingress.kubernetes.io/cors-allow-origin: "https://tasko.dvirlabs.com"` +- `nginx.ingress.kubernetes.io/enable-cors: "true"` + +If you change the frontend domain, update the CORS configuration in `values.yaml`. + +## Production Considerations + +1. **Secrets Management**: Consider using external secret management (e.g., Sealed Secrets, External Secrets Operator) +2. **Database Backups**: Set up regular PostgreSQL backups +3. **Monitoring**: Add Prometheus/Grafana for monitoring +4. **Scaling**: Adjust `replicaCount` for horizontal scaling +5. **Resource Limits**: Tune resource requests/limits based on your workload +6. **Image Security**: Scan Docker images for vulnerabilities +7. **Network Policies**: Implement network policies for additional security + +## Support + +For issues and questions, please refer to the project repository. diff --git a/charts/tasko-chart/tasko/Chart.yaml b/charts/tasko-chart/tasko/Chart.yaml new file mode 100644 index 0000000..ebda231 --- /dev/null +++ b/charts/tasko-chart/tasko/Chart.yaml @@ -0,0 +1,12 @@ +apiVersion: v2 +name: tasko +description: A Helm chart for Tasko - Modern Task Management Application +type: application +version: 1.0.0 +appVersion: "1.0.0" +keywords: + - tasko + - task-management + - productivity +maintainers: + - name: dvir diff --git a/charts/tasko-chart/tasko/templates/NOTES.txt b/charts/tasko-chart/tasko/templates/NOTES.txt new file mode 100644 index 0000000..9f9ca7e --- /dev/null +++ b/charts/tasko-chart/tasko/templates/NOTES.txt @@ -0,0 +1,22 @@ +1. Get the frontend application URL by running these commands: +{{- if .Values.frontend.ingress.enabled }} + https://{{ (index .Values.frontend.ingress.hosts 0).host }} +{{- else if contains "NodePort" .Values.frontend.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "tasko.fullname" . }}-frontend) + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo http://$NODE_IP:$NODE_PORT +{{- else if contains "LoadBalancer" .Values.frontend.service.type }} + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "tasko.fullname" . }}-frontend' + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "tasko.fullname" . }}-frontend --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") + echo http://$SERVICE_IP:{{ .Values.frontend.service.port }} +{{- else if contains "ClusterIP" .Values.frontend.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "tasko.name" . }},app.kubernetes.io/instance={{ .Release.Name }},app.kubernetes.io/component=frontend" -o jsonpath="{.items[0].metadata.name}") + echo "Visit http://127.0.0.1:8080 to use your application" + kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:80 +{{- end }} + +2. Get the backend API URL by running these commands: +{{- if .Values.backend.ingress.enabled }} + https://{{ (index .Values.backend.ingress.hosts 0).host }} +{{- end }} diff --git a/charts/tasko-chart/tasko/templates/_helpers.tpl b/charts/tasko-chart/tasko/templates/_helpers.tpl new file mode 100644 index 0000000..e017b94 --- /dev/null +++ b/charts/tasko-chart/tasko/templates/_helpers.tpl @@ -0,0 +1,60 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "tasko.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +*/}} +{{- define "tasko.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 "tasko.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "tasko.labels" -}} +helm.sh/chart: {{ include "tasko.chart" . }} +{{ include "tasko.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "tasko.selectorLabels" -}} +app.kubernetes.io/name: {{ include "tasko.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "tasko.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "tasko.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/charts/tasko-chart/tasko/templates/backend-deployment.yaml b/charts/tasko-chart/tasko/templates/backend-deployment.yaml new file mode 100644 index 0000000..b738764 --- /dev/null +++ b/charts/tasko-chart/tasko/templates/backend-deployment.yaml @@ -0,0 +1,72 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "tasko.fullname" . }}-backend + labels: + {{- include "tasko.labels" . | nindent 4 }} + app.kubernetes.io/component: backend +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + {{- include "tasko.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: backend + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "tasko.selectorLabels" . | nindent 8 }} + app.kubernetes.io/component: backend + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "tasko.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + initContainers: + - name: wait-for-postgres + image: busybox:1.35 + command: ['sh', '-c', 'until nc -z {{ include "tasko.fullname" . }}-postgresql 5432; do echo waiting for postgres; sleep 2; done;'] + containers: + - name: backend + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.backend.image.repository }}:{{ .Values.backend.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.backend.image.pullPolicy }} + ports: + - name: http + containerPort: {{ .Values.backend.service.targetPort }} + protocol: TCP + env: + {{- toYaml .Values.backend.env | nindent 8 }} + livenessProbe: + httpGet: + path: / + port: http + initialDelaySeconds: 30 + periodSeconds: 10 + readinessProbe: + httpGet: + path: / + port: http + initialDelaySeconds: 10 + periodSeconds: 5 + resources: + {{- toYaml .Values.backend.resources | nindent 12 }} + {{- 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/tasko-chart/tasko/templates/backend-ingress.yaml b/charts/tasko-chart/tasko/templates/backend-ingress.yaml new file mode 100644 index 0000000..08fe558 --- /dev/null +++ b/charts/tasko-chart/tasko/templates/backend-ingress.yaml @@ -0,0 +1,42 @@ +{{- if .Values.backend.ingress.enabled -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "tasko.fullname" . }}-backend + labels: + {{- include "tasko.labels" . | nindent 4 }} + app.kubernetes.io/component: backend + {{- with .Values.backend.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if .Values.backend.ingress.className }} + ingressClassName: {{ .Values.backend.ingress.className }} + {{- end }} + {{- if .Values.backend.ingress.tls }} + tls: + {{- range .Values.backend.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} + rules: + {{- range .Values.backend.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range .paths }} + - path: {{ .path }} + pathType: {{ .pathType }} + backend: + service: + name: {{ include "tasko.fullname" $ }}-backend + port: + number: {{ $.Values.backend.service.port }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/tasko-chart/tasko/templates/backend-service.yaml b/charts/tasko-chart/tasko/templates/backend-service.yaml new file mode 100644 index 0000000..0f7ecae --- /dev/null +++ b/charts/tasko-chart/tasko/templates/backend-service.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "tasko.fullname" . }}-backend + labels: + {{- include "tasko.labels" . | nindent 4 }} + app.kubernetes.io/component: backend +spec: + type: {{ .Values.backend.service.type }} + ports: + - port: {{ .Values.backend.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + {{- include "tasko.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: backend diff --git a/charts/tasko-chart/tasko/templates/frontend-deployment.yaml b/charts/tasko-chart/tasko/templates/frontend-deployment.yaml new file mode 100644 index 0000000..528ebcc --- /dev/null +++ b/charts/tasko-chart/tasko/templates/frontend-deployment.yaml @@ -0,0 +1,68 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "tasko.fullname" . }}-frontend + labels: + {{- include "tasko.labels" . | nindent 4 }} + app.kubernetes.io/component: frontend +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + {{- include "tasko.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: frontend + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "tasko.selectorLabels" . | nindent 8 }} + app.kubernetes.io/component: frontend + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "tasko.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: frontend + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.frontend.image.repository }}:{{ .Values.frontend.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.frontend.image.pullPolicy }} + ports: + - name: http + containerPort: {{ .Values.frontend.service.targetPort }} + protocol: TCP + env: + {{- toYaml .Values.frontend.env | nindent 8 }} + livenessProbe: + httpGet: + path: / + port: http + initialDelaySeconds: 30 + periodSeconds: 10 + readinessProbe: + httpGet: + path: / + port: http + initialDelaySeconds: 10 + periodSeconds: 5 + resources: + {{- toYaml .Values.frontend.resources | nindent 12 }} + {{- 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/tasko-chart/tasko/templates/frontend-ingress.yaml b/charts/tasko-chart/tasko/templates/frontend-ingress.yaml new file mode 100644 index 0000000..675fb17 --- /dev/null +++ b/charts/tasko-chart/tasko/templates/frontend-ingress.yaml @@ -0,0 +1,42 @@ +{{- if .Values.frontend.ingress.enabled -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "tasko.fullname" . }}-frontend + labels: + {{- include "tasko.labels" . | nindent 4 }} + app.kubernetes.io/component: frontend + {{- with .Values.frontend.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if .Values.frontend.ingress.className }} + ingressClassName: {{ .Values.frontend.ingress.className }} + {{- end }} + {{- if .Values.frontend.ingress.tls }} + tls: + {{- range .Values.frontend.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} + rules: + {{- range .Values.frontend.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range .paths }} + - path: {{ .path }} + pathType: {{ .pathType }} + backend: + service: + name: {{ include "tasko.fullname" $ }}-frontend + port: + number: {{ $.Values.frontend.service.port }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/tasko-chart/tasko/templates/frontend-service.yaml b/charts/tasko-chart/tasko/templates/frontend-service.yaml new file mode 100644 index 0000000..b29779c --- /dev/null +++ b/charts/tasko-chart/tasko/templates/frontend-service.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "tasko.fullname" . }}-frontend + labels: + {{- include "tasko.labels" . | nindent 4 }} + app.kubernetes.io/component: frontend +spec: + type: {{ .Values.frontend.service.type }} + ports: + - port: {{ .Values.frontend.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + {{- include "tasko.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: frontend diff --git a/charts/tasko-chart/tasko/templates/secret.yaml b/charts/tasko-chart/tasko/templates/secret.yaml new file mode 100644 index 0000000..c72865d --- /dev/null +++ b/charts/tasko-chart/tasko/templates/secret.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Secret +metadata: + name: tasko-secrets + labels: + {{- include "tasko.labels" . | nindent 4 }} +type: Opaque +stringData: + database-url: "postgresql://{{ .Values.postgresql.auth.username }}:{{ .Values.postgresql.auth.password }}@{{ include "tasko.fullname" . }}-postgresql:5432/{{ .Values.postgresql.auth.database }}" diff --git a/charts/tasko-chart/tasko/templates/serviceaccount.yaml b/charts/tasko-chart/tasko/templates/serviceaccount.yaml new file mode 100644 index 0000000..cf6a127 --- /dev/null +++ b/charts/tasko-chart/tasko/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "tasko.serviceAccountName" . }} + labels: + {{- include "tasko.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/tasko-chart/tasko/values.yaml b/charts/tasko-chart/tasko/values.yaml new file mode 100644 index 0000000..d51acf0 --- /dev/null +++ b/charts/tasko-chart/tasko/values.yaml @@ -0,0 +1,125 @@ +replicaCount: 1 + +frontend: + image: + repository: tasko-frontend + pullPolicy: IfNotPresent + tag: "latest" + + service: + type: ClusterIP + port: 80 + targetPort: 80 + + ingress: + enabled: true + className: "nginx" + annotations: + cert-manager.io/cluster-issuer: "letsencrypt-prod" + nginx.ingress.kubernetes.io/ssl-redirect: "true" + hosts: + - host: tasko.dvirlabs.com + paths: + - path: / + pathType: Prefix + tls: + - secretName: tasko-frontend-tls + hosts: + - tasko.dvirlabs.com + + resources: + limits: + cpu: 200m + memory: 256Mi + requests: + cpu: 100m + memory: 128Mi + + env: + - name: VITE_API_URL + value: "https://api-tasko.dvirlabs.com" + +backend: + image: + repository: tasko-backend + pullPolicy: IfNotPresent + tag: "latest" + + service: + type: ClusterIP + port: 8001 + targetPort: 8001 + + ingress: + enabled: true + className: "nginx" + annotations: + cert-manager.io/cluster-issuer: "letsencrypt-prod" + nginx.ingress.kubernetes.io/ssl-redirect: "true" + nginx.ingress.kubernetes.io/cors-allow-origin: "https://tasko.dvirlabs.com" + nginx.ingress.kubernetes.io/enable-cors: "true" + nginx.ingress.kubernetes.io/cors-allow-methods: "GET, POST, PUT, DELETE, OPTIONS" + nginx.ingress.kubernetes.io/cors-allow-headers: "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization" + hosts: + - host: api-tasko.dvirlabs.com + paths: + - path: / + pathType: Prefix + tls: + - secretName: tasko-backend-tls + hosts: + - api-tasko.dvirlabs.com + + resources: + limits: + cpu: 500m + memory: 512Mi + requests: + cpu: 250m + memory: 256Mi + + env: + - name: DATABASE_URL + valueFrom: + secretKeyRef: + name: tasko-secrets + key: database-url + +postgresql: + enabled: true + auth: + username: tasko_user + password: tasko_password + database: tasko_db + primary: + persistence: + enabled: true + size: 8Gi + resources: + limits: + cpu: 500m + memory: 512Mi + requests: + cpu: 250m + memory: 256Mi + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + create: true + annotations: {} + name: "" + +podAnnotations: {} + +podSecurityContext: {} + +securityContext: {} + +nodeSelector: {} + +tolerations: [] + +affinity: {} diff --git a/manifests/tasko/cname.yaml b/manifests/tasko/cname.yaml new file mode 100644 index 0000000..0c9ab0b --- /dev/null +++ b/manifests/tasko/cname.yaml @@ -0,0 +1,2 @@ +enabled: true +hostname: tasko.dvirlabs.com \ No newline at end of file diff --git a/manifests/tasko/values.yaml b/manifests/tasko/values.yaml new file mode 100644 index 0000000..a5553ff --- /dev/null +++ b/manifests/tasko/values.yaml @@ -0,0 +1,113 @@ +global: + namespace: my-apps + imagePullSecrets: [] + +# Backend configuration +backend: + name: backend + replicaCount: 1 + image: + repository: harbor.dvirlabs.com/my-apps/tasko-backend + pullPolicy: Always + tag: "latest" + + service: + type: ClusterIP + port: 8001 + targetPort: 8001 + + resources: + requests: + cpu: 100m + memory: 128Mi + limits: + cpu: 500m + memory: 512Mi + + env: + PYTHONUNBUFFERED: "1" + + ingress: + enabled: true + className: "traefik" + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.tls: "true" + cert-manager.io/cluster-issuer: "letsencrypt-prod" + hosts: + - host: api-tasko.dvirlabs.com + paths: + - path: / + pathType: Prefix + tls: + - secretName: api-tasko-tls + hosts: + - api-tasko.dvirlabs.com + +# Frontend configuration +frontend: + name: frontend + replicaCount: 1 + image: + repository: harbor.dvirlabs.com/my-apps/tasko-frontend + pullPolicy: Always + tag: "latest" + + service: + type: ClusterIP + port: 80 + targetPort: 80 + + env: + VITE_API_URL: "https://api-tasko.dvirlabs.com" + + resources: + requests: + cpu: 50m + memory: 64Mi + limits: + cpu: 200m + memory: 256Mi + + ingress: + enabled: true + className: "traefik" + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.tls: "true" + cert-manager.io/cluster-issuer: "letsencrypt-prod" + hosts: + - host: tasko.dvirlabs.com + paths: + - path: / + pathType: Prefix + tls: + - secretName: tasko-tls + hosts: + - tasko.dvirlabs.com + +# PostgreSQL configuration +postgres: + name: db + image: + repository: postgres + tag: "16-alpine" + pullPolicy: IfNotPresent + + user: tasko_user + password: tasko_password + database: tasko_db + port: 5432 + + persistence: + enabled: true + size: 8Gi + storageClass: "" + + resources: + requests: + cpu: 100m + memory: 128Mi + limits: + cpu: 500m + memory: 512Mi