diff --git a/aleksis/core/apps.py b/aleksis/core/apps.py
index 1647161460720845a42f4b5896622048b32c07ae..aaee34bc1439fb045626ec07768f7b9555c67ef7 100644
--- a/aleksis/core/apps.py
+++ b/aleksis/core/apps.py
@@ -1,5 +1,6 @@
 from django.apps import AppConfig, apps
-from django.db.models.signals import post_save
+
+from constance.signals import config_updated
 
 from .signals import clean_scss
 
@@ -10,4 +11,4 @@ class CoreConfig(AppConfig):
 
     def ready(self) -> None:
         clean_scss()
-        post_save.connect(clean_scss, sender=apps.get_model("dbsettings", "Setting"))
+        config_updated.connect(clean_scss)
diff --git a/aleksis/core/mailer.py b/aleksis/core/mailer.py
index 6cd4c0c98cb0927e6aa72c0561a5327c10a67cad..e4dc6b4479ccd9e1ca5644108c3e0be7ed6ca4d5 100644
--- a/aleksis/core/mailer.py
+++ b/aleksis/core/mailer.py
@@ -1,10 +1,14 @@
 from django.core.mail import send_mail
 from django.template.loader import render_to_string
 
-SENDER_EMAIL = 'SchoolApps <infoplan@katharineum.de>'
+from constance import config
 
 
-def send_mail_with_template(title, receivers, plain_template, html_template, context={}, sender_email=SENDER_EMAIL):
+mail_out = "{} <{}>".format(config.MAIL_OUT_NAME,
+                            config.MAIL_OUT) if config.MAIL_OUT_NAME else config.MAIL_OUT
+
+
+def send_mail_with_template(title, receivers, plain_template, html_template, context={}, mail_out=mail_out):
     msg_plain = render_to_string(plain_template, context)
     msg_html = render_to_string(html_template, context)
 
