1. The problem I’m having:
I can’t make a custom error page for reverse_proxy, so that when the frontend container shows the custom error page.
I have a caddy and frontend docker containers. The frontend folder has folder error_505, where html, css, svg files located. I make mount in docker-compose.yml in the caddy service on this folder like that:
volumes:
- ./error_500:/usr/share/caddy/error_500/
I tried handle_response and handle_error, but when i turn off frontend container and I go through URL, I get 502 status code, without a custom page, or white screen with 200 status code.
2. Error messages and/or full log output:
{"level":"error","ts":1695625064.578222,"logger":"http.log.error.log0","msg":"error handling handler error","request":{"remote_ip":"31.13.134.16","remote_port":"46928","client_ip":"31.13.134.16","proto":"HTTP/2.0","method":"GET","host":"unity.staging.donorsearch.org","uri":"/favicon.ico","headers":{"Accept":["image/avif,image/webp,*/*"],"Authorization":[],"Cookie":[],"Sec-Fetch-Dest":["image"],"Sec-Fetch-Site":["same-origin"],"User-Agent":["Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/117.0"],"Accept-Language":["ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3"],"Cache-Control":["no-cache"],"Accept-Encoding":["gzip, deflate, br"],"Referer":["https://unity.staging.donorsearch.org/"],"Sec-Fetch-Mode":["no-cors"],"Pragma":["no-cache"],"Te":["trailers"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","server_name":"unity.staging.donorsearch.org"}},"duration":0.00457702,"error":"{id=jm0v0igf8} fileserver.(*FileServer).notFound (staticfiles.go:613): HTTP 404","first_error":{"msg":"dial tcp: lookup unity_frontend on 127.0.0.11:53: server misbehaving","status":502,"err_id":"i5ytri1gq","err_trace":"reverseproxy.statusError (reverseproxy.go:1248)"}}
{"level":"error","ts":1695625064.578261,"logger":"http.log.access.log0","msg":"handled request","request":{"remote_ip":"31.13.134.16","remote_port":"46928","client_ip":"31.13.134.16","proto":"HTTP/2.0","method":"GET","host":"unity.staging.donorsearch.org","uri":"/favicon.ico","headers":{"User-Agent":["Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/117.0"],"Accept-Language":["ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3"],"Cache-Control":["no-cache"],"Accept-Encoding":["gzip, deflate, br"],"Referer":["https://unity.staging.donorsearch.org/"],"Sec-Fetch-Mode":["no-cors"],"Pragma":["no-cache"],"Te":["trailers"],"Accept":["image/avif,image/webp,*/*"],"Authorization":[],"Cookie":[],"Sec-Fetch-Dest":["image"],"Sec-Fetch-Site":["same-origin"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","server_name":"unity.staging.donorsearch.org"}},"bytes_read":0,"user_id":"admin","duration":0.00457702,"size":0,"status":502,"resp_headers":{"Server":["Caddy"],"Alt-Svc":["h3=\":443\"; ma=2592000"],"Strict-Transport-Security":["max-age=31536000;"]}}
3. Caddy version:
v2.7.4 h1:J8nisjdOxnYHXlorUKXY75Gr6iBfudfoGhrJ8t7/flI=
4. How I installed and ran Caddy:
a. System environment:
OS Linux Ubuntu 18.04, Docker version 19.03.12
b. Command:
docker-compose -f docker-compose.caddy.yml up -d --build
c. Service/unit/compose file:
version: "3.6"
networks:
proxynet:
services:
caddy:
image: caddy:latest
container_name: unity_caddy
restart: unless-stopped
env_file: ./config/.env
volumes:
- ./caddy/Caddyfile:/etc/caddy/Caddyfile # configuration
- caddy-config:/config # configuation autosaves
- caddy-data:/data # saving certificates
- /etc/ssl:/etc/ssl
- ./error_500:/usr/share/caddy/error_500/
ports:
- "80:80"
- "443:443"
networks:
- proxynet
volumes:
caddy-config:
caddy-data:
d. My complete Caddy config:
{
email {$TLS_EMAIL}
}
{$DOMAIN_NAME} {
# HTTPS options:
header Strict-Transport-Security max-age=31536000;
# Removing some headers for improved security:
header -Server
# @error status 500 502 503
# Serving dynamic requests:
reverse_proxy unity_frontend:3000 {
@error status 500 502 503
handle_response @error {
root * /app
rewrite * /app/error_500/index.html
file_server
}
}
# handle_errors {
# rewrite * /usr/share/caddy/error_500/index.html
# file_server
# }
basicauth /* {
admin JDJhJDEwJE5LZ1NMLmVzVi9lSXBsSGhZTS5Mc2VxYnhIYmdmeWlxa09uUi5Pd3g3aXoxeTEvTGt3REJP
}
try_files {path} /index.html
# Allows to use .gz files when available:
encode gzip
# Logs:
log {
output stdout
}
}