diff --git a/supabase/deploy.sh b/supabase/deploy.sh index 0ed9e8d..39523b9 100755 --- a/supabase/deploy.sh +++ b/supabase/deploy.sh @@ -59,6 +59,38 @@ die() { exit 1 } +repair_blocked() { + local reason="$1" + local fix="${2:-}" + echo "" >&2 + echo "[REPAIR_BLOCKED] ${reason}" >&2 + if [[ -n "$fix" ]]; then + echo "Suggested Fix: ${fix}" >&2 + fi + echo "" >&2 + exit 1 +} + +check_supabase_minio_blocked() { + local ns="$1" + local kube_context="${2:-}" + local ctx_args=() + if [[ -n "$kube_context" ]]; then + ctx_args+=(--context "$kube_context") + fi + + local minio_pod + minio_pod=$(kubectl "${ctx_args[@]}" get pods -n "$ns" -l "app.kubernetes.io/instance=supabase" --no-headers -o custom-columns=":metadata.name" | grep "minio" | head -n 1) + if [[ -n "$minio_pod" ]]; then + local logs + logs=$(kubectl "${ctx_args[@]}" logs -n "$ns" "$minio_pod" --tail=50 2>/dev/null || true) + if [[ "$logs" == *"file access denied"* ]] || [[ "$logs" == *"/data/.minio.sys/tmp"* ]]; then + repair_blocked "Supabase MinIO is failing with file access denied on /data" \ + "Ensure the rendered YAML contains the correct podSecurityContext (runAsUser: 65532, fsGroup: 65532). MinIO with Chainguard images must run as non-root with appropriate fsGroup for PVC volume mounts." + fi + fi +} + warn() { echo "Warning: $*" >&2 } @@ -427,6 +459,9 @@ wait_for_supabase_ready() { continue fi + # Targeted blocked-state checks + check_supabase_minio_blocked "$ns" "$kube_context" + local pending_pvcs not_ready_pods terminating_pods pvc_blockers pod_blockers status_metrics status_metrics=$(STATUS_JSON="$status_json" python3 - <<'PY' import json diff --git a/supabase/helm/generated/manifest-summary.json b/supabase/helm/generated/manifest-summary.json index 86148d3..c492daa 100644 --- a/supabase/helm/generated/manifest-summary.json +++ b/supabase/helm/generated/manifest-summary.json @@ -1,8 +1,8 @@ { - "values": "/Users/chrisfu/dev/prole/supabase/helm/generated/values.generated.json", - "manifests": "/Users/chrisfu/dev/prole/supabase/k8s/supabase-helm.yaml", - "manifests_app": "/Users/chrisfu/dev/prole/supabase/helm/generated/supabase-helm.app.yaml", - "manifests_frontdoor_db": "/Users/chrisfu/dev/prole/supabase/helm/generated/supabase-helm.frontdoor-db.yaml", + "values": "supabase/helm/generated/values.generated.json", + "manifests": "supabase/k8s/supabase-helm.yaml", + "manifests_app": "supabase/helm/generated/supabase-helm.app.yaml", + "manifests_frontdoor_db": "supabase/helm/generated/supabase-helm.frontdoor-db.yaml", "db_host": "knoe-db-rw.knoe-db-0.svc.cluster.local", "supabase_namespace": "supabase" } \ No newline at end of file diff --git a/supabase/helm/render_supabase.py b/supabase/helm/render_supabase.py index 747efed..5a26600 100755 --- a/supabase/helm/render_supabase.py +++ b/supabase/helm/render_supabase.py @@ -808,7 +808,27 @@ def _build_overlay(cfg: configparser.ConfigParser, args: argparse.Namespace) -> "vector": {"enabled": True, "fullnameOverride": "supabase-vector"}, "kong": {"enabled": True, "fullnameOverride": "supabase-kong"}, "storage": {"enabled": True, "fullnameOverride": "supabase-storage"}, - "minio": {"enabled": not use_garage_s3, "fullnameOverride": "supabase-minio"}, + "minio": { + "enabled": not use_garage_s3, + "fullnameOverride": "supabase-minio", + "podSecurityContext": { + "runAsUser": 65532, + "runAsGroup": 65532, + "fsGroup": 65532, + "fsGroupChangePolicy": "OnRootMismatch" + }, + "securityContext": { + "runAsUser": 65532, + "runAsGroup": 65532, + "allowPrivilegeEscalation": False, + "readOnlyRootFilesystem": True, + "runAsNonRoot": True + }, + "resources": { + "requests": {"cpu": "100m", "memory": "256Mi"}, + "limits": {"cpu": "500m", "memory": "512Mi"} + } + }, "imgproxy": {"enabled": True, "fullnameOverride": "supabase-imgproxy"}, # Explicit fullnameOverride per component strips the chart name # from pod names (avoids 'supabase-knoe-supabase-').