@@ -12,7 +16,7 @@ def send_mail_with_template(title, receivers, plain_template, html_template, con
         send_mail(
             title,
             msg_plain,
-            sender_email,
+            mail_out,
             receivers,
             html_message=msg_html,
         )
diff --git a/aleksis/core/menus.py b/aleksis/core/menus.py
index c4ba24e2ab87e783a358721d90028e0a8c77b96a..a7662bc719438e5486d620bbb64127dfd347c7a5 100644
--- a/aleksis/core/menus.py
+++ b/aleksis/core/menus.py
@@ -129,8 +129,9 @@ MENUS = {
         },
     ],
     "FOOTER_MENU_CORE": [
-        {"name": _("Website"), "url": "https://aleksis.edugit.org/"},
+        {"name": _("Website"), "url": "https://aleksis.edugit.io/"},
         {"name": "Teckids e.V.", "url": "https://www.teckids.org/"},
+        {"name": "Katharineum zu Lübeck", "url": "https://katharineum-zu-luebeck.de"}
     ],
     "DATA_MANAGEMENT_MENU": [],
     "SCHOOL_MANAGEMENT_MENU": [
diff --git a/aleksis/core/models.py b/aleksis/core/models.py
index 811cfaeb03c17393a95668abce719e4e7470544c..c3faec8d52d4b86df75202d5ab4ba3f0afca6d0d 100644
--- a/aleksis/core/models.py
+++ b/aleksis/core/models.py
@@ -5,8 +5,6 @@ from django.contrib.auth.models import User
 from django.db import models
 from django.utils import timezone
 from django.utils.translation import ugettext_lazy as _
-
-import dbsettings
 from image_cropping import ImageCropField, ImageRatioField
 from phonenumber_field.modelfields import PhoneNumberField
 
@@ -14,14 +12,6 @@ from .mailer import send_mail_with_template
 from .mixins import ExtensibleModel
 
 
-class ThemeSettings(dbsettings.Group):
-    colour_primary = dbsettings.StringValue(default="#007bff")
-    colour_secondary = dbsettings.StringValue(default="#007bff")
-
-
-theme_settings = ThemeSettings("Global theme settings")
-
-
 class School(models.Model):
     """A school that will have many other objects linked to it.
     AlekSIS has multi-tenant support by linking all objects to a school,
diff --git a/aleksis/core/settings.py b/aleksis/core/settings.py
index 8fe5e7f5e8356e78b22127291ffc21f48c0a01d5..e92f3f847e5c1c9361f7803ca2c0ad2f4528b3a3 100644
--- a/aleksis/core/settings.py
+++ b/aleksis/core/settings.py
@@ -53,7 +53,7 @@ INSTALLED_APPS = [
     "settings_context_processor",
     "sass_processor",
     "easyaudit",
-    "dbsettings",
+    "constance",
     "django_any_js",
     "django_yarnpkg",
     "django_tables2",
@@ -119,6 +119,7 @@ TEMPLATES = [
                 "django.contrib.messages.context_processors.messages",
                 "maintenance_mode.context_processors.maintenance_mode",
                 "settings_context_processor.context_processors.settings",
+                "constance.context_processors.config"
             ],
         },
     },
@@ -231,6 +232,7 @@ NODE_MODULES_ROOT = _settings.get("node_modules.root", os.path.join(BASE_DIR, "n
 
 YARN_INSTALLED_APPS = ["datatables", "highlight.js", "jquery", "manup", "materialize-css", "moment", "popper.js",
                        "prop-types", "react", "react-dom", "material-design-icons-iconfont", "select2"]
+YARN_INSTALLED_APPS = ["datatables", "jquery", "materialize-css", "material-design-icons-iconfont", "select2"]
 
 JS_URL = _settings.get("js_assets.url", STATIC_URL)
 JS_ROOT = _settings.get("js_assets.root", NODE_MODULES_ROOT + "/node_modules")
@@ -249,7 +251,7 @@ ANY_JS = {
 SASS_PROCESSOR_AUTO_INCLUDE = False
 SASS_PROCESSOR_CUSTOM_FUNCTIONS = {
     "get-colour": "aleksis.core.util.sass_helpers.get_colour",
-    "get-theme-setting": "aleksis.core.util.sass_helpers.get_theme_setting",
+    "get-setting": "aleksis.core.util.sass_helpers.get_setting",
 }
 SASS_PROCESSOR_INCLUDE_DIRS = [_settings.get("materialize.sass_path", JS_ROOT + "/materialize-css/sass/"), STATIC_ROOT]
 
@@ -270,6 +272,24 @@ if _settings.get("mail.server.host", None):
 
 TEMPLATE_VISIBLE_SETTINGS = ["ADMINS", "DEBUG"]
 
+CONSTANCE_BACKEND = 'constance.backends.database.DatabaseBackend'
+CONSTANCE_ADDITIONAL_FIELDS = {
+    "image_field": ["django.forms.ImageField", {}]
+}
+CONSTANCE_CONFIG = {
+    "COLOUR_PRIMARY": ("#007bff", _("Primary colour")),
+    "COLOUR_SECONDARY": ("#007bff", _("Secondary colour")),
+    "MAIL_OUT_NAME": ("AlekSIS", _("Mail out name")),
+    "MAIL_OUT": ("aleksis@example.com", _("Mail out address")),
+    "PRIVACY_URL": ("", _("Link to privacy policy")),
+    "IMPRINT_URL": ("", _("Link to imprint")),
+}
+CONSTANCE_CONFIG_FIELDSETS = {
+    "Theme settings": ("COLOUR_PRIMARY", "COLOUR_SECONDARY"),
+    "Mail settings": ("MAIL_OUT_NAME", "MAIL_OUT"),
+    "Footer settings": ("PRIVACY_URL", "IMPRINT_URL"),
+}
+
 MAINTENANCE_MODE = _settings.get("maintenance.enabled", None)
 MAINTENANCE_MODE_IGNORE_IP_ADDRESSES = _settings.get(
     "maintenance.ignore_ips", _settings.get("maintenance.internal_ips", [])
diff --git a/aleksis/core/static/theme.scss b/aleksis/core/static/theme.scss
index 6cb2c96081bad9721be4e4a6bee006c698cf4ea2..18b344169fe115d9175d8ac76df80d7dc9c178ae 100644
--- a/aleksis/core/static/theme.scss
+++ b/aleksis/core/static/theme.scss
@@ -34,11 +34,11 @@
 // 1. Colors
 // ==========================================================================
 
-$primary-color: adjust-color(get-colour(get-theme-setting(colour_primary)), $alpha: 1);
+$primary-color: adjust-color(get-colour(get-setting(COLOUR_PRIMARY)), $alpha: 1);
 $primary-color-light: lighten($primary-color, 15%) !default;
 $primary-color-dark: darken($primary-color, 15%) !default;
 
-$secondary-color: adjust-color(get-colour(get-theme-setting(colour_secondary)), $alpha: 1);
+$secondary-color: adjust-color(get-colour(get-setting(COLOUR_SECONDARY)), $alpha: 1);
 $success-color: color("green", "base") !default;
 $error-color: color("red", "base") !default;
 $link-color: color("light-blue", "darken-1") !default;
diff --git a/aleksis/core/templates/core/base.html b/aleksis/core/templates/core/base.html
index 854a16afb3c44f281c84bcd93b704b8c66faf3f4..e98f71587ed93f987ed710c0dd7721f86f21a407 100644
--- a/aleksis/core/templates/core/base.html
+++ b/aleksis/core/templates/core/base.html
@@ -124,28 +124,35 @@
   </div>
   <div class="footer-copyright">
     <div class="container">
-            <span class="left">
-              <a class="blue-text text-lighten-4" href="https://aleksis.edugit.org/">
-                AlekSIS — The Free School Information System
-            </a>
-              © The AlekSIS Team @
-              <a class="blue-text text-lighten-4" href="https://www.teckids.org">
-              Teckids e.V.
-            </a>
-              and
-              <a class="blue-text text-lighten-4" href="https://katharineum-zu-luebeck.de">
-                Katharineum zu Lübeck
-              </a>
-            </span>
-      <span class="right">
-                <span id="doit"></span>
-
-                <a class="blue-text text-lighten-4" href="https://katharineum-zu-luebeck.de/impressum/">Impressum</a>
-                ·
-                <a class="blue-text text-lighten-4" href="https://katharineum-zu-luebeck.de/datenschutzerklaerung/">
-                    Datenschutzerklärung
-                </a>
-            </span>
+      <div class="left">
+        <a class="blue-text text-lighten-4" href="https://aleksis.edugit.org/">
+          AlekSIS — The Free School Information System
+        </a>
+        © The AlekSIS Team @
+        <a class="blue-text text-lighten-4" href="https://www.teckids.org">
+          Teckids e.V.
+        </a>
+        and
+        <a class="blue-text text-lighten-4" href="https://katharineum-zu-luebeck.de">
+          Katharineum zu Lübeck
+        </a>
+      </div>
+      <div class="right">
+        <span id="doit"></span>
+        {% if DB_SETTINGS.footer.impress_url %}
+          <a class="blue-text text-lighten-4" href="{{ DB_SETTINGS.footer.impress_url }}">
+            {% trans "Impress" %}
+          </a>
+        {% endif %}
+        {% if DB_SETTINGS.footer.privacy_url and DB_SETTINGS.footer.impress_url %}
+          ·
+        {% endif %}
+        {% if DB_SETTINGS.footer.privacy_url %}
+          <a class="blue-text text-lighten-4" href="{{ DB_SETTINGS.footer.privacy_url }}">
+            {% trans "Privacy Policy" %}
+          </a>
+        {% endif %}
+      </div>
     </div>
   </div>
 </footer>
diff --git a/aleksis/core/urls.py b/aleksis/core/urls.py
index 2e3b0c98dbdd9831cc7d2e5a19d2511910c64e63..1368243ba3e4cc46daaadc50f2d2088afa06b55d 100644
--- a/aleksis/core/urls.py
+++ b/aleksis/core/urls.py
@@ -35,7 +35,6 @@ urlpatterns = [
     path("impersonate/", include("impersonate.urls")),
     path("__i18n__/", include("django.conf.urls.i18n")),
     path("select2/", include("django_select2.urls")),
-    path("settings/", include("dbsettings.urls")),
 ]
 
 # Serve static files from STATIC_ROOT to make it work with runserver
diff --git a/aleksis/core/util/sass_helpers.py b/aleksis/core/util/sass_helpers.py
index 2bb44b09c62a55219272d3021a78daf4aaa07b98..7c86f6337dc8d8dfaa89eb958737a3bf9a16c64f 100644
--- a/aleksis/core/util/sass_helpers.py
+++ b/aleksis/core/util/sass_helpers.py
@@ -1,8 +1,9 @@
+from django.conf import settings
+
 from colour import web2hex
+from constance import config
 from sass import SassColor
 
-from aleksis.core.models import theme_settings
-
 
 def get_colour(html_colour: str) -> SassColor:
     rgb = web2hex(html_colour, force_long=True)[1:]
@@ -11,5 +12,5 @@ def get_colour(html_colour: str) -> SassColor:
     return SassColor(r, g, b, 255)
 
 
-def get_theme_setting(setting: str) -> str:
-    return getattr(theme_settings, setting, "")
+def get_setting(setting: str) -> str:
+    return getattr(config, setting, "") or getattr(settings, setting, "")
diff --git a/poetry.lock b/poetry.lock
index cd62881947c361493e1275b5b46b8a8bec59cb7b..9d000b9d8897277815c951e71190cd424cd8328e 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -161,6 +161,9 @@ optional = false
 python-versions = "*"
 version = "5.0.6"
 
+[package.dependencies]
+six = "*"
+
 [[package]]
 category = "dev"
 description = "Code coverage measurement for Python"
@@ -256,11 +259,22 @@ Django = ">=1.8"
 
 [[package]]
 category = "main"
-description = "Application settings whose values can be updated while a project is up and running."
-name = "django-dbsettings"
+description = "Django live settings with pluggable backends, including Redis."
+name = "django-constance"
 optional = false
 python-versions = "*"
-version = "1.0.0"
+version = "2.5.0"
+
+[package.dependencies]
+six = "*"
+
+[package.dependencies.django-picklefield]
+optional = true
+version = "*"
+
+[package.extras]
+database = ["django-picklefield"]
+redis = ["redis"]
 
 [[package]]
 category = "main"
@@ -416,24 +430,23 @@ version = "3.0.1"
 Django = ">=1.11.3"
 babel = "*"
 
-[package.dependencies.phonenumbers]
-optional = true
-version = ">=7.0.2"
-
 [package.extras]
 phonenumbers = ["phonenumbers (>=7.0.2)"]
 phonenumberslite = ["phonenumberslite (>=7.0.2)"]
 
 [[package]]
 category = "main"
-description = "A Django app to include a manifest.json and Service Worker instance to enable progressive web app behavior"
-name = "django-pwa"
+description = "Pickled object field for Django"
+name = "django-picklefield"
 optional = false
 python-versions = "*"
-version = "1.0.6"
+version = "2.0"
 
 [package.dependencies]
-django = ">=1.8"
+Django = ">=1.11"
+
+[package.extras]
+tests = ["tox"]
 
 [[package]]
 category = "main"
@@ -1234,7 +1247,7 @@ category = "main"
 description = "YAML parser and emitter for Python"
 name = "pyyaml"
 optional = false
-python-versions = "*"
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
 version = "5.2"
 
 [[package]]
@@ -1658,7 +1671,7 @@ testing = ["pathlib2", "contextlib2", "unittest2"]
 ldap = ["django-auth-ldap"]
 
 [metadata]
-content-hash = "7c5cc3497e09ab1ef53c542aeba9787d5045524e6f1a9c299454f18aa4d592a6"
+content-hash = "bca26513f4520039661e719a675e767eef8a19273d1430cd0810ea8a10ea40da"
 python-versions = "^3.7"
 
 [metadata.files]
@@ -1782,8 +1795,9 @@ django-bulk-update = [
     {file = "django-bulk-update-2.2.0.tar.gz", hash = "sha256:5ab7ce8a65eac26d19143cc189c0f041d5c03b9d1b290ca240dc4f3d6aaeb337"},
     {file = "django_bulk_update-2.2.0-py2.py3-none-any.whl", hash = "sha256:49a403392ae05ea872494d74fb3dfa3515f8df5c07cc277c3dc94724c0ee6985"},
 ]
-django-dbsettings = [
-    {file = "django-dbsettings-1.0.0.tar.gz", hash = "sha256:42b04dffd3bc90d91718c822f1e0212d9368e8efe340f7ef09517b5fb1cf49f5"},
+django-constance = [
+    {file = "django-constance-2.5.0.tar.gz", hash = "sha256:c47db4abd5788584115db681c0e8fef8ff870d49af90aa359076f0833a537199"},
+    {file = "django_constance-2.5.0-py2.py3-none-any.whl", hash = "sha256:1b536d153c168ef548fea5bdcdea84afab83892e2163ec4e896557a3139effd7"},
 ]
 django-debug-toolbar = [
     {file = "django-debug-toolbar-2.1.tar.gz", hash = "sha256:24c157bc6c0e1648e0a6587511ecb1b007a00a354ce716950bff2de12693e7a8"},
@@ -1836,9 +1850,9 @@ django-phonenumber-field = [
     {file = "django-phonenumber-field-3.0.1.tar.gz", hash = "sha256:794ebbc3068a7af75aa72a80cb0cec67e714ff8409a965968040f1fd210b2d97"},
     {file = "django_phonenumber_field-3.0.1-py3-none-any.whl", hash = "sha256:1ab19f723928582fed412bd9844221fa4ff466276d8526b8b4a9913ee1487c5e"},
 ]
-django-pwa = [
-    {file = "django-pwa-1.0.6.tar.gz", hash = "sha256:b3f1ad0c5241fae4c7505423540de4db93077d7c88416ff6d2af545ffe209f34"},
-    {file = "django_pwa-1.0.6-py3-none-any.whl", hash = "sha256:9306105fcb637ae16fea6527be4b147d45fd53db85efb1d4f61dfea6bf793e56"},
+django-picklefield = [
+    {file = "django-picklefield-2.0.tar.gz", hash = "sha256:f1733a8db1b6046c0d7d738e785f9875aa3c198215de11993463a9339aa4ea24"},
+    {file = "django_picklefield-2.0-py2.py3-none-any.whl", hash = "sha256:9052f2dcf4882c683ce87b4356f29b4d014c0dad645b6906baf9f09571f52bc8"},
 ]
 django-sass-processor = [
     {file = "django-sass-processor-0.8.tar.gz", hash = "sha256:e039551994feaaba6fcf880412b25a772dd313162a34cbb4289814988cfae340"},
@@ -2414,6 +2428,7 @@ urllib3 = [
 ]
 wcwidth = [
     {file = "wcwidth-0.1.8-py2.py3-none-any.whl", hash = "sha256:8fd29383f539be45b20bd4df0dc29c20ba48654a41e661925e612311e9f3c603"},
+    {file = "wcwidth-0.1.8.tar.gz", hash = "sha256:f28b3e8a6483e5d49e7f8949ac1a78314e740333ae305b4ba5defd3e74fb37a8"},
 ]
 yubiotp = [
     {file = "YubiOTP-0.2.2.post1-py2.py3-none-any.whl", hash = "sha256:7e281801b24678f4bda855ce8ab975a7688a912f5a6cb22b6c2b16263a93cbd2"},
diff --git a/pyproject.toml b/pyproject.toml
index ea95aa00dd4b6873da4982ec10d5d8203693c190..03bf5cdc77f266f408b761cf8acba90e32d8cf99 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -48,9 +48,9 @@ django_select2 = "^7.1"
 requests = "^2.22"
 django-two-factor-auth = { version = "^1.10.0", extras = [ "YubiKey", "phonenumbers", "Call", "SMS" ] }
 django-yarnpkg = "^6.0"
-django-dbsettings = "^1.0.0"
 django-material = "^1.6.0"
 django-pwa = "^1.0.6"
+django-constance = {version = "^2.5.0", extras = ["database"]}
 
 [tool.poetry.extras]
 ldap = ["django-auth-ldap"]