Skip to content

Deployment for Observability Dashboard#1261

Open
syntaxsdev wants to merge 3 commits intomainfrom
feat/obs-dashboard
Open

Deployment for Observability Dashboard#1261
syntaxsdev wants to merge 3 commits intomainfrom
feat/obs-dashboard

Conversation

@syntaxsdev
Copy link
Copy Markdown
Contributor

@syntaxsdev syntaxsdev commented Apr 9, 2026

This PR will deploy the Observability dashboard using K8s deployment patterns.

Repo located here:
https://github.com/ambient-code/observability

Some things to note:

  • using ghcr.io temporarily for the initial deployment
  • observability dashboard is subject to change pattern

Summary by CodeRabbit

  • New Features
    • Observability dashboard deployed as a containerized service with health checks, resource limits, env-based configuration, and a ClusterIP service for internal access.
  • Chores
    • Build and push workflows updated to include the observability dashboard and to load the image into local test clusters.
  • Configuration
    • Local and production deployment overlays updated to map and pin the observability image for dev and prod environments.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 9, 2026

📝 Walkthrough

Walkthrough

Adds an observability dashboard: Makefile build/push/load targets, a Kubernetes Deployment and Service for the dashboard, and overlay image/patch entries for kind-local and production environments.

Changes

Cohort / File(s) Summary
Build configuration
Makefile
Added OBSERVABILITY_DASHBOARD_IMAGE ?= vteam_observability_dashboard:$(IMAGE_TAG), new build-observability-dashboard target, extended build-all to include it, updated push-all to tag/push the image, and updated _kind-load-images to save/load the dashboard image into kind.
Core Kubernetes manifests
components/manifests/base/core/kustomization.yaml, components/manifests/base/core/observability-dashboard-deployment.yaml
Added observability-dashboard-deployment.yaml to base resources. New Deployment observability-dashboard (1 replica) with container ghcr.io/ambient-code/observability:latest, port 8000, envFrom secret observability-dashboard-env, explicit envs (PORT=8000, DATA_SOURCE=langfuse, SYNC_INTERVAL=300), resource requests/limits, liveness/readiness probes; and a ClusterIP Service observability-dashboard-service.
Environment overlays
components/manifests/overlays/kind-local/kustomization.yaml, components/manifests/overlays/production/kustomization.yaml
kind-local: added images remap ghcr.io/ambient-code/observabilitylocalhost/observability:latest and added a patch to set imagePullPolicy for the observability-dashboard Deployment. production: added image override entries for ghcr.io/ambient-code/observability (with and without :latest) setting newName: ghcr.io/ambient-code/observability and newTag: latest.
🚥 Pre-merge checks | ✅ 4 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Title check ⚠️ Warning The title does not follow Conventional Commits format; it lacks the required 'type(scope):' prefix. Reformat the title to follow Conventional Commits: 'feat(observability): add observability dashboard deployment' or similar.
Kubernetes Resource Safety ⚠️ Warning observability-dashboard Deployment lacks pod and container security contexts, running with permissive defaults allowing root execution and privilege escalation. Add pod-level securityContext with runAsNonRoot: true and seccompProfile type, plus container-level securityContext with allowPrivilegeEscalation: false and readOnlyRootFilesystem: true.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Performance And Algorithmic Complexity ✅ Passed PR introduces only configuration and Kubernetes manifest changes with no algorithmic complexity, unbounded structures, or N+1 patterns. Fixed-size image loops (8 items) and single bounded deployment add no performance regression.
Security And Secret Handling ✅ Passed PR adds K8s manifests and Makefile entries without hardcoded secrets, new API endpoints, or auth/authz concerns.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/obs-dashboard
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch feat/obs-dashboard

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
components/manifests/base/core/observability-dashboard-deployment.yaml (1)

16-53: Resource limits present and compliant; consider adding securityContext for hardening.

