Self-hostable uptime monitor and status page on Django: HTTP checks, Lighthouse audits, SEO crawls, and email and Discord alerts.
djangodockerhandcodedpythonself-hostedsqlitestatus-pageuptime-monitoringvite
1import os
2from pathlib import Path
3
4from django.contrib.messages import constants as messages
5
6
7# Build paths inside the project like this: BASE_DIR / 'subdir'.
8BASE_DIR = Path(__file__).resolve().parent.parent.parent
9
10
11# Application definition
12
13INSTALLED_APPS = [
14 'django.contrib.admin',
15 'django.contrib.auth',
16 'django.contrib.contenttypes',
17 'django.contrib.sessions',
18 'django.contrib.messages',
19 'django.contrib.staticfiles',
20
21 'accounts',
22 'properties',
23 'pages',
24]
25
26MIDDLEWARE = [
27 'django.middleware.security.SecurityMiddleware',
28
29 'whitenoise.middleware.WhiteNoiseMiddleware',
30
31 'django.contrib.sessions.middleware.SessionMiddleware',
32 'django.middleware.common.CommonMiddleware',
33 'django.middleware.csrf.CsrfViewMiddleware',
34 'django.contrib.auth.middleware.AuthenticationMiddleware',
35 'django.contrib.messages.middleware.MessageMiddleware',
36 'django.middleware.clickjacking.XFrameOptionsMiddleware',
37]
38
39ROOT_URLCONF = 'status.urls'
40
41TEMPLATES = [
42 {
43 'BACKEND': 'django.template.backends.django.DjangoTemplates',
44 'DIRS': [BASE_DIR / 'status/templates'],
45 'APP_DIRS': True,
46 'OPTIONS': {
47 'context_processors': [
48 'django.template.context_processors.debug',
49 'django.template.context_processors.request',
50 'django.contrib.auth.context_processors.auth',
51 'django.contrib.messages.context_processors.messages',
52
53 'status.context_processors.canonical',
54 'status.context_processors.base_url',
55 ],
56 },
57 },
58]
59
60WSGI_APPLICATION = 'status.wsgi.application'
61
62
63# Messages
64# https://docs.djangoproject.com/en/3.0/ref/settings/#messages
65
66MESSAGE_TAGS = {
67 messages.DEBUG: "alert-info",
68 messages.INFO: "alert-info",
69 messages.SUCCESS: "alert-success",
70 messages.WARNING: "alert-warning",
71 messages.ERROR: "alert-danger",
72}
73
74
75# Internationalization
76# https://docs.djangoproject.com/en/4.0/topics/i18n/
77
78LANGUAGE_CODE = 'en-us'
79TIME_ZONE = 'UTC'
80USE_I18N = True
81USE_TZ = True
82USE_THOUSAND_SEPARATOR = True
83
84
85# Static files (CSS, JavaScript, Images)
86# https://docs.djangoproject.com/en/4.0/howto/static-files/
87
88STATIC_URL = 'static/'
89STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage"
90STATICFILES_DIRS = (BASE_DIR / "status/static",)
91STATIC_ROOT = BASE_DIR / "static"
92
93
94# Media files (Images, Videos)
95# https://docs.djangoproject.com/en/4.0/ref/settings/#media-root
96
97MEDIA_URL = 'media/'
98MEDIA_ROOT = BASE_DIR / "media"
99
100
101# Database
102# https://docs.djangoproject.com/en/4.0/ref/settings/#databases
103
104DATABASES = {
105 'default': {
106 'ENGINE': 'django.db.backends.sqlite3',
107 'NAME': BASE_DIR / 'db.sqlite3',
108 'OPTIONS': {
109 # WAL lets readers run concurrently with a writer; the scheduler
110 # has several worker threads, so the default rollback journal
111 # yields frequent "database is locked" errors. A 30s busy timeout
112 # gives contending writers a chance to serialize rather than
113 # fail, which previously stranded alert state mid-transition.
114 'timeout': 30,
115 'transaction_mode': 'IMMEDIATE',
116 # mmap_size is intentionally omitted: gunicorn workers and the
117 # scheduler each open their own connection, and SQLite's mmap is
118 # documented as unsafe for multi-process writers — it amplified
119 # an unrelated WAL inconsistency into full database corruption
120 # on 2026-04-19.
121 'init_command': (
122 'PRAGMA journal_mode=WAL;'
123 'PRAGMA synchronous=NORMAL;'
124 'PRAGMA foreign_keys=ON;'
125 'PRAGMA temp_store=MEMORY;'
126 'PRAGMA journal_size_limit=67108864;'
127 'PRAGMA cache_size=-20000;'
128 ),
129 },
130 }
131}
132
133
134# Default primary key field type
135# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field
136
137DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
138
139
140# Auth
141# https://docs.djangoproject.com/en/3.0/ref/settings/#auth
142
143AUTH_USER_MODEL = "accounts.User"
144LOGIN_REDIRECT_URL = "properties"
145
146
147# Email
148# https://docs.djangoproject.com/en/4.0/topics/email/#console-backend
149
150EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'