I have Nginx Ingress controller deployed in Nginx namespace of my kubernetes cluster. I am building a custom backend image and deploying it in Nginx namespace as nginx default backend. Now it should serve custom http error pages like 404, 500 and 503etc.
I built one and deployed using helm-chart with below default.conf file but it is serving index.html for 404 error and serving just default 503 error(not my custom 503.html page)
server {
listen 8080 default_server;
root /var/www/html;
index index.html;
location / {
}
location /healthz {
access_log off;
return 200 "healthy\n";
}
location /metrics {
stub_status on;
}
error_page 404 /404.html;
location = /404.html {
internal;
}
error_page 500 /500.html;
location = /500.html {
internal;
}
error_page 503 /503.html;
location = /503.html {
internal;
}
}
Dockerfile
FROM nginxinc/nginx-unprivileged
USER root
RUN rm /etc/nginx/conf.d/default.conf && \
ln -sf /dev/stdout /var/log/nginx/access.log && \
ln -sf /dev/stderr /var/log/nginx/error.log
COPY ./default.conf /etc/nginx/conf.d/default.conf
COPY content/ /var/www/html/
CMD ["nginx", "-g", "daemon off;"]Please ask me if you need more info. Your help will be much appreciated, Thanks.
To update the default error page, edit the config map of nginx-ingress-controller. Insert a new key custom-http-errors with the HTTP status code that you want to change its error page, such as:
apiVersion: v1
kind: ConfigMap
data:
custom-http-errors: 404,413,503
enable-vts-status: "false"
metadata:
labels:
app: nginx-ingress
chart: nginx-ingress-1.6.0
component: controller
heritage: Tiller
release: nginx-ingress
name: nginx-ingress-controller
namespace: NginxNow, fire the test command again,
curl -i "[http://err-test.192.168.64.5.nip.io/err?code=413](http://err-test.192.168.64.5.nip.io/err?code=413)"
HTTP/1.1 404 Not Found
Server: nginx/1.15.10
Date: Sun, 05 May 2019 11:36:04 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 21
Connection: closedefault backend - 404This is NOT what you want. The Nginx ingress controller correctly captures the HTTP status code that we want to customize. However, the default Nginx “default-backend” (Image: k8s.gcr.io/defaultbackend:1.4) just simply returns 404 status regardless of the actual status code that the application intends to return. This will cause a problem if the status code is to be used for other purposes.
In the Nginx Ingress Controller documentation you may see:
The custom backend is expected to return the correct HTTP status code instead of
200. NGINX does not change the response from the custom default backend.
Then in Dockerfile you have to add path to your defined custom backends errors:
ADD custom-error-pages /
CMD ["/custom-error-pages"]Build the image and push into docker hub. Redeploy the Nginx helm chart in K3s it looks like:
apiVersion: k3s.cattle.io/v1
kind: HelmChart
metadata:
name: nginx-ingress
namespace: Nginx
spec:
chart: stable/nginx-ingress
targetNamespace: kube-system
valuesContent: |-
defaultBackend:
enabled: true
name: default-backend
image:
repository: your-image/custom-error-page
tag: latestIn k8s simply execute:
helm upgrade nginx-ingress stable/nginx-ingress --set defaultBackendService.enabled=true --set defaultBackend.image.repository=your-image/custom-error-page --set defaultBackend.image.tag=latestThen test again, execute the same curl command:
➜ curl -i "[http://err-test.192.168.64.5.nip.io/err?code=413](http://err-test.192.168.64.5.nip.io/err?code=413)"
HTTP/1.1 413 Request Entity Too Large
Server: nginx/1.15.10
Date: Sun, 05 May 2019 12:09:21 GMT
Content-Type: */*
Transfer-Encoding: chunked
Connection: close4xx htmlYou will have the custom error page with the correct HTTP status code.
Since you trap 503 status, scale down the replica.
Execute command:
$ kubectl scale deploy err-status-test --replicas=0
If you will access the application again, you will see the custom error page with the status code shown as 503 which is expected.
More information you can find here: custom-backend-errors.