Skip to content

Commit 6203a1c

Browse files
committed
feat: implement helpful error pages per #194
1 parent 53ca337 commit 6203a1c

File tree

3 files changed

+299
-0
lines changed

3 files changed

+299
-0
lines changed

create-a-container/views/nginx-conf.ejs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,13 @@ http {
6868
add_header Alt-Svc 'h3=":443"; ma=86400' always;
6969

7070
<%_ if (httpServices.length === 0) { _%>
71+
error_page 502 @502;
72+
73+
location @502 {
74+
root /opt/opensource-server/error-pages;
75+
try_files /502.html =502;
76+
}
77+
7178
location / {
7279
proxy_pass http://localhost:3000;
7380
proxy_http_version 1.1;
@@ -97,6 +104,13 @@ http {
97104
client_max_body_size 2G;
98105
}
99106
<%_ } else { _%>
107+
error_page 404 @404;
108+
109+
location @404 {
110+
root /opt/opensource-server/error-pages;
111+
try_files /404.html =404;
112+
}
113+
100114
return 404;
101115
<%_ } _%>
102116
}
@@ -133,6 +147,13 @@ http {
133147
add_header X-XSS-Protection "1; mode=block" always;
134148
add_header Alt-Svc 'h3=":443"; ma=86400' always;
135149
150+
error_page 502 @502;
151+
152+
location @502 {
153+
root /opt/opensource-server/error-pages;
154+
try_files /502.html =502;
155+
}
156+
136157
# Proxy settings
137158
location / {
138159
proxy_pass http://<%= service.Container.ipv4Address %>:<%= service.internalPort %>;
@@ -198,6 +219,13 @@ http {
198219
add_header X-XSS-Protection "1; mode=block" always;
199220
add_header Alt-Svc 'h3=":443"; ma=86400' always;
200221
222+
error_page 404 @404;
223+
224+
location @404 {
225+
root /opt/opensource-server/error-pages;
226+
try_files /404.html =404;
227+
}
228+
201229
# Return 404 for all requests
202230
return 404;
203231
}
@@ -234,6 +262,13 @@ http {
234262
add_header X-XSS-Protection "1; mode=block" always;
235263
add_header Alt-Svc 'h3=":443"; ma=86400' always;
236264
265+
error_page 502 @502;
266+
267+
location @502 {
268+
root /opt/opensource-server/error-pages;
269+
try_files /502.html =502;
270+
}
271+
237272
# Proxy to documentation site
238273
location / {
239274
proxy_pass http://localhost:2998;

error-pages/404.html

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>404 — No Service Configured</title>
7+
<style>
8+
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
9+
10+
body {
11+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
12+
background: linear-gradient(135deg, #0f0f23 0%, #1a1a2e 50%, #16213e 100%);
13+
color: #e0e0e0;
14+
min-height: 100vh;
15+
display: flex;
16+
align-items: center;
17+
justify-content: center;
18+
position: relative;
19+
overflow: hidden;
20+
}
21+
22+
body::before {
23+
content: '';
24+
position: absolute;
25+
inset: 0;
26+
background-image:
27+
linear-gradient(rgba(255,255,255,0.05) 1px, transparent 1px),
28+
linear-gradient(90deg, rgba(255,255,255,0.05) 1px, transparent 1px);
29+
background-size: 30px 30px;
30+
pointer-events: none;
31+
}
32+
33+
.container {
34+
position: relative;
35+
max-width: 620px;
36+
width: 90%;
37+
padding: 3rem 2.5rem;
38+
background: rgba(0, 0, 0, 0.5);
39+
border: 1px solid rgba(255, 255, 255, 0.1);
40+
border-radius: 20px;
41+
text-align: center;
42+
}
43+
44+
.status-code {
45+
font-size: 5rem;
46+
font-weight: 700;
47+
background: linear-gradient(135deg, #00bfff, #8a2be2);
48+
-webkit-background-clip: text;
49+
-webkit-text-fill-color: transparent;
50+
background-clip: text;
51+
line-height: 1.1;
52+
}
53+
54+
h1 {
55+
font-size: 1.5rem;
56+
font-weight: 600;
57+
color: #fff;
58+
margin: 0.5rem 0 1.5rem;
59+
}
60+
61+
p {
62+
font-size: 1rem;
63+
line-height: 1.6;
64+
color: #b0b0b0;
65+
margin-bottom: 1rem;
66+
}
67+
68+
.note {
69+
margin-top: 1.5rem;
70+
padding: 1rem 1.25rem;
71+
background: rgba(27, 170, 39, 0.1);
72+
border: 1px solid rgba(27, 170, 39, 0.3);
73+
border-radius: 10px;
74+
font-size: 0.9rem;
75+
color: #c0c0c0;
76+
text-align: left;
77+
}
78+
79+
.note strong {
80+
color: #1baa27;
81+
}
82+
83+
.hostname {
84+
display: inline-block;
85+
margin-top: 0.5rem;
86+
padding: 0.25rem 0.75rem;
87+
background: rgba(255, 255, 255, 0.08);
88+
border-radius: 6px;
89+
font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
90+
font-size: 0.85rem;
91+
color: #00bfff;
92+
word-break: break-all;
93+
}
94+
</style>
95+
</head>
96+
<body>
97+
<div class="container">
98+
<div class="status-code">404</div>
99+
<h1>No Service Configured</h1>
100+
<p>
101+
There is no service registered for this hostname.
102+
</p>
103+
<div class="hostname" id="hostname"></div>
104+
<div class="note">
105+
<strong>Recently configured a service?</strong>
106+
Configuration changes may take a few minutes to propagate.
107+
Try refreshing this page shortly.
108+
</div>
109+
</div>
110+
<script>
111+
document.getElementById('hostname').textContent = window.location.hostname;
112+
</script>
113+
</body>
114+
</html>

error-pages/502.html

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>502 — Service Unavailable</title>
7+
<style>
8+
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
9+
10+
body {
11+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
12+
background: linear-gradient(135deg, #0f0f23 0%, #1a1a2e 50%, #16213e 100%);
13+
color: #e0e0e0;
14+
min-height: 100vh;
15+
display: flex;
16+
align-items: center;
17+
justify-content: center;
18+
position: relative;
19+
overflow: hidden;
20+
}
21+
22+
body::before {
23+
content: '';
24+
position: absolute;
25+
inset: 0;
26+
background-image:
27+
linear-gradient(rgba(255,255,255,0.05) 1px, transparent 1px),
28+
linear-gradient(90deg, rgba(255,255,255,0.05) 1px, transparent 1px);
29+
background-size: 30px 30px;
30+
pointer-events: none;
31+
}
32+
33+
.container {
34+
position: relative;
35+
max-width: 620px;
36+
width: 90%;
37+
padding: 3rem 2.5rem;
38+
background: rgba(0, 0, 0, 0.5);
39+
border: 1px solid rgba(255, 255, 255, 0.1);
40+
border-radius: 20px;
41+
text-align: center;
42+
}
43+
44+
.status-code {
45+
font-size: 5rem;
46+
font-weight: 700;
47+
background: linear-gradient(135deg, #00bfff, #8a2be2);
48+
-webkit-background-clip: text;
49+
-webkit-text-fill-color: transparent;
50+
background-clip: text;
51+
line-height: 1.1;
52+
}
53+
54+
h1 {
55+
font-size: 1.5rem;
56+
font-weight: 600;
57+
color: #fff;
58+
margin: 0.5rem 0 1.5rem;
59+
}
60+
61+
p {
62+
font-size: 1rem;
63+
line-height: 1.6;
64+
color: #b0b0b0;
65+
margin-bottom: 1rem;
66+
}
67+
68+
.troubleshooting {
69+
margin-top: 1.5rem;
70+
padding: 1.25rem;
71+
background: rgba(255, 255, 255, 0.04);
72+
border: 1px solid rgba(255, 255, 255, 0.1);
73+
border-radius: 10px;
74+
text-align: left;
75+
}
76+
77+
.troubleshooting h2 {
78+
font-size: 0.95rem;
79+
font-weight: 600;
80+
color: #fff;
81+
margin-bottom: 0.75rem;
82+
}
83+
84+
.troubleshooting ul {
85+
list-style: none;
86+
padding: 0;
87+
}
88+
89+
.troubleshooting li {
90+
position: relative;
91+
padding: 0.4rem 0 0.4rem 1.5rem;
92+
font-size: 0.9rem;
93+
line-height: 1.5;
94+
color: #b0b0b0;
95+
}
96+
97+
.troubleshooting li::before {
98+
content: '›';
99+
position: absolute;
100+
left: 0.25rem;
101+
color: #1baa27;
102+
font-weight: 700;
103+
font-size: 1.1rem;
104+
}
105+
106+
.troubleshooting code {
107+
padding: 0.15rem 0.4rem;
108+
background: rgba(255, 255, 255, 0.08);
109+
border-radius: 4px;
110+
font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
111+
font-size: 0.8rem;
112+
color: #00bfff;
113+
}
114+
115+
.hostname {
116+
display: inline-block;
117+
margin-top: 0.5rem;
118+
padding: 0.25rem 0.75rem;
119+
background: rgba(255, 255, 255, 0.08);
120+
border-radius: 6px;
121+
font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
122+
font-size: 0.85rem;
123+
color: #00bfff;
124+
word-break: break-all;
125+
}
126+
</style>
127+
</head>
128+
<body>
129+
<div class="container">
130+
<div class="status-code">502</div>
131+
<h1>Service Unavailable</h1>
132+
<p>
133+
A service is configured for this hostname, but the upstream is not responding.
134+
</p>
135+
<div class="hostname" id="hostname"></div>
136+
<div class="troubleshooting">
137+
<h2>Troubleshooting</h2>
138+
<ul>
139+
<li>Check that the service is running inside the container.</li>
140+
<li>Verify the configured port matches the port your service is listening on.</li>
141+
<li>Ensure the service binds to <code>0.0.0.0</code> (all interfaces), not <code>127.0.0.1</code> (localhost only).</li>
142+
<li>Check that no firewall rules inside the container are blocking incoming connections.</li>
143+
</ul>
144+
</div>
145+
</div>
146+
<script>
147+
document.getElementById('hostname').textContent = window.location.hostname;
148+
</script>
149+
</body>
150+
</html>

0 commit comments

Comments
 (0)