feat(netbox): add enterprise-grade server documenting app w/ shared postgres

This commit is contained in:
forust committed 2026-09-25 23:24:21 +02:00
1 parent a4a4bb4cc5
commit c536a16a2a
17 files changed
+772 -1

No files matched your search

+32
View File
@@ -0,0 +1,32 @@
POSTGRES_DB=netbox
POSTGRES_USER=netbox
POSTGRES_PASSWORD=CHANGE_ME_POSTGRES_PASSWORD
DB_NAME=netbox
DB_USER=netbox
DB_PASSWORD=CHANGE_ME_POSTGRES_PASSWORD
DB_HOST=postgres
DB_PORT=5432
DB_SSLMODE=disable
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_PASSWORD=CHANGE_ME_REDIS_PASSWORD
REDIS_DATABASE=0
REDIS_CACHE_HOST=redis-cache
REDIS_CACHE_PORT=6379
REDIS_CACHE_PASSWORD=CHANGE_ME_REDIS_CACHE_PASSWORD
REDIS_CACHE_DATABASE=1
ALLOWED_HOSTS=localhost,127.0.0.1,[::1],netbox.forust.xyz,netbox.workstation.internal
CSRF_TRUSTED_ORIGINS=https://netbox.forust.xyz,https://netbox.workstation.internal
SECRET_KEY=CHANGE_ME_DJANGO_SECRET_KEY
API_TOKEN_PEPPER_1=CHANGE_ME_API_TOKEN_PEPPER
TIME_ZONE=Europe/Bratislava
TZ=Europe/Bratislava
SKIP_SUPERUSER=false
SUPERUSER_NAME=admin
SUPERUSER_EMAIL=admin@example.com
SUPERUSER_PASSWORD=CHANGE_ME_SUPERUSER_PASSWORD
+96
View File
@@ -0,0 +1,96 @@
# NetBox
NetBox for homelab documentation and visualization. Two runtimes are available:
| Runtime | Manifest | Purpose |
| ------- | -------------- | -------------------------------------------------------------- |
| Docker | `compose.yaml` | Local stand on `127.0.0.1:8000` (no public exposure) |
| k8s | `k8s/` | Homelab service on `netbox.forust.xyz` (and the internal name) |
Both use the same image (`netboxcommunity/netbox:v4.7-5.1.1`) and Valkey for tasks
plus a second logical database for caching. The Docker stand keeps its own
PostgreSQL container, while the k8s deployment uses the shared `database` cluster
(`postgres.database.svc.cluster.local:5432`, role/database `netbox`); only Valkey
stays a per-service StatefulSet.
## Docker Compose
```bash
cp .env.example .env
# replace CHANGE_ME
docker compose up -d
```
The UI is available at <http://localhost:8000>. The port is bound to `127.0.0.1`
intentionally, so this stand is not exposed on the LAN or public interfaces.
The `netbox` service is also attached to the external `proxy` network and carries
Traefik labels for `netbox.forust.xyz` and `netbox.workstation.internal`. Those
labels only take effect while the Docker Traefik stack is running; it is currently
stopped, and the live ingress path in this homelab is the k8s Traefik.
Inspect startup and health with:
```bash
docker compose ps
docker compose logs -f netbox
```
Stop it with `docker compose down`; data is kept in the named volumes
`netbox-postgres`, `netbox-media-files`, `netbox-reports-files`,
`netbox-scripts-files` and `netbox-redis-data`.
## Kubernetes
`k8s/` is deployed in the homelab cluster and serves `netbox.forust.xyz` publicly
plus `netbox.workstation.internal` / `netbox.gigaforust.internal` internally. To
rebuild it from scratch:
```bash
# 1. shared PostgreSQL: the password lives in the shared secret, NetBox keeps a copy
kubectl -n database patch secret postgres-shared-secrets \
--type merge -p '{"stringData":{"NETBOX_DB_PASSWORD":"<same value>"}}'
kubectl -n database exec postgres17-0 -- psql -U postgres -d postgres \
-c 'CREATE ROLE netbox LOGIN PASSWORD ...' -c 'CREATE DATABASE netbox OWNER netbox'
# 2. secrets first: the deploy workflow never applies *secret*.yaml
cp k8s/secrets.yaml.example k8s/secrets.yaml # replace CHANGE_ME
kubectl apply -f k8s/secrets.yaml
# 3. manifests
kubectl apply -f k8s/
```
The shared cluster is reached at `postgres.database.svc.cluster.local:5432`. Its
NetworkPolicy (`postgres/k8s/network-policy.yaml`) must list the `netbox` namespace
or connections are dropped, and `postgres/initdb/01-create-databases.sh` already
creates the role and database on a fresh data directory. NetBox has no PostgreSQL
StatefulSet of its own — only `netbox-valkey`.
`netbox.forust.xyz` resolves to this host (`78.98.72.122`) through the `DOMAINS`
list in the `default/cfddns` secret. cert-manager issues `netbox-prod-tls` with the
`letsencrypt-prod` issuer, the internal route uses `internal-wildcard-tls`.
Resources are permanent again now that the first-boot migrations are complete:
the web container reserves `100m`/`512Mi` and is capped at `2` CPU/`2Gi`, the
worker reserves `50m`/`256Mi` and is capped at `1` CPU/`1Gi`, and Valkey reserves
`25m`/`64Mi` and is capped at `250m`/`256Mi`. The deliberately generous CPU caps
leave enough headroom for future schema migrations without letting one process
consume the whole node.
The first start applies ~810 migrations, each in its own transaction with DDL and
a commit; every later start is a no-op. The startup probe allows 15 minutes and
`progressDeadlineSeconds` is 1800 for the same reason. Probes run inside the pod
and explicitly set `Host: netbox.forust.xyz`; a kubelet `httpGet.host` field would
replace the probe destination with that public hostname and bypass the pod.
## Secrets
- `netbox/.env` (compose) and `netbox/k8s/secrets.yaml` (k8s) are gitignored. Only
`.env.example` and `k8s/secrets.yaml.example` are committed.
- `netbox/configuration/configuration.py` is env-driven: hosts, database, Redis and
the Django keys all come from the environment, so the same settings file works in
both runtimes. The k8s copy lives in the `netbox-settings` ConfigMap
(`k8s/settings.yaml`) and must be kept in sync with the file.
- Rotating `SECRET_KEY` invalidates all sessions; rotating `API_TOKEN_PEPPER_1`
invalidates every API token.
+137
View File
@@ -0,0 +1,137 @@
services:
netbox:
image: docker.io/netboxcommunity/netbox:v4.7-5.1.1
container_name: netbox
restart: unless-stopped
user: "netbox:root"
ports:
- "127.0.0.1:8000:8080"
env_file:
- .env
environment:
GRANIAN_WORKERS: "2"
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
redis-cache:
condition: service_healthy
volumes:
- ./configuration:/etc/netbox/config:z,ro
- netbox-media-files:/opt/netbox/netbox/media
- netbox-reports-files:/opt/netbox/netbox/reports
- netbox-scripts-files:/opt/netbox/netbox/scripts
networks:
- default
- proxy
labels:
- "traefik.enable=true"
- "traefik.http.services.netbox.loadbalancer.server.port=8080"
# Prod Router
- "traefik.http.routers.netbox.rule=Host(`netbox.forust.xyz`)"
- "traefik.http.routers.netbox.entrypoints=websecure"
- "traefik.http.routers.netbox.middlewares=security-headers@file"
- "traefik.http.routers.netbox.tls.certresolver=letsencrypt"
# Local Router
- "traefik.http.routers.netbox-local.rule=Host(`netbox.workstation.internal`)"
- "traefik.http.routers.netbox-local.entrypoints=websecure"
- "traefik.http.routers.netbox-local.tls=true"
healthcheck:
test: ["CMD", "/opt/netbox/health.sh"]
start_period: 600s
timeout: 5s
interval: 15s
retries: 10
netbox-worker:
image: docker.io/netboxcommunity/netbox:v4.7-5.1.1
container_name: netbox-worker
restart: unless-stopped
user: "netbox:root"
command:
- /opt/netbox/venv/bin/python
- /opt/netbox/netbox/manage.py
- rqworker
env_file:
- .env
depends_on:
netbox:
condition: service_healthy
volumes:
- ./configuration:/etc/netbox/config:z,ro
- netbox-media-files:/opt/netbox/netbox/media
- netbox-reports-files:/opt/netbox/netbox/reports
- netbox-scripts-files:/opt/netbox/netbox/scripts
healthcheck:
test: ["CMD-SHELL", "ps -ef | grep -q '[r]qworker'"]
start_period: 30s
timeout: 5s
interval: 15s
retries: 10
postgres:
image: docker.io/postgres:18.6-alpine
container_name: netbox-postgres
restart: unless-stopped
environment:
POSTGRES_DB: "${POSTGRES_DB:?POSTGRES_DB must be set}"
POSTGRES_USER: "${POSTGRES_USER:?POSTGRES_USER must be set}"
POSTGRES_PASSWORD: "${POSTGRES_PASSWORD:?POSTGRES_PASSWORD must be set}"
volumes:
- netbox-postgres:/var/lib/postgresql
healthcheck:
test: ["CMD-SHELL", 'pg_isready -q -t 2 -d "$${POSTGRES_DB}" -U "$${POSTGRES_USER}"']
start_period: 20s
timeout: 5s
interval: 10s
retries: 10
redis:
image: docker.io/valkey/valkey:9.1.2-alpine
container_name: netbox-redis
restart: unless-stopped
command:
- sh
- -c
- valkey-server --appendonly yes --requirepass "$$REDIS_PASSWORD"
environment:
REDIS_PASSWORD: "${REDIS_PASSWORD:?REDIS_PASSWORD must be set}"
volumes:
- netbox-redis-data:/data
healthcheck:
test: ["CMD-SHELL", 'valkey-cli --pass "$${REDIS_PASSWORD}" ping | grep -q PONG']
start_period: 5s
timeout: 5s
interval: 5s
retries: 10
redis-cache:
image: docker.io/valkey/valkey:9.1.2-alpine
container_name: netbox-redis-cache
restart: unless-stopped
command:
- sh
- -c
- valkey-server --requirepass "$$REDIS_CACHE_PASSWORD"
environment:
REDIS_CACHE_PASSWORD: "${REDIS_CACHE_PASSWORD:?REDIS_CACHE_PASSWORD must be set}"
healthcheck:
test: ["CMD-SHELL", 'valkey-cli --pass "$${REDIS_CACHE_PASSWORD}" ping | grep -q PONG']
start_period: 5s
timeout: 5s
interval: 5s
retries: 10
volumes:
netbox-media-files:
netbox-reports-files:
netbox-scripts-files:
netbox-postgres:
netbox-redis-data:
networks:
default:
proxy:
external: true
+48
View File
@@ -0,0 +1,48 @@
import os
def _csv(name, default=""):
return [item.strip() for item in os.environ.get(name, default).split(",") if item.strip()]
ALLOWED_HOSTS = _csv("ALLOWED_HOSTS", "localhost,127.0.0.1,[::1]")
CSRF_TRUSTED_ORIGINS = _csv("CSRF_TRUSTED_ORIGINS")
USE_X_FORWARDED_HOST = True
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
DATABASES = {
"default": {
"NAME": os.environ["DB_NAME"],
"USER": os.environ["DB_USER"],
"PASSWORD": os.environ["DB_PASSWORD"],
"HOST": os.environ["DB_HOST"],
"PORT": os.environ.get("DB_PORT", "5432"),
"OPTIONS": {"sslmode": os.environ.get("DB_SSLMODE", "disable")},
"CONN_MAX_AGE": int(os.environ.get("DB_CONN_MAX_AGE", "300")),
}
}
REDIS = {
"tasks": {
"HOST": os.environ["REDIS_HOST"],
"PORT": int(os.environ.get("REDIS_PORT", "6379")),
"PASSWORD": os.environ["REDIS_PASSWORD"],
"DATABASE": int(os.environ.get("REDIS_DATABASE", "0")),
"SSL": False,
},
"caching": {
"HOST": os.environ["REDIS_CACHE_HOST"],
"PORT": int(os.environ.get("REDIS_CACHE_PORT", "6379")),
"PASSWORD": os.environ["REDIS_CACHE_PASSWORD"],
"DATABASE": int(os.environ.get("REDIS_CACHE_DATABASE", "1")),
"SSL": False,
},
}
SECRET_KEY = os.environ["SECRET_KEY"]
API_TOKEN_PEPPERS = {1: os.environ["API_TOKEN_PEPPER_1"]}
TIME_ZONE = os.environ.get("TIME_ZONE", "UTC")
MEDIA_ROOT = "/opt/netbox/netbox/media"
REPORTS_ROOT = "/opt/netbox/netbox/reports"
SCRIPTS_ROOT = "/opt/netbox/netbox/scripts"
CENSUS_REPORTING_ENABLED = False
+28
View File
@@ -0,0 +1,28 @@
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: netbox-prod-tls
namespace: netbox
spec:
secretName: netbox-prod-tls
dnsNames:
- netbox.forust.xyz
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: internal-wildcard-tls
namespace: netbox
spec:
secretName: internal-wildcard-tls
dnsNames:
- "*.workstation.internal"
- "*.gigaforust.internal"
- workstation.internal
- gigaforust.internal
issuerRef:
name: internal-ca
kind: ClusterIssuer
+21
View File
@@ -0,0 +1,21 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: netbox-config
namespace: netbox
data:
DB_HOST: "postgres.database.svc.cluster.local"
DB_PORT: "5432"
DB_SSLMODE: "disable"
REDIS_HOST: "netbox-valkey"
REDIS_PORT: "6379"
REDIS_DATABASE: "0"
REDIS_CACHE_HOST: "netbox-valkey"
REDIS_CACHE_PORT: "6379"
REDIS_CACHE_DATABASE: "1"
TIME_ZONE: "Europe/Bratislava"
TZ: "Europe/Bratislava"
GRANIAN_WORKERS: "2"
ALLOWED_HOSTS: "netbox.forust.xyz,netbox.workstation.internal,netbox.gigaforust.internal"
CSRF_TRUSTED_ORIGINS: "https://netbox.forust.xyz,https://netbox.workstation.internal,https://netbox.gigaforust.internal"
SKIP_SUPERUSER: "false"
+36
View File
@@ -0,0 +1,36 @@
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: netbox-prod
namespace: netbox
spec:
entryPoints:
- websecure
routes:
- match: Host(`netbox.forust.xyz`)
kind: Rule
middlewares:
- name: crowdsec-bouncer
namespace: crowdsec
services:
- name: netbox-service
port: 8080
tls:
secretName: netbox-prod-tls
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: netbox-local
namespace: netbox
spec:
entryPoints:
- websecure
routes:
- match: Host(`netbox.workstation.internal`) || Host(`netbox.gigaforust.internal`)
kind: Rule
services:
- name: netbox-service
port: 8080
tls:
secretName: internal-wildcard-tls
+4
View File
@@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: netbox
+204
View File
@@ -0,0 +1,204 @@
apiVersion: v1
kind: Service
metadata:
name: netbox-service
namespace: netbox
spec:
selector:
app: netbox
ports:
- name: http
port: 8080
targetPort: http
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: netbox-deployment
namespace: netbox
labels:
app: netbox
spec:
replicas: 1
progressDeadlineSeconds: 300
selector:
matchLabels:
app: netbox
strategy:
# ReadWriteOnce PVC
type: Recreate
template:
metadata:
labels:
app: netbox
spec:
containers:
- name: netbox
image: docker.io/netboxcommunity/netbox:v4.7-5.1.1
ports:
- name: http
containerPort: 8080
envFrom:
- configMapRef:
name: netbox-config
- secretRef:
name: netbox-secrets
volumeMounts:
- name: netbox-config
mountPath: /etc/netbox/config
readOnly: true
- name: netbox-media
mountPath: /opt/netbox/netbox/media
- name: netbox-reports
mountPath: /opt/netbox/netbox/reports
- name: netbox-scripts
mountPath: /opt/netbox/netbox/scripts
startupProbe:
exec:
command:
- /opt/netbox/venv/bin/python
- -c
- >-
exec /usr/bin/curl --fail --silent --show-error --max-time 4
--header 'Host: netbox.forust.xyz'
http://127.0.0.1:8080/login/ >/dev/null
failureThreshold: 90
periodSeconds: 10
readinessProbe:
exec:
command:
- /opt/netbox/venv/bin/python
- -c
- >-
exec /usr/bin/curl --fail --silent --show-error --max-time 4
--header 'Host: netbox.forust.xyz'
http://127.0.0.1:8080/login/ >/dev/null
periodSeconds: 10
livenessProbe:
exec:
command:
- /opt/netbox/venv/bin/python
- -c
- >-
exec /usr/bin/curl --fail --silent --show-error --max-time 4
--header 'Host: netbox.forust.xyz'
http://127.0.0.1:8080/login/ >/dev/null
initialDelaySeconds: 30
periodSeconds: 30
resources:
requests:
cpu: "100m"
memory: "512Mi"
limits:
cpu: "2"
memory: "2Gi"
volumes:
- name: netbox-config
configMap:
name: netbox-settings
- name: netbox-media
persistentVolumeClaim:
claimName: netbox-media-pvc
- name: netbox-reports
persistentVolumeClaim:
claimName: netbox-reports-pvc
- name: netbox-scripts
persistentVolumeClaim:
claimName: netbox-scripts-pvc
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: netbox-worker-deployment
namespace: netbox
labels:
app: netbox-worker
spec:
replicas: 1
progressDeadlineSeconds: 300
selector:
matchLabels:
app: netbox-worker
strategy:
type: Recreate
template:
metadata:
labels:
app: netbox-worker
spec:
containers:
- name: netbox-worker
image: docker.io/netboxcommunity/netbox:v4.7-5.1.1
command:
- /opt/netbox/venv/bin/python
- netbox/manage.py
- rqworker
workingDir: /opt/netbox
envFrom:
- configMapRef:
name: netbox-config
- secretRef:
name: netbox-secrets
volumeMounts:
- name: netbox-config
mountPath: /etc/netbox/config
readOnly: true
- name: netbox-media
mountPath: /opt/netbox/netbox/media
- name: netbox-reports
mountPath: /opt/netbox/netbox/reports
- name: netbox-scripts
mountPath: /opt/netbox/netbox/scripts
resources:
requests:
cpu: "50m"
memory: "256Mi"
limits:
cpu: "1"
memory: "1Gi"
volumes:
- name: netbox-config
configMap:
name: netbox-settings
- name: netbox-media
persistentVolumeClaim:
claimName: netbox-media-pvc
- name: netbox-reports
persistentVolumeClaim:
claimName: netbox-reports-pvc
- name: netbox-scripts
persistentVolumeClaim:
claimName: netbox-scripts-pvc
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: netbox-media-pvc
namespace: netbox
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 2Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: netbox-reports-pvc
namespace: netbox
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: netbox-scripts-pvc
namespace: netbox
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 1Gi
+18
View File
@@ -0,0 +1,18 @@
apiVersion: v1
kind: Secret
metadata:
name: netbox-secrets
namespace: netbox
type: Opaque
stringData:
DB_NAME: "netbox"
DB_USER: "netbox"
DB_PASSWORD: "CHANGE_ME_POSTGRES_PASSWORD"
REDIS_PASSWORD: "CHANGE_ME_VALKEY_PASSWORD"
REDIS_CACHE_PASSWORD: "CHANGE_ME_VALKEY_PASSWORD"
VALKEY_PASSWORD: "CHANGE_ME_VALKEY_PASSWORD"
SECRET_KEY: "CHANGE_ME_DJANGO_SECRET_KEY"
API_TOKEN_PEPPER_1: "CHANGE_ME_API_TOKEN_PEPPER"
SUPERUSER_NAME: "admin"
SUPERUSER_EMAIL: "admin@example.com"
SUPERUSER_PASSWORD: "CHANGE_ME_SUPERUSER_PASSWORD"
+56
View File
@@ -0,0 +1,56 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: netbox-settings
namespace: netbox
data:
# Sync wit netbox/configuration/configuration.py (the Docker mounts that file).
configuration.py: |
import os
def _csv(name, default=""):
return [item.strip() for item in os.environ.get(name, default).split(",") if item.strip()]
ALLOWED_HOSTS = _csv("ALLOWED_HOSTS", "localhost,127.0.0.1,[::1]")
CSRF_TRUSTED_ORIGINS = _csv("CSRF_TRUSTED_ORIGINS")
USE_X_FORWARDED_HOST = True
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
DATABASES = {
"default": {
"NAME": os.environ["DB_NAME"],
"USER": os.environ["DB_USER"],
"PASSWORD": os.environ["DB_PASSWORD"],
"HOST": os.environ["DB_HOST"],
"PORT": os.environ.get("DB_PORT", "5432"),
"OPTIONS": {"sslmode": os.environ.get("DB_SSLMODE", "disable")},
"CONN_MAX_AGE": int(os.environ.get("DB_CONN_MAX_AGE", "300")),
}
}
REDIS = {
"tasks": {
"HOST": os.environ["REDIS_HOST"],
"PORT": int(os.environ.get("REDIS_PORT", "6379")),
"PASSWORD": os.environ["REDIS_PASSWORD"],
"DATABASE": int(os.environ.get("REDIS_DATABASE", "0")),
"SSL": False,
},
"caching": {
"HOST": os.environ["REDIS_CACHE_HOST"],
"PORT": int(os.environ.get("REDIS_CACHE_PORT", "6379")),
"PASSWORD": os.environ["REDIS_CACHE_PASSWORD"],
"DATABASE": int(os.environ.get("REDIS_CACHE_DATABASE", "1")),
"SSL": False,
},
}
SECRET_KEY = os.environ["SECRET_KEY"]
API_TOKEN_PEPPERS = {1: os.environ["API_TOKEN_PEPPER_1"]}
TIME_ZONE = os.environ.get("TIME_ZONE", "UTC")
MEDIA_ROOT = "/opt/netbox/netbox/media"
REPORTS_ROOT = "/opt/netbox/netbox/reports"
SCRIPTS_ROOT = "/opt/netbox/netbox/scripts"
CENSUS_REPORTING_ENABLED = False
+82
View File
@@ -0,0 +1,82 @@
apiVersion: v1
kind: Service
metadata:
name: netbox-valkey
namespace: netbox
labels:
app: netbox-valkey
spec:
clusterIP: None
selector:
app: netbox-valkey
ports:
- name: valkey
port: 6379
targetPort: valkey
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: netbox-valkey
namespace: netbox
labels:
app: netbox-valkey
spec:
serviceName: netbox-valkey
replicas: 1
selector:
matchLabels:
app: netbox-valkey
template:
metadata:
labels:
app: netbox-valkey
spec:
containers:
- name: valkey
image: docker.io/valkey/valkey:9.1.2-alpine
command:
- sh
- -c
- valkey-server --appendonly yes --save 30 1 --loglevel warning --requirepass "$VALKEY_PASSWORD"
env:
- name: VALKEY_PASSWORD
valueFrom:
secretKeyRef:
name: netbox-secrets
key: VALKEY_PASSWORD
ports:
- name: valkey
containerPort: 6379
volumeMounts:
- name: valkey-data
mountPath: /data
startupProbe:
exec:
command: ["sh", "-c", 'valkey-cli --pass "$VALKEY_PASSWORD" ping | grep -q PONG']
failureThreshold: 20
periodSeconds: 5
readinessProbe:
exec:
command: ["sh", "-c", 'valkey-cli --pass "$VALKEY_PASSWORD" ping | grep -q PONG']
periodSeconds: 10
livenessProbe:
exec:
command: ["sh", "-c", 'valkey-cli --pass "$VALKEY_PASSWORD" ping | grep -q PONG']
initialDelaySeconds: 20
periodSeconds: 20
resources:
requests:
cpu: "25m"
memory: "64Mi"
limits:
cpu: "250m"
memory: "256Mi"
volumeClaimTemplates:
- metadata:
name: valkey-data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 1Gi