apiVersion: apps/v1 kind: Deployment metadata: name: app-deployment labels: app: docs-portal spec: replicas: 1 selector: matchLabels: app: docs-portal template: metadata: labels: app: docs-portal spec: # El base fuerza runAsNonRoot: true a nivel pod. La imagen ACTUAL # de docs-portal (nginx:1.27-alpine, sin USER) corre como root -- # aplicar el default del base tal cual rompe el pod # (CreateContainerConfigError). Override explícito acá hasta que # docs-portal adopte dockerfiles/static-nginx.Dockerfile # (nginx-unprivileged, no-root) como cambio de imagen aparte -- # no es parte de esta migración de manifiestos. securityContext: runAsNonRoot: false containers: - name: app image: gitea.cruzcloud.net/devops/docs-portal:v1.0.237 # El base saca TODAS las capabilities. Probado en vivo y # revertido: con drop: ALL (aunque se agregue NET_BIND_SERVICE # de vuelta) el propio entrypoint de nginx:1.27-alpine falla al # arrancar -- necesita CAP_CHOWN para el chown() que hace sobre # /var/cache/nginx/client_temp en cada arranque ("Operation not # permitted", confirmado en el log real del pod). No vale la # pena ir agregando capabilities una por una a ciegas -- se # deja sin restricción de capabilities, igual que como corre # hoy en producción (no es peor que el estado actual). Se # resuelve del todo cuando docs-portal pase a # nginx-unprivileged (no necesita root ni capabilities # especiales para nada de esto). securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: false # Ni omitir "capabilities" ni un objeto vacío {} alcanzan # para anular el drop:[ALL] del base (probado en vivo, los # dos dejaron el drop:[ALL] heredado intacto). "null" es la # forma real de borrar un campo heredado en un patch de # merge de Kubernetes/Kustomize. capabilities: null resources: requests: cpu: 50m memory: 64Mi limits: cpu: 200m memory: 128Mi