- Blade 58.9%
- PHP 37.7%
- Dockerfile 1.6%
- Nix 0.7%
- Shell 0.5%
- Other 0.6%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .claude/skills/laravel-best-practices | ||
| app | ||
| bootstrap | ||
| config | ||
| database | ||
| docker | ||
| public | ||
| resources | ||
| routes | ||
| storage | ||
| tests | ||
| .dockerignore | ||
| .editorconfig | ||
| .env.example | ||
| .envrc | ||
| .gitattributes | ||
| .gitignore | ||
| .mcp.json | ||
| .npmrc | ||
| artisan | ||
| boost.json | ||
| bun.lock | ||
| CLAUDE.md | ||
| composer.json | ||
| composer.lock | ||
| devenv.lock | ||
| devenv.nix | ||
| devenv.yaml | ||
| Dockerfile | ||
| package.json | ||
| phpunit.xml | ||
| README.md | ||
| vite.config.js | ||
Cluster Tester
A single-page, no-auth Laravel utility for smoke-testing a Kubernetes cluster from inside a running container. It checks that a mounted storage volume, the database, the cache/Redis backend, and injected environment variables are all wired up as expected.
⚠️ There is no authentication and the environment viewer shows secrets unmasked. Keep this service internal to the cluster — do not expose it publicly.
The tools
Everything lives on /, one card per check:
| Tool | What it does |
|---|---|
| 💾 Storage | Upload a file → writes it to the local disk, reads it back, deletes it. Reports path, size, disk root. |
| 🗄️ Database | Shows live connection info (driver / host / database / server version / reachable). Button to run migrations; once migrated, a form to create records and a list of them. |
| ⚡ Cache / Redis | Writes a key to the active cache store and reads it back. |
| 🔧 Environment & Config | Dumps $_ENV and resolved config (DB host/port, disk, cache/queue/session drivers, app url/env). |
The page loads even when the database or cache is down — each tool reports its own failure inline, so you can always tell which backend is broken.
Run in Kubernetes
Build and push the image:
docker build -t <your-registry>/cluster-tester:latest .
docker push <your-registry>/cluster-tester:latest
The container serves plain HTTP on :8080 (point a Service at it; use GET / for liveness/
readiness probes). Configure everything through environment variables — inject the ones matching
the backend you want to test:
Environment variables
| Variable | Purpose |
|---|---|
APP_KEY |
Recommended via a Secret (base64:…, e.g. php artisan key:generate --show). If unset, each pod generates an ephemeral key, which breaks shared sessions across replicas. |
DB_CONNECTION |
mysql, pgsql, mariadb, or sqlite (drivers bundled in the image). |
DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME, DB_PASSWORD |
Point the database tool at a cluster DB. Use the DB Service DNS name for DB_HOST (e.g. postgres.default.svc.cluster.local). |
CACHE_STORE |
Set to redis to make the cache tool exercise Redis. |
REDIS_HOST, REDIS_PORT, REDIS_PASSWORD |
Redis Service address (e.g. redis.default.svc.cluster.local, 6379). |
APP_ENV, APP_DEBUG |
Default production / false. Set APP_DEBUG=true to see full stack traces. |
Image defaults keep page rendering independent of the database: SESSION_DRIVER=file,
CACHE_STORE=file, QUEUE_CONNECTION=sync, LOG_CHANNEL=stderr. Override any of them via env.
Volume mounts
To exercise the storage tool against a real volume, mount your PVC at the local disk root:
| Mount path | What it is |
|---|---|
/app/storage/app/private |
Root of the local filesystem disk — the storage tool writes/reads here. Mount your PVC here to test a real PersistentVolume. |
The container runs as www-data (uid 33) — make the volume writable by it, e.g. set fsGroup: 33
on the pod's securityContext.
Example Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: cluster-tester
spec:
replicas: 1
selector:
matchLabels: { app: cluster-tester }
template:
metadata:
labels: { app: cluster-tester }
spec:
securityContext:
fsGroup: 33 # www-data — lets the pod write the mounted PVC
containers:
- name: cluster-tester
image: <your-registry>/cluster-tester:latest
ports:
- containerPort: 8080
env:
- name: APP_KEY
valueFrom: { secretKeyRef: { name: cluster-tester, key: app-key } }
# --- database tool ---
- name: DB_CONNECTION
value: pgsql
- name: DB_HOST
value: postgres.default.svc.cluster.local
- name: DB_PORT
value: "5432"
- name: DB_DATABASE
value: clustertest
- name: DB_USERNAME
value: postgres
- name: DB_PASSWORD
valueFrom: { secretKeyRef: { name: cluster-tester, key: db-password } }
# --- cache tool ---
- name: CACHE_STORE
value: redis
- name: REDIS_HOST
value: redis.default.svc.cluster.local
- name: REDIS_PORT
value: "6379"
volumeMounts:
- name: storage # mounts the PVC at the local disk root
mountPath: /app/storage/app/private
readinessProbe:
httpGet: { path: /, port: 8080 }
livenessProbe:
httpGet: { path: /, port: 8080 }
volumes:
- name: storage
persistentVolumeClaim:
claimName: cluster-tester-storage
---
apiVersion: v1
kind: Service
metadata:
name: cluster-tester
spec:
selector: { app: cluster-tester }
ports:
- port: 80
targetPort: 8080
Local development
composer install
bun install # or npm install
cp .env.example .env && php artisan key:generate
php artisan migrate
composer run dev # serves app + vite + queue + logs
Run the tests:
php artisan test