Garden.io is a development and testing platform for Kubernetes-based applications. It builds a dependency graph — called the stack graph — of your services, tests, and build steps, then orchestrates them intelligently: only rebuilding what changed, reusing remote cache results, and running tests against live containers instead of mocks. Teams use Garden to bring their full production topology to a local or ephemeral CI environment.
But Garden environments are complex distributed systems. The stack graph might have dozens of nodes, remote cluster connections, registry pushes, and live test suites — any of which can fail silently. This tutorial shows you how to monitor your Garden.io environments with Vigilmon so failures surface as incidents before they become blocked developers.
Why Garden environments need external monitoring
Garden orchestrates your services so you can develop and test against a realistic stack. That orchestration creates several distinct failure modes that are invisible without external monitoring:
- Stack graph resolution failure — a missing dependency, a bad
garden.yml, or an unavailable module causes Garden to fail silently during sync; services appear deployed but are running stale versions - Remote cache misses turning into build failures — Garden uses a shared build cache (local or in-cluster); when the cache backend becomes unavailable, builds fall back to local and may fail due to resource constraints
- Container runtime connectivity loss — Garden proxies traffic from your local machine to remote containers; a network partition or cluster credential rotation breaks the proxy without visible error
- Deploy task failures in the graph — a single failed deploy task blocks all downstream services; if your workflow doesn't surface task exit codes clearly, the failure is silent
- Environment sync drift — a developer modifies cluster state outside Garden; the next
garden devsession thinks everything is up-to-date but the running containers don't match the current code
External HTTP monitoring from Vigilmon adds a ground-truth layer: it reaches into your Garden-managed service's HTTP endpoints from outside the cluster and verifies they actually respond. No amount of garden get status can substitute for a probe that validates real connectivity from multiple global vantage points.
What you'll need
- A project using Garden.io (v0.13+ or Bonsai/Acorn)
- A Kubernetes cluster (local like kind/k3s, or remote like GKE/EKS)
- Services that expose HTTP endpoints
- A free Vigilmon account — sign up in under 30 seconds
Step 1: Add a health action to your Garden config
Garden defines builds, deploys, tests, and runs as actions in garden.yml. Add a health endpoint to your service container and expose it:
# garden.yml (service module)
kind: Deploy
name: api-service
type: kubernetes
description: Main API service
spec:
files:
- manifests/api-deployment.yaml
- manifests/api-service.yaml
defaultTarget:
kind: Deployment
name: api-service
Your Kubernetes manifests should include a /health or /healthz endpoint in the container:
# manifests/api-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-service
spec:
replicas: 2
selector:
matchLabels:
app: api-service
template:
metadata:
labels:
app: api-service
spec:
containers:
- name: api-service
image: ${var.registry}/api-service:${actions.build.api-service.outputs.deploymentImageId}
ports:
- containerPort: 3000
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 10
periodSeconds: 20
readinessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 5
periodSeconds: 10
env:
- name: NODE_ENV
value: ${var.environment}
The ${actions.build.api-service.outputs.deploymentImageId} variable is Garden's way of passing the freshly-built image digest into the deployment manifest — this is how Garden ensures deploys always use the latest build artifact.
Step 2: Add a Garden run action for health verification
Garden's Run action type executes arbitrary commands inside a container in the cluster. Add a run action that verifies your service is reachable from within the cluster right after deploy:
# garden.yml addition
kind: Run
name: health-check
type: container
description: Verify API service health after deploy
dependencies:
- deploy.api-service
spec:
image: curlimages/curl:latest
command:
- sh
- -c
- |
echo "Checking API health..."
curl -sf http://api-service:3000/health \
--max-time 10 \
--retry 3 \
--retry-delay 2 \
-o /dev/null \
-w "HTTP %{http_code} in %{time_total}s\n"
echo "Health check passed"
Run this action with:
garden run health-check
Garden will deploy api-service first (respecting the dependency), then execute the curl in-cluster. If this passes, you know the deploy succeeded and the service is responding internally.
Step 3: Expose your service externally
For Vigilmon to probe from outside the cluster, your service needs an external address. Add an Ingress or use Garden's port-forward capability for development:
# manifests/api-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-service
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
tls:
- hosts:
- api.yourdomain.com
secretName: api-tls
rules:
- host: api.yourdomain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-service
port:
number: 3000
For ephemeral Garden preview environments in CI, use a dynamic hostname based on branch:
# garden.yml project-level variables
variables:
hostname: ${environment.name}-api.preview.yourdomain.com
# manifests/api-ingress.yaml with dynamic hostname
spec:
rules:
- host: ${var.hostname}
Step 4: Set up Vigilmon monitoring
Log in to Vigilmon and add an HTTP monitor for each Garden environment you want to watch:
Production environment:
- Click New Monitor → HTTP(S)
- URL:
https://api.yourdomain.com/health - Interval: 1 minute
- Response validation: status
200, body contains"status":"ok" - Regions: at least 3 (US East, EU West, Asia Pacific)
- Click Save
Preview/staging environments:
For ephemeral environments, create monitors programmatically using the Vigilmon API after each Garden deploy in CI:
# In your CI pipeline, after garden deploy --env=preview
HOSTNAME="${BRANCH_NAME}-api.preview.yourdomain.com"
curl -X POST "https://api.vigilmon.online/v1/monitors" \
-H "Authorization: Bearer $VIGILMON_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Preview: '"$BRANCH_NAME"'",
"type": "http",
"url": "https://'"$HOSTNAME"'/health",
"interval": 60,
"regions": ["us-east", "eu-west"],
"tags": ["preview", "branch:'"$BRANCH_NAME"'"]
}'
This creates a short-lived monitor for each PR environment. Delete it when the PR closes:
# After PR merge/close
MONITOR_ID=$(curl -s "https://api.vigilmon.online/v1/monitors?tag=branch:$BRANCH_NAME" \
-H "Authorization: Bearer $VIGILMON_API_KEY" | jq -r '.monitors[0].id')
curl -X DELETE "https://api.vigilmon.online/v1/monitors/$MONITOR_ID" \
-H "Authorization: Bearer $VIGILMON_API_KEY"
Step 5: Monitor Garden task execution in CI
Garden outputs structured exit codes and JSON status. Wrap your CI Garden commands to send success/failure signals to Vigilmon:
#!/bin/bash
# ci-garden-deploy.sh
set -euo pipefail
VIGILMON_URL="https://api.vigilmon.online/v1/monitors/$VIGILMON_MONITOR_ID"
# Run garden deploy and capture exit code
if garden deploy --env=staging --log-level=info; then
echo "Garden deploy succeeded"
STATUS="up"
else
echo "Garden deploy failed"
STATUS="down"
fi
# Send status update to Vigilmon
curl -s -X POST "${VIGILMON_URL}/status" \
-H "Authorization: Bearer $VIGILMON_API_KEY" \
-H "Content-Type: application/json" \
-d '{"status":"'"$STATUS"'","note":"Garden deploy '"$STATUS"' for '"$GITHUB_SHA"'"}'
Step 6: Configure alerts
In Vigilmon, configure notifications for your Garden monitors:
- Email for the on-call engineer
- Slack to
#deploymentswith the Garden environment name in the message - Webhook back to your Garden project's CI system to trigger a re-deploy on transient failures
Set the confirmation threshold to 2 consecutive failures to avoid alerts from Garden's brief startup window when containers initialize.
What you're now monitoring
| Failure | How Vigilmon catches it |
|---|---|
| Stack graph resolution fails; deploy is skipped | HTTP probe detects stale/missing service |
| Remote build cache unavailable; deploy uses broken artifact | Container starts but /health returns 5xx |
| Port-forward proxy drops; local dev loses cluster connectivity | Ingress still routes; Vigilmon detects discrepancy |
| Garden deploy task fails midway | Service partially updated; health check fails consistency checks |
| Cluster credential rotation breaks Garden sync | Running containers unaffected; Vigilmon confirms service still live while you fix credentials |
Conclusion
Garden.io eliminates the friction of developing and testing against real Kubernetes environments. But its complexity — stack graphs, remote caches, multi-action pipelines — creates failure modes that only external validation can catch. Adding Vigilmon takes minutes: expose /health from your Garden-managed services, add an Ingress for external access, and point Vigilmon at the URL. Every Garden deploy is then verified from multiple global regions, and any failure generates an alert before developers hit a dead end.
Get started with a free Vigilmon account.