diff --git a/GEMINI.md b/GEMINI.md new file mode 100644 index 0000000..b3eb1c2 --- /dev/null +++ b/GEMINI.md @@ -0,0 +1,84 @@ +# Project: Memelord Jake + +## Project Overview + +This project defines the Kubernetes deployment and configuration for a Django application named "memelord". The application is designed for cloud-native environments, leveraging Kubernetes for orchestration, PostgreSQL as its primary database, Redis (DragonflyDB) for caching/sessions, and an S3-compatible object storage (MinIO/Onyxia S3) for media files. Authentication is handled via OpenID Connect (OIDC) using a service called "Passmower". The setup also includes Grafana for monitoring, which is similarly integrated with OIDC. + +## Architecture + +The project's architecture is built around several interconnected services deployed within a Kubernetes cluster: + +* **Memelord Application:** A Django application running in a Kubernetes Deployment, serving on port 8000. It uses a Docker image (`ghcr.io/l4rm4nd/memelord:latest`). +* **Database:** A PostgreSQL database managed by CloudNativePG (`postgresql.cnpg.io`) is used for persistent data storage. +* **Cache/Session Store:** Redis, deployed via DragonflyDB (`dragonflydb.io`), serves as a caching layer and for Django session management. +* **Object Storage:** An S3-compatible service (MinIO, managed by Onyxia S3 custom resources) is used for storing application media, configured with policies and user credentials. +* **Authentication:** OpenID Connect (OIDC) is integrated for user authentication, with client configurations defined for both the "memelord" application and Grafana. +* **Monitoring:** Grafana is deployed as a StatefulSet, configured with Prometheus and Loki datasources, and protected by OIDC authentication. +* **Networking:** Kubernetes Services expose the applications internally, while Ingress resources (using Traefik) provide external access with TLS certificates managed by cert-manager. + +## Key Configuration Files + +The project relies heavily on Kubernetes YAML manifests for its configuration and deployment: + +* **`app.yaml`**: Defines the main Kubernetes `Deployment` for the `memelord` application. It specifies the Docker image, container ports, and critical environment variables for database, Redis, S3, and OIDC connectivity. It also mounts a `settings.py` from a ConfigMap. +* **`config.yaml`**: Contains a Kubernetes `ConfigMap` named `settings`, which provides the `settings.py` file for the Django application. This file dynamically configures various aspects of the Django project based on environment variables, including database backend, Redis caching, security headers (CSP, HSTS), logging, and different cloud storage providers (S3, Azure, GCS, SFTP, Dropbox). It also integrates `mozilla_django_oidc` if OIDC is enabled. +* **`deployment.yaml`**: A comprehensive manifest defining the backing services for the `memelord` application. This includes: + * `StringSecret` and `Dragonfly` for Redis (memelord-jake-redis). + * `StringSecret`, `Cluster`, and `Database` for PostgreSQL (memelord-jake-database). + * `Policy`, `S3User`, and `Bucket` for S3 object storage (memelord-jake). + * A Kubernetes `Service` and `Ingress` for the `memelord` application, including `Certificate` setup for TLS. +* **`grafana.yaml`**: Defines the Kubernetes resources for deploying and configuring Grafana. This includes: + * A `Namespace` (`memelord-jake`). + * `ConfigMap` for Grafana's Prometheus and Loki datasources. + * A `StatefulSet` for Grafana, configuring it for SQLite storage and integrating Generic OAuth for OIDC authentication. + * A Kubernetes `Service`, `Certificate`, and `Ingress` for Grafana. + * An `OIDCClient` custom resource for Grafana's OIDC setup. +* **`oidc.yaml`**: Defines an `OIDCClient` custom resource specifically for the `memelord-jake` application, detailing its OIDC redirect URIs, grant types, response types, and available scopes for authentication. + +## Deployment + +This project is designed to be deployed to a Kubernetes cluster. The entire environment, including the application, database, Redis, S3, and Grafana, can be deployed by applying these YAML manifests. + +To deploy the application and its dependencies to a Kubernetes cluster, you would typically use `kubectl apply -f` for each of the YAML files in the directory. + +```bash +kubectl apply -f app.yaml +kubectl apply -f config.yaml +kubectl apply -f deployment.yaml +kubectl apply -f grafana.yaml +kubectl apply -f oidc.yaml +``` + +**Note:** The `.yaml` files define custom resources that require specific Kubernetes operators (e.g., CloudNativePG, DragonflyDB, Onyxia S3, cert-manager, Traefik, Codemowers Cloud OIDC) to be installed in the cluster. + +## Development Notes + +The Django application is heavily configured via environment variables, as seen in `config.yaml` (`settings.py`). This allows for flexible configuration depending on the deployment environment (development, staging, production). Secrets (like database passwords and API keys) are injected into the application containers via Kubernetes `Secret` resources, often generated by `StringSecret` custom resources for enhanced security. + +The `settings.py` includes robust security practices such as Content Security Policy (CSP), HSTS, and secure cookie settings. It also supports various file storage backends, making it adaptable to different cloud providers. + +## Monitoring + +Grafana is included in the deployment to provide monitoring capabilities. It is pre-configured with Prometheus and Loki datasources, allowing for the visualization of metrics and logs from the deployed services. Access to Grafana is secured via OIDC. + +## Training Context (Koolitus 2026) + +This project was developed as part of a Kubernetes training (Koolitus 2026). The following tasks and configurations were implemented based on the training requirements: + +### Tuesday Tasks +* **ConfigMap Integration:** Mounted `settings.py` from a `ConfigMap` into the Memelord deployment at `/opt/app/myproject/settings.py` using `subPath` to avoid overwriting the entire directory. +* **S3 Configuration:** Set `AWS_S3_ADDRESSING_STYLE = 'path'` in Django settings. +* **ArgoCD:** Configured ArgoCD to track the repository, deploying into the `memelord-jake` namespace with a destination cluster at `https://10.254.10.31:6443`. +* **Grafana Setup:** + * Deployed as a `StatefulSet` using the `sqlite` storage class (5Gi volume). + * Configured Ingress with TLS (`cert-manager`). + * Integrated OIDC authentication via Passmower. + * Provisioned Prometheus (`http://prometheus-operated.monitoring.svc.cluster.local:9090`) and Loki (`http://loki.monitoring.svc.cluster.local:3100`) datasources. + +### Wednesday Tasks +* **Architectural Review:** Discussion on `Deployment` vs `StatefulSet` vs `DaemonSet`. +* **Observability:** Implementation of Prometheus metrics and Loki logs. +* **Declarative Grafana:** Configuring datasources via Kubernetes manifests (as seen in `grafana.yaml`). + +### LLM Integration (Optional Context) +The training environment included access to LLMs via `https://llama-api.ee-lte-1.codemowers.io` and a WebUI at `https://llm.ee-lte-1.codemowers.io/`. A sample `StatefulSet` for `open-webui` was provided as a challenge to integrate SSO and PostgreSQL. diff --git a/grafana.yaml b/grafana.yaml index 9373da7..841ce41 100644 --- a/grafana.yaml +++ b/grafana.yaml @@ -175,6 +175,7 @@ metadata: annotations: traefik.ingress.kubernetes.io/router.entrypoints: websecure spec: + ingressClassName: traefik rules: - host: grafana-jake.ee-lte-1.codemowers.io http: