prime8dev

prime8dev
git clone https://git.prime8.dev/prime8dev.git
Log | Files | Refs | README | LICENSE

commit c54680e004e50c2ae9a0aa13e5ee1eec7cb3091c
parent ea069d2110cb2ed9359f988f1a465b8b6a8ae9fe
Author: Damian Myrda <damian@prime8.dev>
Date:   Sun, 24 Nov 2024 13:46:57 -0600

Update caddy config and add error pages

Diffstat:
MDockerfile | 8++++++--
Mcaddy | 145++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
Mweb/templates/404.html | 28+++-------------------------
Aweb/templates/429.html | 9+++++++++
Aweb/templates/500.html | 9+++++++++
Aweb/templates/error.html | 29+++++++++++++++++++++++++++++
6 files changed, 181 insertions(+), 47 deletions(-)

diff --git a/Dockerfile b/Dockerfile @@ -5,10 +5,14 @@ RUN ["zola", "build"] FROM caddy:builder AS caddy RUN xcaddy build \ - --with github.com/caddyserver/cache-handler + --with github.com/caddyserver/cache-handler \ + --with github.com/mholt/caddy-ratelimit FROM caddy:latest COPY --from=caddy /usr/bin/caddy /usr/bin/caddy COPY ./caddy /etc/caddy/Caddyfile COPY --from=web /src/public/ /web/ -EXPOSE 80 443 +EXPOSE 80 443 443/udp + +HEALTHCHECK --interval=60s --timeout=5s --start-period=5s \ + CMD curl -f http://localhost/ || exit 1 diff --git a/caddy b/caddy @@ -1,46 +1,151 @@ { - cache + cache } +# Root prime8.dev { - redir https://www.prime8.dev{uri} 301 + redir https://www.prime8.dev{uri} 301 + + # Rate Limiting + rate_limit { + burst 20 # Allow an initial burst of 20 requests + limit 10 # After the burst, allow 10 requests per minute + } + + # Security + header { + Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" # Enforce HTTPS for 1 year + X-Frame-Options "DENY" # Prevent embedding + -Server # Remove the Server header + Permissions-Policy "geolocation=(), microphone=(), camera=()" # No permissions + X-Content-Type-Options "nosniff" # Prevent MIME-type sniffing + Referrer-Policy "no-referrer-when-downgrade" # Control referrer behavior + } + tls damian@prime8.dev } +# Main Site www.prime8.dev { root * /web/ file_server try_files {path} {path}.html - cache - handle_errors { - @404 { - expression {http.error.status_code} == 404 - } - rewrite @404 /404.html - file_server - } + # 404 Page Handling + handle_errors { + @404 { + expression {http.error.status_code} == 404 + } + rewrite @404 /404.html + + @429 { + expression {http.error.status_code} == 429 + } + rewrite @429 /429.html + + @500 { + expression {http.error.status_code} == 500 + } + rewrite @500 /500.html + + file_server + } + + # Caching + cache + header /static/* { + Cache-Control "public, max-age=86400; immutable" # Cache for 1 day + } + + # Rate Limiting + rate_limit { + burst 20 # Allow an initial burst of 20 requests + limit 10 # After the burst, allow 10 requests per minute + } - tls damian@prime8.dev + # Security + header { + Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" # Enforce HTTPS for 1 year + X-Frame-Options "DENY" # Prevent embedding + -Server # Remove the Server header + Permissions-Policy "geolocation=(), microphone=(), camera=()" # No permissions + X-Content-Type-Options "nosniff" # Prevent MIME-type sniffing + Referrer-Policy "no-referrer-when-downgrade" # Control referrer behavior + } + tls damian@prime8.dev } +# Mail Server mail.prime8.dev { - tls damian@prime8.dev + header { + X-Robots-Tag "noindex, nofollow" # Prevent search engine indexing + + # Security + Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" # Enforce HTTPS for 1 year + X-Frame-Options "DENY" # Prevent embedding + -Server # Remove the Server header + Permissions-Policy "geolocation=(), microphone=(), camera=()" # No permissions + X-Content-Type-Options "nosniff" # Prevent MIME-type sniffing + Referrer-Policy "no-referrer-when-downgrade" # Control referrer behavior + } + tls damian@prime8.dev } +# Git Server git.prime8.dev { - reverse_proxy http://gitweb:80 - cache + reverse_proxy http://gitweb:80 - header { - X-Robots-Tag "index, nofollow" + # Caching + cache + header /static/* { + Cache-Control "public, max-age=86400; immutable" # Cache for 1 day + } + + # Rate Limiting + rate_limit { + burst 20 # Allow an initial burst of 20 requests + limit 10 # After the burst, allow 10 requests per minute } - tls damian@prime8.dev + header { + X-Robots-Tag "noindex, nofollow" # Prevent search engine indexing + + # Security + Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" # Enforce HTTPS for 1 year + X-Frame-Options "DENY" # Prevent embedding + -Server # Remove the Server header + Permissions-Policy "geolocation=(), microphone=(), camera=()" # No permissions + X-Content-Type-Options "nosniff" # Prevent MIME-type sniffing + Referrer-Policy "no-referrer-when-downgrade" # Control referrer behavior + } + tls damian@prime8.dev } +# CSC Website csc.prime8.dev { - reverse_proxy http://csc:80 - cache + reverse_proxy http://csc:80 - tls damian@prime8.dev + # Caching + cache + header /static/* { + Cache-Control "public, max-age=86400; immutable" # Cache for 1 day + } + + # Rate Limiting + rate_limit { + burst 20 # Allow an initial burst of 20 requests + limit 10 # After the burst, allow 10 requests per minute + } + + header { + X-Robots-Tag "noindex, nofollow" # Prevent search engine indexing + + # Security + Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" # Enforce HTTPS for 1 year + X-Frame-Options "DENY" # Prevent embedding + -Server # Remove the Server header + Permissions-Policy "geolocation=(), microphone=(), camera=()" # No permissions + X-Content-Type-Options "nosniff" # Prevent MIME-type sniffing + Referrer-Policy "no-referrer-when-downgrade" # Control referrer behavior + } + tls damian@prime8.dev } diff --git a/web/templates/404.html b/web/templates/404.html @@ -1,31 +1,9 @@ -{% extends "base.html" %} - -{% import "nav.html" as nav %} -{% block navbar %} -{{ nav::bar(active="") }} -{% endblock %} +{% extends "error.html" %} {% block title %} <title>not found</title> {% endblock %} -{% block content %} -<div id="message"> - <h1>not found</h1> -</div> -<style> - #content { - padding: 0px !important; - } - - #message { - display: flex; - justify-content: center; - align-items: center; - height: 100vh; - } -</style> -<script> - _386 = { fastLoad: true }; -</script> +{% block message %} +<h1 id="message">not found (404)</h1> {% endblock %} diff --git a/web/templates/429.html b/web/templates/429.html @@ -0,0 +1,9 @@ +{% extends "error.html" %} + +{% block title %} +<title>too many requests</title> +{% endblock %} + +{% block message %} +<h1 id="message">too many requests (429)</h1> +{% endblock %} diff --git a/web/templates/500.html b/web/templates/500.html @@ -0,0 +1,9 @@ +{% extends "error.html" %} + +{% block title %} +<title>server error</title> +{% endblock %} + +{% block message %} +<h1 id="message">server error (500)</h1> +{% endblock %} diff --git a/web/templates/error.html b/web/templates/error.html @@ -0,0 +1,29 @@ +{% extends "base.html" %} + +{% import "nav.html" as nav %} +{% block navbar %} +{{ nav::bar(active="") }} +{% endblock %} + +{% block content %} +<div> + {% block message %} + {% endblock %} +</div> +<style> + #content { + padding: 0px !important; + } + + #message { + color: #ff5555; + display: flex; + justify-content: center; + align-items: center; + height: 100vh; + } +</style> +<script> + _386 = { fastLoad: true }; +</script> +{% endblock %}