1. The problem I’m having:
We have a layered infra structure with K8s clusters internally, service endpoints exposed by Nginx ingresses and then all publicly facing APIs are served by a Caddyserver acting as a WAF and reverse proxy.
( outer world → [caddy ↔ ingress ↔ applications] )
We are using NextJs for web apps. NextJs is streaming data with text/x-component
as protocol. For example when a user waits for data to fill the app, there is a spinner rendered in the browser, which occurs with a streaming connection.
If we connect directly to the Nginx ingresses, everything is working as expected. The spinner is rendered when data is handled server side.
If we use the app via Caddyserver, the spinner is not rendered. The web app looks like it froze and then data is populated.
At first I suspected the weird protocol to be the bad boy, but no. There is no indication in any logs that these responses are being blocked. And, the user gets the data in the end so it can’t be a drop/block issue after all.
I’ve tried the flush_interval -1
config discussed here. But there is no difference in behaviour when I add this to the reverse proxy directive.
What am I missing? Anyone else using NextJs behind Caddy who might have some tricks up the sleeve?
2. Error messages and/or full log output:
None. No logs.
3. Caddy version:
2.7.6 with Coraza v2 (xcaddy builder)
4. How I installed and ran Caddy:
FROM caddy:2.7.6-builder AS builder
WORKDIR /app
RUN xcaddy build --output caddy \
--with github.com/corazawaf/coraza-caddy/v2@latest
FROM caddy:2.7.6
COPY conf/* /etc/caddy/
COPY --from=builder /app/caddy /usr/bin/caddy
CMD ["caddy", "run", "--config", "/etc/caddy/Caddyfile", "--adapter", "caddyfile", "--watch"]
a. System environment:
Docker, see above
b. Command:
PASTE OVER THIS, BETWEEN THE ``` LINES.
Please use the preview pane to ensure it looks nice.
c. Service/unit/compose file:
PASTE OVER THIS, BETWEEN THE ``` LINES.
Please use the preview pane to ensure it looks nice.
d. My complete Caddy config:
{
order coraza_waf first
}
(cors) {
@origin{args[0]} header Origin {args[0]}
header @origin{args[0]} Access-Control-Allow-Origin "{args[0]}"
header @origin{args[0]} Vary Origin
}
import endpoints-prod/*
import endpoints-test/*
This config is one of the apps in test for example:’
tks-manager.alpcot.tech {
coraza_waf {
load_owasp_crs
directives `
Include /etc/caddy/coraza.conf
Include /etc/caddy/crs-setup-nextjs.conf
Include /etc/caddy/rules/*.conf
SecRuleEngine On
`
}
tls ------------
encode zstd gzip
import cors https://*.azurewebsites.net
handle * {
rewrite * /tks-manager/{uri}
reverse_proxy ----------
}
respond "hello tks"
log
}