Container has resource limits/requests as required, but lacks securityContext. While this is security best practice, it's consistent with other deployments in the codebase (e.g., backend-deployment.yaml also lacks it). If adopted, apply across all deployments rather than in isolation.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/manifests/base/core/observability-dashboard-deployment.yaml`
around lines 16 - 53, The container spec for the observability-dashboard
container lacks a securityContext; add a securityContext block for the
observability-dashboard container (inside the spec -> containers entry for name:
observability-dashboard) with hardened settings such as runAsNonRoot: true, a
non-zero runAsUser, allowPrivilegeEscalation: false, readOnlyRootFilesystem:
true, and dropping all capabilities (e.g., capabilities: drop: ["ALL"]); if you
decide to adopt this hardening, apply the same securityContext pattern
consistently to other deployments (e.g., backend-deployment) to avoid
inconsistent behavior across the cluster.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@components/manifests/overlays/kind-local/kustomization.yaml`:
- Around line 77-79: The image remap in kustomization.yaml is targeting
quay.io/ambient_code/vteam_observability_dashboard but the base deployment uses
ghcr.io/ambient-code/observability:latest, so the override is ineffective;
update the image transformer entry (the name/newName/newTag triple) to match the
base image name (ghcr.io/ambient-code/observability) and map it to your local
image (e.g., newName: localhost/observability and newTag: latest) so kind will
use the local image (adjust the name/newName/newTag fields in the existing
kustomization.yaml entry).

In `@components/manifests/overlays/production/kustomization.yaml`:
- Around line 98-103: The kind-local overlay imageOverride entries in
kustomization.yaml reference quay.io/ambient_code/vteam_observability_dashboard
which doesn't match the base image ghcr.io/ambient-code/observability:latest;
update the overlay so the image name being remapped matches the base (replace
quay.io/ambient_code/vteam_observability_dashboard with
ghcr.io/ambient-code/observability or change the overlay entries to use name:
ghcr.io/ambient-code/observability and newName/newTag accordingly), or
alternatively change the base deployment image to
quay.io/ambient_code/vteam_observability_dashboard so the existing override
applies; ensure the symbol names in the overlay (name:
ghcr.io/ambient-code/observability and name:
ghcr.io/ambient-code/observability:latest) exactly match the image string used
in the base manifest.

---

Nitpick comments:
In `@components/manifests/base/core/observability-dashboard-deployment.yaml`:
- Around line 16-53: The container spec for the observability-dashboard
container lacks a securityContext; add a securityContext block for the
observability-dashboard container (inside the spec -> containers entry for name:
observability-dashboard) with hardened settings such as runAsNonRoot: true, a
non-zero runAsUser, allowPrivilegeEscalation: false, readOnlyRootFilesystem:
true, and dropping all capabilities (e.g., capabilities: drop: ["ALL"]); if you
decide to adopt this hardening, apply the same securityContext pattern
consistently to other deployments (e.g., backend-deployment) to avoid
inconsistent behavior across the cluster.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 3cc9d7c1-a65d-4777-b6c8-c3c055a918ea

📥 Commits

Reviewing files that changed from the base of the PR and between 02d3d96 and 817e29d.

📒 Files selected for processing (5)
  • Makefile
  • components/manifests/base/core/kustomization.yaml
  • components/manifests/base/core/observability-dashboard-deployment.yaml
  • components/manifests/overlays/kind-local/kustomization.yaml
  • components/manifests/overlays/production/kustomization.yaml

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@components/manifests/base/core/observability-dashboard-deployment.yaml`:
- Around line 19-20: The Deployment currently references a mutable image
("image" field) ghcr.io/ambient-code/observability:latest with imagePullPolicy:
Always which makes rollouts non-deterministic; update the "image" field to a
fixed, immutable identifier (preferably a digest such as
ghcr.io/ambient-code/observability@sha256:<digest> or at minimum a fixed semver
tag) and adjust "imagePullPolicy" as appropriate (If you pin by digest or exact
tag you can keep Always or switch to IfNotPresent per your release policy).
Locate and replace the image value and confirm the imagePullPolicy setting in
this manifest so deployments use an immutable, reproducible image reference.
- Around line 16-53: The Pod/Container lacks a securityContext; update the
Deployment spec for the observability-dashboard container to enforce least
privilege by adding a pod-level securityContext (e.g., runAsNonRoot: true,
runAsUser: non-root UID, runAsGroup, fsGroup) and a container-level
securityContext on the container named observability-dashboard (set
allowPrivilegeEscalation: false, readOnlyRootFilesystem: true,
capabilities.drop: ["ALL"], and any required runAsNonRoot/runAsUser). Ensure
these fields are placed under the same spec where the containers array is
defined so the pod and container both inherit the hardened defaults.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a0ef1a0d-5468-43ac-8c4e-12865515d43d

📥 Commits

Reviewing files that changed from the base of the PR and between 817e29d and a696e38.

📒 Files selected for processing (5)
  • Makefile
  • components/manifests/base/core/kustomization.yaml
  • components/manifests/base/core/observability-dashboard-deployment.yaml
  • components/manifests/overlays/kind-local/kustomization.yaml
  • components/manifests/overlays/production/kustomization.yaml
✅ Files skipped from review due to trivial changes (2)
  • components/manifests/base/core/kustomization.yaml
  • components/manifests/overlays/production/kustomization.yaml
🚧 Files skipped from review as they are similar to previous changes (2)
  • components/manifests/overlays/kind-local/kustomization.yaml
  • Makefile

Comment on lines +16 to +53
spec:
containers:
- name: observability-dashboard
imagePullPolicy: Always
image: ghcr.io/ambient-code/observability:latest
ports:
- containerPort: 8000
name: http
envFrom:
- secretRef:
name: observability-dashboard-env
optional: true
env:
- name: PORT
value: "8000"
- name: DATA_SOURCE
value: "langfuse"
- name: SYNC_INTERVAL
value: "300"
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
livenessProbe:
httpGet:
path: /api/health
port: http
initialDelaySeconds: 15
periodSeconds: 10
readinessProbe:
httpGet:
path: /api/health
port: http
initialDelaySeconds: 10
periodSeconds: 5
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Harden pod/container security context to enforce least privilege

