fix: replace registry Ingress+Buffering with IngressRoute for streaming

The Buffering middleware was causing 413 on large Docker layer pushes
by spooling entire request bodies to disk before forwarding. Docker's
chunked blob upload protocol (PATCH/PUT with Content-Range) requires
streaming, not buffering.

Replace with IngressRoute CRDs + Certificate resources for direct
streaming passthrough. responseForwarding.flushInterval=100ms ensures
prompt chunk delivery to the registry backend.
This commit is contained in:
Will Anderson
2026-03-26 11:13:25 -05:00
parent 206873e83b
commit d163a92ec6
+52 -54
View File
@@ -1,71 +1,69 @@
---
# Middleware: allow unlimited body size for Docker image layer uploads
apiVersion: traefik.io/v1alpha1
kind: Middleware
# Certificate for Docker registry (cert-manager — required for IngressRoute)
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: registry-chunked
name: registry-tls
namespace: registry
spec:
buffering:
maxRequestBodyBytes: 0
maxResponseBodyBytes: 0
memRequestBodyBytes: 0
retryExpression: ""
secretName: registry-tls
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
dnsNames:
- registry.neuralplatform.ai
---
# Docker registry ingress with chunked upload middleware
apiVersion: networking.k8s.io/v1
kind: Ingress
# Docker registry — IngressRoute with no buffering middleware.
# Traefik streams blob data directly to the registry backend.
# The Buffering middleware was causing 413s on large layer pushes by
# spooling the entire body to disk before forwarding.
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: registry
namespace: registry
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
cert-manager.io/cluster-issuer: letsencrypt-prod
traefik.ingress.kubernetes.io/router.middlewares: registry-chunked@kubernetescrd
nginx.ingress.kubernetes.io/proxy-body-size: "0"
nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
spec:
ingressClassName: traefik
entryPoints:
- websecure
routes:
- match: Host(`registry.neuralplatform.ai`)
kind: Rule
services:
- name: registry
port: 5000
responseForwarding:
flushInterval: "100ms"
tls:
- hosts:
- registry.neuralplatform.ai
secretName: registry-tls
rules:
- host: registry.neuralplatform.ai
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: registry
port:
number: 5000
secretName: registry-tls
---
# Certificate for Docker registry UI
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: docker-ui-tls
namespace: registry
spec:
secretName: docker-ui-tls
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
dnsNames:
- docker.neuralplatform.ai
---
# Docker registry UI
apiVersion: networking.k8s.io/v1
kind: Ingress
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: registry-ui
namespace: registry
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
ingressClassName: traefik
entryPoints:
- websecure
routes:
- match: Host(`docker.neuralplatform.ai`)
kind: Rule
services:
- name: registry-ui
port: 80
tls:
- hosts:
- docker.neuralplatform.ai
secretName: docker-ui-tls
rules:
- host: docker.neuralplatform.ai
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: registry-ui
port:
number: 80
secretName: docker-ui-tls