Added custom page
This commit is contained in:
parent
96c864e1d2
commit
edb60952c7
28
default.conf
Normal file
28
default.conf
Normal file
@ -0,0 +1,28 @@
|
||||
server {
|
||||
listen 80 default_server;
|
||||
listen [::]:80 default_server;
|
||||
|
||||
root /var/www/html;
|
||||
|
||||
index index.html index.htm index.nginx-debian.html;
|
||||
|
||||
server_name _;
|
||||
|
||||
# === custom error pages ===
|
||||
error_page 404 /errors/404.html;
|
||||
error_page 500 502 503 504 /errors/50x.html;
|
||||
|
||||
location = /errors/404.html {
|
||||
root /var/www;
|
||||
internal;
|
||||
}
|
||||
|
||||
location = /errors/50x.html {
|
||||
root /var/www;
|
||||
internal;
|
||||
}
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ =404;
|
||||
}
|
||||
}
|
||||
95
http/404.html
Normal file
95
http/404.html
Normal file
@ -0,0 +1,95 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>404 | Page Lost in the Void</title>
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: #050814;
|
||||
color: #e5e5e5;
|
||||
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
}
|
||||
.card {
|
||||
text-align: center;
|
||||
padding: 2.5rem 3rem;
|
||||
border-radius: 1rem;
|
||||
background: radial-gradient(circle at top, #1e293b, #020617);
|
||||
box-shadow: 0 0 40px rgba(15, 23, 42, 0.9);
|
||||
}
|
||||
.code {
|
||||
font-size: 4rem;
|
||||
letter-spacing: 0.2em;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
.glitch {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
font-size: 1.4rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.25em;
|
||||
}
|
||||
.glitch::before,
|
||||
.glitch::after {
|
||||
content: attr(data-text);
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
overflow: hidden;
|
||||
clip-path: inset(0 0 50% 0);
|
||||
opacity: 0.7;
|
||||
animation: glitch 1.6s infinite linear alternate-reverse;
|
||||
}
|
||||
.glitch::before {
|
||||
transform: translate(-2px, -1px);
|
||||
}
|
||||
.glitch::after {
|
||||
transform: translate(2px, 1px);
|
||||
clip-path: inset(50% 0 0 0);
|
||||
}
|
||||
@keyframes glitch {
|
||||
0% { transform: translate(0, 0); }
|
||||
20% { transform: translate(-3px, 2px); }
|
||||
40% { transform: translate(2px, -2px); }
|
||||
60% { transform: translate(-2px, 1px); }
|
||||
80% { transform: translate(1px, -1px); }
|
||||
100% { transform: translate(0, 0); }
|
||||
}
|
||||
p {
|
||||
margin-top: 1rem;
|
||||
font-size: 0.95rem;
|
||||
opacity: 0.8;
|
||||
}
|
||||
a {
|
||||
display: inline-block;
|
||||
margin-top: 1.5rem;
|
||||
padding: 0.6rem 1.4rem;
|
||||
border-radius: 999px;
|
||||
border: 1px solid rgba(148, 163, 184, 0.6);
|
||||
text-decoration: none;
|
||||
color: #e5e5e5;
|
||||
font-size: 0.9rem;
|
||||
backdrop-filter: blur(4px);
|
||||
}
|
||||
a:hover {
|
||||
background: rgba(148, 163, 184, 0.15);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="card">
|
||||
<div class="code">404</div>
|
||||
<div class="glitch" data-text="NOT FOUND">NOT FOUND</div>
|
||||
<p>
|
||||
The page you’re looking for has drifted out of this universe.<br />
|
||||
Check the URL or head back to the safe zone.
|
||||
</p>
|
||||
<a href="/">Return to Home</a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
178
http/50x.html
Normal file
178
http/50x.html
Normal file
@ -0,0 +1,178 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>5xx | Server is on Fire</title>
|
||||
<style>
|
||||
:root {
|
||||
color-scheme: dark;
|
||||
}
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: radial-gradient(circle at top, #111827 0%, #020617 55%, #000 100%);
|
||||
color: #f9fafb;
|
||||
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
.card {
|
||||
position: relative;
|
||||
text-align: center;
|
||||
padding: 2.8rem 3.2rem;
|
||||
border-radius: 1.25rem;
|
||||
background: linear-gradient(145deg, rgba(15,23,42,0.95), rgba(30,64,175,0.9));
|
||||
box-shadow:
|
||||
0 0 30px rgba(0,0,0,0.8),
|
||||
0 0 80px rgba(248,113,113,0.5);
|
||||
max-width: 480px;
|
||||
width: 90%;
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
.code {
|
||||
font-size: 3.6rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.2em;
|
||||
text-transform: uppercase;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
.subtitle {
|
||||
font-size: 1rem;
|
||||
letter-spacing: 0.16em;
|
||||
text-transform: uppercase;
|
||||
opacity: 0.85;
|
||||
}
|
||||
.flames {
|
||||
position: absolute;
|
||||
inset: auto -10%;
|
||||
bottom: -2.5rem;
|
||||
height: 80px;
|
||||
pointer-events: none;
|
||||
opacity: 0.95;
|
||||
mix-blend-mode: screen;
|
||||
}
|
||||
.flame {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 26px;
|
||||
height: 80px;
|
||||
background: radial-gradient(circle at 20% 0%, #fef3c7 0, #f97316 40%, #b91c1c 70%, transparent 80%);
|
||||
border-radius: 50% 50% 0 0;
|
||||
filter: blur(1px);
|
||||
animation: rise 1.4s infinite ease-in-out alternate;
|
||||
opacity: 0.9;
|
||||
}
|
||||
.flame:nth-child(1) { left: 10%; animation-delay: -0.1s; transform-origin: 50% 100%; }
|
||||
.flame:nth-child(2) { left: 25%; animation-delay: -0.4s; transform-origin: 50% 100%; }
|
||||
.flame:nth-child(3) { left: 50%; animation-delay: -0.2s; transform-origin: 50% 100%; }
|
||||
.flame:nth-child(4) { left: 70%; animation-delay: -0.6s; transform-origin: 50% 100%; }
|
||||
.flame:nth-child(5) { left: 86%; animation-delay: -0.3s; transform-origin: 50% 100%; }
|
||||
|
||||
@keyframes rise {
|
||||
0% { transform: scaleY(0.7) translateY(10px); opacity: 0.6; }
|
||||
50% { transform: scaleY(1.05) translateY(-6px); opacity: 1; }
|
||||
100% { transform: scaleY(0.85) translateY(4px); opacity: 0.7; }
|
||||
}
|
||||
|
||||
.text {
|
||||
margin-top: 1.4rem;
|
||||
font-size: 0.96rem;
|
||||
line-height: 1.6;
|
||||
opacity: 0.9;
|
||||
}
|
||||
.hint {
|
||||
margin-top: 0.75rem;
|
||||
font-size: 0.8rem;
|
||||
opacity: 0.6;
|
||||
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
}
|
||||
.btn-row {
|
||||
margin-top: 1.8rem;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 0.75rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
a.btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 0.4rem;
|
||||
padding: 0.55rem 1.35rem;
|
||||
border-radius: 999px;
|
||||
border: 1px solid rgba(148,163,184,0.7);
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
font-size: 0.85rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.12em;
|
||||
background: rgba(15,23,42,0.8);
|
||||
backdrop-filter: blur(6px);
|
||||
white-space: nowrap;
|
||||
}
|
||||
a.btn:hover {
|
||||
background: rgba(248,113,113,0.15);
|
||||
border-color: rgba(248,113,113,0.7);
|
||||
}
|
||||
.emoji {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.card {
|
||||
padding: 2.1rem 1.7rem;
|
||||
}
|
||||
.code {
|
||||
font-size: 3rem;
|
||||
}
|
||||
.subtitle {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
.text {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="card">
|
||||
<div class="code">5XX</div>
|
||||
<div class="subtitle">SERVER IS ON FIRE</div>
|
||||
|
||||
<div class="text">
|
||||
Something on the backend just went very wrong.<br />
|
||||
Your request didn’t make it through, but the logs definitely did.
|
||||
</div>
|
||||
|
||||
<div class="hint">
|
||||
Tip: If you’re the admin, check your upstreams, containers, and error logs.<br />
|
||||
If you’re not, maybe just pretend this never happened.
|
||||
</div>
|
||||
|
||||
<div class="btn-row">
|
||||
<a href="/" class="btn">
|
||||
<span class="emoji">🏠</span>
|
||||
<span>Back to Safety</span>
|
||||
</a>
|
||||
<a href="https://x.com/nik4nao" class="btn">
|
||||
<span class="emoji">🧯</span>
|
||||
<span>Alert Admin</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="flames">
|
||||
<div class="flame"></div>
|
||||
<div class="flame"></div>
|
||||
<div class="flame"></div>
|
||||
<div class="flame"></div>
|
||||
<div class="flame"></div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@ -35,6 +35,24 @@ server {
|
||||
# proxy_redirect off;
|
||||
}
|
||||
|
||||
# ---- Jellyfin at /anime/ ----
|
||||
location = /anime { return 302 /anime/; } # enforce trailing slash
|
||||
|
||||
location /anime/ {
|
||||
proxy_pass http://anime_upstream/; # uses upstream (or use the raw URL)
|
||||
proxy_next_upstream error timeout invalid_header http_502 http_503 http_504;
|
||||
include snippets/proxy-common.conf;
|
||||
|
||||
# Jellyfin behind subpath specifics
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection $connection_upgrade;
|
||||
proxy_set_header X-Forwarded-Host $host;
|
||||
proxy_set_header X-Forwarded-Prefix /anime;
|
||||
|
||||
# (Optional) if you see odd redirects, uncomment:
|
||||
# proxy_redirect off;
|
||||
}
|
||||
|
||||
# ---- Pi-hole admin at /admin/ ----
|
||||
# Pi-hole’s UI lives under /admin/, so keep the trailing slash in proxy_pass.
|
||||
location /admin/ {
|
||||
|
||||
@ -57,6 +57,11 @@ server {
|
||||
add_header X-Frame-Options "DENY" always;
|
||||
add_header X-Robots-Tag "noindex, nofollow, noimageindex, nosnippet, noarchive" always;
|
||||
|
||||
# Custom error pages for public site
|
||||
proxy_intercept_errors on;
|
||||
error_page 404 /errors/404.html;
|
||||
error_page 500 502 503 504 /errors/50x.html;
|
||||
|
||||
# (Optional) Block noncompliant AI bots (requires $block_ai map in nginx.conf)
|
||||
if ($block_ai) { return 403; }
|
||||
|
||||
@ -109,6 +114,18 @@ server {
|
||||
proxy_read_timeout 60s;
|
||||
}
|
||||
|
||||
# Deny anything unexpected
|
||||
# Pretty error pages (served from disk, not directly reachable)
|
||||
location = /errors/404.html {
|
||||
root /var/www;
|
||||
internal;
|
||||
}
|
||||
|
||||
location = /errors/50x.html {
|
||||
root /var/www;
|
||||
internal;
|
||||
}
|
||||
|
||||
# Deny anything unexpected
|
||||
location / {
|
||||
return 404;
|
||||
|
||||
@ -12,4 +12,10 @@ upstream pihole_upstream {
|
||||
upstream watchparty_upstream {
|
||||
server 192.168.7.96:3000;
|
||||
keepalive 16;
|
||||
}
|
||||
}
|
||||
|
||||
upstream anime_upstream {
|
||||
server 192.168.7.78:8096 max_fails=2 fail_timeout=3s;
|
||||
server 192.168.7.7:8096 backup;
|
||||
keepalive 16;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user