Self-hostable uptime monitor and status page on Django: HTTP checks, Lighthouse audits, SEO crawls, and email and Discord alerts.
djangodockerhandcodedpythonself-hostedsqlitestatus-pageuptime-monitoringvite
1<!DOCTYPE html>
2<html lang="en">
3 <head>
4 <meta charset="utf-8">
5 <meta http-equiv="x-ua-compatible" content="ie=edge">
6 <meta name="viewport" content="width=device-width, initial-scale=1">
7 <meta name="x-apple-disable-message-reformatting">
8 <meta name="color-scheme" content="dark">
9 <meta name="supported-color-schemes" content="dark">
10 <meta name="format-detection" content="telephone=no, date=no, address=no, email=no">
11 <title>{{ email_title }}</title>
12 <style type="text/css">
13 body { margin: 0 !important; padding: 0 !important; background: #0e0d0a !important; }
14 table { border-collapse: collapse; }
15 img { border: 0; display: block; }
16 a { color: #7db88c; text-decoration: none; }
17 a:hover { text-decoration: underline; }
18 @media (max-width: 620px) {
19 .shell { width: 100% !important; }
20 .px-pad { padding-left: 22px !important; padding-right: 22px !important; }
21 .kv-key { width: 100% !important; display: block !important; border-left: 0 !important; padding: 14px 0 0 0 !important; }
22 .kv-val { width: 100% !important; display: block !important; border-left: 0 !important; padding: 4px 0 14px 0 !important; }
23 }
24 </style>
25 </head>
26 <body style="margin: 0; padding: 0; background-color: #0e0d0a; color: #ddd7cd; font-family: ui-monospace, 'Cascadia Code', 'SF Mono', Menlo, Consolas, monospace; font-size: 14px; line-height: 1.65;">
27
28 <div style="display: none; max-height: 0; overflow: hidden; mso-hide: all; font-size: 1px; line-height: 1px; color: #0e0d0a;">{{ preheader }}</div>
29
30 <table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%" style="background-color: #0e0d0a;">
31 <tr>
32 <td align="center" style="padding: 40px 16px;">
33
34 <table role="presentation" cellpadding="0" cellspacing="0" border="0" class="shell" width="560" style="width: 100%; max-width: 560px;">
35 <tr>
36 <td class="px-pad" style="padding: 0 0 18px 0;">
37 <table role="presentation" cellpadding="0" cellspacing="0" border="0">
38 <tr>
39 <td style="vertical-align: middle; padding-right: 10px; line-height: 0;">
40 <span style="display: inline-block; width: 8px; height: 8px; background-color: #6b9e78; border-radius: 50%; box-shadow: 0 0 0 3px rgba(107,158,120,0.18);"></span>
41 </td>
42 <td style="vertical-align: middle; color: #ede8e0; font-family: ui-monospace, 'Cascadia Code', 'SF Mono', Menlo, Consolas, monospace; font-size: 12px; letter-spacing: 0.18em; text-transform: uppercase; font-weight: 700;">
43 // Status
44 </td>
45 </tr>
46 </table>
47 </td>
48 </tr>
49 </table>
50
51 <table role="presentation" cellpadding="0" cellspacing="0" border="0" class="shell" width="560" style="width: 100%; max-width: 560px; background-color: #13120e; border: 1px solid {{ accent_border }};">
52 <tr>
53 <td style="height: 3px; background-color: {{ accent }}; line-height: 3px; font-size: 0;"> </td>
54 </tr>
55
56 <tr>
57 <td class="px-pad" style="padding: 30px 32px 6px 32px;">
58 <table role="presentation" cellpadding="0" cellspacing="0" border="0">
59 <tr>
60 <td style="vertical-align: middle; padding-right: 8px; line-height: 0;">
61 <span style="display: inline-block; width: 7px; height: 7px; background-color: {{ accent }}; border-radius: 50%;"></span>
62 </td>
63 <td style="vertical-align: middle; color: {{ accent_bright }}; font-family: ui-monospace, 'Cascadia Code', 'SF Mono', Menlo, Consolas, monospace; font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase; font-weight: 700;">
64 {{ status_label }}
65 </td>
66 </tr>
67 </table>
68 </td>
69 </tr>
70
71 <tr>
72 <td class="px-pad" style="padding: 14px 32px 4px 32px;">
73 <h1 style="margin: 0; color: #ede8e0; font-family: ui-monospace, 'Cascadia Code', 'SF Mono', Menlo, Consolas, monospace; font-size: 26px; line-height: 1.25; font-weight: 700; letter-spacing: -0.01em;">
74 {{ event_title }}
75 </h1>
76 </td>
77 </tr>
78
79 <tr>
80 <td class="px-pad" style="padding: 14px 32px 26px 32px; color: #a09890; font-size: 14px; line-height: 1.75;">
81 {{ event_copy }}
82 </td>
83 </tr>
84
85 <tr>
86 <td class="px-pad" style="padding: 0 32px 6px 32px;">
87 <div style="font-family: ui-monospace, 'Cascadia Code', 'SF Mono', Menlo, Consolas, monospace; font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; color: #c9a84c; padding: 0 0 10px 0; font-weight: 700;">
88 / Property
89 </div>
90 <table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%" style="border: 1px solid rgba(107,158,120,0.12); background: rgba(9,8,6,0.5);">
91 <tr>
92 <td class="kv-key" width="32%" style="padding: 12px 14px; color: #665f56; font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase; font-weight: 700; vertical-align: top; font-family: ui-monospace, 'Cascadia Code', 'SF Mono', Menlo, Consolas, monospace;">Name</td>
93 <td class="kv-val" style="padding: 12px 14px; color: #ede8e0; font-size: 13px; font-family: ui-monospace, 'Cascadia Code', 'SF Mono', Menlo, Consolas, monospace; border-left: 1px solid rgba(107,158,120,0.08); vertical-align: top; word-break: break-word;">{{ property.name }}</td>
94 </tr>
95 <tr>
96 <td class="kv-key" style="padding: 12px 14px; color: #665f56; font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase; font-weight: 700; border-top: 1px solid rgba(107,158,120,0.08); vertical-align: top; font-family: ui-monospace, 'Cascadia Code', 'SF Mono', Menlo, Consolas, monospace;">URL</td>
97 <td class="kv-val" style="padding: 12px 14px; font-size: 13px; font-family: ui-monospace, 'Cascadia Code', 'SF Mono', Menlo, Consolas, monospace; border-top: 1px solid rgba(107,158,120,0.08); border-left: 1px solid rgba(107,158,120,0.08); vertical-align: top; word-break: break-all;">
98 <a href="{{ property.url }}" style="color: #7db88c; text-decoration: none;">{{ property.url }}</a>
99 </td>
100 </tr>
101 <tr>
102 <td class="kv-key" style="padding: 12px 14px; color: #665f56; font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase; font-weight: 700; border-top: 1px solid rgba(107,158,120,0.08); vertical-align: top; font-family: ui-monospace, 'Cascadia Code', 'SF Mono', Menlo, Consolas, monospace;">Status</td>
103 <td class="kv-val" style="padding: 12px 14px; font-size: 13px; font-family: ui-monospace, 'Cascadia Code', 'SF Mono', Menlo, Consolas, monospace; border-top: 1px solid rgba(107,158,120,0.08); border-left: 1px solid rgba(107,158,120,0.08); vertical-align: top;">
104 <span style="display: inline-block; background-color: {{ accent_tint }}; color: {{ accent_bright }}; border: 1px solid {{ accent_border }}; padding: 3px 9px; font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; font-weight: 700;">{{ property.current_status }}</span>
105 </td>
106 </tr>
107 <tr>
108 <td class="kv-key" style="padding: 12px 14px; color: #665f56; font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase; font-weight: 700; border-top: 1px solid rgba(107,158,120,0.08); vertical-align: top; font-family: ui-monospace, 'Cascadia Code', 'SF Mono', Menlo, Consolas, monospace;">Avg time</td>
109 <td class="kv-val" style="padding: 12px 14px; color: #ede8e0; font-size: 13px; font-family: ui-monospace, 'Cascadia Code', 'SF Mono', Menlo, Consolas, monospace; border-top: 1px solid rgba(107,158,120,0.08); border-left: 1px solid rgba(107,158,120,0.08); vertical-align: top;">{{ property.avg_response_time }} ms</td>
110 </tr>
111 </table>
112 </td>
113 </tr>
114
115 <tr>
116 <td class="px-pad" style="padding: 26px 32px 32px 32px;">
117 <table role="presentation" cellpadding="0" cellspacing="0" border="0">
118 <tr>
119 <td style="background-color: {{ accent_tint }}; border: 1px solid {{ accent_border }};">
120 <a href="{{ BASE_URL }}/properties/{{ property.id }}/" style="display: inline-block; padding: 12px 22px; color: {{ accent_bright }}; font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; font-weight: 700; text-decoration: none; font-family: ui-monospace, 'Cascadia Code', 'SF Mono', Menlo, Consolas, monospace;">
121 View property →
122 </a>
123 </td>
124 </tr>
125 </table>
126 </td>
127 </tr>
128 </table>
129
130 <table role="presentation" cellpadding="0" cellspacing="0" border="0" class="shell" width="560" style="width: 100%; max-width: 560px;">
131 <tr>
132 <td class="px-pad" style="padding: 24px 0 0 0; color: #4a443c; font-size: 11px; line-height: 1.8; letter-spacing: 0.02em;">
133 Self-hosted monitoring · HTTP checks every three minutes<br>
134 Alerts fire only on state transitions. Manage notifications from your <a href="{{ BASE_URL }}/accounts/profile/" style="color: #665f56; text-decoration: underline;">profile</a>.
135 </td>
136 </tr>
137 </table>
138
139 </td>
140 </tr>
141 </table>
142 </body>
143</html>