The Deployment runs with default security context (Line 16 onward), which permits root-leaning defaults and privilege escalation paths. Add pod/container securityContext to enforce non-root execution and filesystem hardening.

Suggested patch
 spec:
   replicas: 1
@@
   template:
@@
     spec:
+      securityContext:
+        runAsNonRoot: true
+        seccompProfile:
+          type: RuntimeDefault
       containers:
       - name: observability-dashboard
+        securityContext:
+          allowPrivilegeEscalation: false
+          readOnlyRootFilesystem: true
+          capabilities:
+            drop:
+            - ALL
         imagePullPolicy: Always
         image: ghcr.io/ambient-code/observability:latest

As per coding guidelines, "Flag only errors, security risks, or functionality-breaking problems."

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
spec:
containers:
- name: observability-dashboard
imagePullPolicy: Always
image: ghcr.io/ambient-code/observability:latest
ports:
- containerPort: 8000
name: http
envFrom:
- secretRef:
name: observability-dashboard-env
optional: true
env:
- name: PORT
value: "8000"
- name: DATA_SOURCE
value: "langfuse"
- name: SYNC_INTERVAL
value: "300"
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
livenessProbe:
httpGet:
path: /api/health
port: http
initialDelaySeconds: 15
periodSeconds: 10
readinessProbe:
httpGet:
path: /api/health
port: http
initialDelaySeconds: 10
periodSeconds: 5
spec:
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containers:
- name: observability-dashboard
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
imagePullPolicy: Always
image: ghcr.io/ambient-code/observability:latest
ports:
- containerPort: 8000
name: http
envFrom:
- secretRef:
name: observability-dashboard-env
optional: true
env:
- name: PORT
value: "8000"
- name: DATA_SOURCE
value: "langfuse"
- name: SYNC_INTERVAL
value: "300"
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
livenessProbe:
httpGet:
path: /api/health
port: http
initialDelaySeconds: 15
periodSeconds: 10
readinessProbe:
httpGet:
path: /api/health
port: http
initialDelaySeconds: 10
periodSeconds: 5
🧰 Tools
🪛 Trivy (0.69.3)

[error] 18-53: Root file system is not read-only

Container 'observability-dashboard' of Deployment 'observability-dashboard' should set 'securityContext.readOnlyRootFilesystem' to true

Rule: KSV-0014

Learn more

(IaC/Kubernetes)


[error] 18-53: Default security context configured

container observability-dashboard in default namespace is using the default security context

Rule: KSV-0118

Learn more

(IaC/Kubernetes)


[error] 16-53: Default security context configured

deployment observability-dashboard in default namespace is using the default security context, which allows root privileges

Rule: KSV-0118

Learn more

(IaC/Kubernetes)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/manifests/base/core/observability-dashboard-deployment.yaml`
around lines 16 - 53, The Pod/Container lacks a securityContext; update the
Deployment spec for the observability-dashboard container to enforce least
privilege by adding a pod-level securityContext (e.g., runAsNonRoot: true,
runAsUser: non-root UID, runAsGroup, fsGroup) and a container-level
securityContext on the container named observability-dashboard (set
allowPrivilegeEscalation: false, readOnlyRootFilesystem: true,
capabilities.drop: ["ALL"], and any required runAsNonRoot/runAsUser). Ensure
these fields are placed under the same spec where the containers array is
defined so the pod and container both inherit the hardened defaults.

Comment on lines +19 to +20
imagePullPolicy: Always
image: ghcr.io/ambient-code/observability:latest
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Avoid mutable :latest image in Deployment

Using ghcr.io/ambient-code/observability:latest (Line 20) with imagePullPolicy: Always (Line 19) makes production rollouts non-deterministic and increases supply-chain risk. Pin to an immutable digest (or at minimum a fixed version tag).

As per coding guidelines, "Flag only errors, security risks, or functionality-breaking problems."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/manifests/base/core/observability-dashboard-deployment.yaml`
around lines 19 - 20, The Deployment currently references a mutable image
("image" field) ghcr.io/ambient-code/observability:latest with imagePullPolicy:
Always which makes rollouts non-deterministic; update the "image" field to a
fixed, immutable identifier (preferably a digest such as
ghcr.io/ambient-code/observability@sha256:<digest> or at minimum a fixed semver
tag) and adjust "imagePullPolicy" as appropriate (If you pin by digest or exact
tag you can keep Always or switch to IfNotPresent per your release policy).
Locate and replace the image value and confirm the imagePullPolicy setting in
this manifest so deployments use an immutable, reproducible image reference.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant