diff --git a/Dockerfile b/Dockerfile
index 709062a25582343a3e49aad857d7b3a9f3427edd..65237693e2fdb9f3ec87020516de6d29ab633b2c 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -16,13 +16,18 @@ COPY . .
 RUN bash -c 'adduser --disabled-login --quiet --gecos app app &&  \
              chmod -R o+r /app/ && \
              mkdir /app/media_files && \
+             mkdir /app/static_files && \
              chown -R app:app /app/media_files && \
+             chown -R app:app /app/static_files && \
              chmod o+x /app/run.sh'
 USER app
 
-# TODO HACK!
-# ENV DJANGO_SETTINGS_MODULE "majak.settings.production"
-ENV DJANGO_SETTINGS_MODULE "majak.settings.dev"
+ENV DJANGO_SETTINGS_MODULE "majak.settings.production"
+
+# fake values for required env variables used to run collectstatic during build
+RUN DJANGO_SECRET_KEY=x DATABASE_URL=postgres://x/x DJANGO_ALLOWED_HOSTS=x \
+    OIDC_RP_CLIENT_ID=x OIDC_RP_CLIENT_SECRET=x OIDC_RP_REALM_URL=x \
+    python manage.py collectstatic
 
 EXPOSE 8000
 
diff --git a/README.md b/README.md
index 1b8b37b47711f3e9a6f11ce5ff89dd8d2c5ef729..549f58ddb4dbcadc4dd17c16a2196cfb83be5f0e 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,24 @@ Maják je CMS pro Pirátské weby. Postavený je na [Wagtail](https://wagtail.io
 [![powered by: Wagtail](https://img.shields.io/badge/powered%20by-Wagtail-43b1b0)](https://wagtail.io)
 [![powered by: Django](https://img.shields.io/badge/powered%20by-Django-0C4B33)](https://www.djangoproject.com)
 
-## Konfigurace
+## Pod pokliÄŤkou
+
+[Wagtail](https://wagtail.io) a [Django](https://www.djangoproject.com) jsou poměrně
+vyspělé frameworky. Vždy mysli na to, že problém co řešíš, už pravděpodobně řešil
+někdo před tebou. A obvykle existuje elegantní řešení.
+
+Pár užitečných odkazů:
+
+* [docs Wagtail](https://docs.wagtail.io/)
+* [docs Django](https://docs.djangoproject.com/)
+* [docs Wagtailmenus](https://wagtailmenus.readthedocs.io/)
+
+A za zmĂ­nku stojĂ­ [Awesome Wagtail](https://github.com/springload/awesome-wagtail)
+jako přehled pluginů a rozšíření pro Wagtail.
+
+## Deployment
+
+### Konfigurace
 
 Je třeba nastavit environment proměnné:
 
@@ -14,29 +31,24 @@ Je třeba nastavit environment proměnné:
 | --- | --- | --- |
 | `DATABASE_URL` | | DSN k databázi (např. `postgres://user:pass@localhost:5342/majak`) |
 | `OIDC_RP_REALM_URL` | | OpenID server realm URL (napĹ™. `http://localhost:8080/auth/realms/master/`) |
-| `OIDC_RP_CLIENT_ID`  | | OpenID Client ID |
-| `OIDC_RP_CLIENT_SECRET`  | | OpenID Client Secret |
+| `OIDC_RP_CLIENT_ID` | | OpenID Client ID |
+| `OIDC_RP_CLIENT_SECRET` | | OpenID Client Secret |
+| `BASE_URL` | https://majak.pirati.cz | základní URL pro notifikační emaily apod. |
 
 V produkci musí být navíc nastaveno:
 
 | proměnná | default | popis |
 | --- | --- | --- |
 | `DJANGO_SECRET_KEY` | | tajný šifrovací klíč |
+| `DJANGO_ALLOWED_HOSTS` | | allowed hosts (více hodnot odděleno čárkami) |
 
-## Pod pokliÄŤkou
-
-[Wagtail](https://wagtail.io) a [Django](https://www.djangoproject.com) jsou poměrně
-vyspělé frameworky. Vždy mysli na to, že problém co řešíš, už pravděpodobně řešil
-někdo před tebou. A obvykle existuje elegantní řešení.
-
-Pár užitečných odkazů:
+### Přidání nového webu
 
-* [docs Wagtail](https://docs.wagtail.io/)
-* [docs Django](https://docs.djangoproject.com/)
-* [docs Wagtailmenus](https://wagtailmenus.readthedocs.io/)
+Doména či subdoména se musí nakonfigurovat v:
 
-A za zmĂ­nku stojĂ­ [Awesome Wagtail](https://github.com/springload/awesome-wagtail)
-jako přehled pluginů a rozšíření pro Wagtail.
+* environment proměnné `DJANGO_ALLOWED_HOSTS`
+* proxy před Majákem
+* SSO Client redirect URIs
 
 ## Vývoj
 
diff --git a/majak/settings/base.py b/majak/settings/base.py
index cc6c4ccbccd5649d2fb1c2f1b40108a25b31f39a..3f546ac79ee3038af780223b8e305062a1f0dc2d 100644
--- a/majak/settings/base.py
+++ b/majak/settings/base.py
@@ -9,8 +9,27 @@ PROJECT_DIR = ROOT_DIR / "majak"
 env = environ.Env()
 environ.Env.read_env(str(ROOT_DIR / ".env"))
 
-# Application definition
+# GENERAL
+# ------------------------------------------------------------------------------
+DEBUG = env.bool("DJANGO_DEBUG", False)
+ROOT_URLCONF = "majak.urls"
+WSGI_APPLICATION = "majak.wsgi.application"
 
+# I18N and L10N
+# ------------------------------------------------------------------------------
+TIME_ZONE = "Europe/Prague"
+LANGUAGE_CODE = "cs"
+USE_I18N = True
+USE_L10N = True
+USE_TZ = True
+
+# DATABASES
+# ------------------------------------------------------------------------------
+DATABASES = {"default": env.db("DATABASE_URL")}
+DATABASES["default"]["ATOMIC_REQUESTS"] = True
+
+# APPS
+# ------------------------------------------------------------------------------
 INSTALLED_APPS = [
     "search",
     "senator",
@@ -41,6 +60,25 @@ INSTALLED_APPS = [
     "django.contrib.staticfiles",
 ]
 
+# AUTHENTICATION
+# ------------------------------------------------------------------------------
+AUTHENTICATION_BACKENDS = ["pirates.auth.PiratesOIDCAuthenticationBackend"]
+AUTH_USER_MODEL = "users.User"
+LOGIN_REDIRECT_URL = "/admin"
+LOGOUT_REDIRECT_URL = "/admin"
+LOGIN_URL = "/admin"
+
+OIDC_RP_CLIENT_ID = env.str("OIDC_RP_CLIENT_ID")
+OIDC_RP_CLIENT_SECRET = env.str("OIDC_RP_CLIENT_SECRET")
+OIDC_RP_REALM_URL = env.str("OIDC_RP_REALM_URL")
+OIDC_RP_SIGN_ALGO = "RS256"
+OIDC_OP_JWKS_ENDPOINT = join(OIDC_RP_REALM_URL, "protocol/openid-connect/certs")
+OIDC_OP_AUTHORIZATION_ENDPOINT = join(OIDC_RP_REALM_URL, "protocol/openid-connect/auth")
+OIDC_OP_TOKEN_ENDPOINT = join(OIDC_RP_REALM_URL, "protocol/openid-connect/token")
+OIDC_OP_USER_ENDPOINT = join(OIDC_RP_REALM_URL, "protocol/openid-connect/userinfo")
+
+# MIDDLEWARE
+# ------------------------------------------------------------------------------
 MIDDLEWARE = [
     "django.contrib.sessions.middleware.SessionMiddleware",
     "django.middleware.common.CommonMiddleware",
@@ -52,14 +90,33 @@ MIDDLEWARE = [
     "wagtail.contrib.redirects.middleware.RedirectMiddleware",
 ]
 
-ROOT_URLCONF = "majak.urls"
+# STATIC
+# ------------------------------------------------------------------------------
+STATIC_ROOT = str(ROOT_DIR / "static_files")
+STATIC_URL = "/static/"
+STATICFILES_DIRS = [str(PROJECT_DIR / "static")]
+STATICFILES_FINDERS = [
+    "django.contrib.staticfiles.finders.FileSystemFinder",
+    "django.contrib.staticfiles.finders.AppDirectoriesFinder",
+]
+STATICFILES_STORAGE = "django.contrib.staticfiles.storage.ManifestStaticFilesStorage"
+
+# MEDIA
+# ------------------------------------------------------------------------------
+MEDIA_URL = "/media/"
+MEDIA_ROOT = str(ROOT_DIR / "media_files")
 
+# TEMPLATES
+# ------------------------------------------------------------------------------
 TEMPLATES = [
     {
         "BACKEND": "django.template.backends.django.DjangoTemplates",
         "DIRS": [str(PROJECT_DIR / "templates")],
-        "APP_DIRS": True,
         "OPTIONS": {
+            "loaders": [
+                "django.template.loaders.filesystem.Loader",
+                "django.template.loaders.app_directories.Loader",
+            ],
             "context_processors": [
                 "django.template.context_processors.debug",
                 "django.template.context_processors.request",
@@ -72,75 +129,52 @@ TEMPLATES = [
     },
 ]
 
-WSGI_APPLICATION = "majak.wsgi.application"
-
-
-# Database
-# https://docs.djangoproject.com/en/3.0/ref/settings/#databases
-
-DATABASES = {"default": env.db("DATABASE_URL")}
-DATABASES["default"]["ATOMIC_REQUESTS"] = True
-
-
-# Password validation
-# https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators
-
-AUTH_PASSWORD_VALIDATORS = [
-    {
-        "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
+# SECURITY
+# ------------------------------------------------------------------------------
+SESSION_COOKIE_HTTPONLY = True
+CSRF_COOKIE_HTTPONLY = True
+SECURE_BROWSER_XSS_FILTER = True
+X_FRAME_OPTIONS = "DENY"
+
+# EMAIL
+# ------------------------------------------------------------------------------
+EMAIL_BACKEND = env(
+    "DJANGO_EMAIL_BACKEND", default="django.core.mail.backends.dummy.EmailBackend"
+)
+
+# LOGGING
+# ------------------------------------------------------------------------------
+LOGGING = {
+    "version": 1,
+    "disable_existing_loggers": False,
+    "formatters": {
+        "verbose": {
+            "format": "%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s"
+        }
     },
-    {"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",},
-    {"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",},
-    {"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",},
-]
-
-
-# Internationalization
-# https://docs.djangoproject.com/en/3.0/topics/i18n/
-
-LANGUAGE_CODE = "cs"
-TIME_ZONE = "Europe/Prague"
-USE_I18N = True
-USE_L10N = True
-USE_TZ = True
-
-
-# Static files (CSS, JavaScript, Images)
-# https://docs.djangoproject.com/en/3.0/howto/static-files/
-
-STATICFILES_FINDERS = [
-    "django.contrib.staticfiles.finders.FileSystemFinder",
-    "django.contrib.staticfiles.finders.AppDirectoriesFinder",
-]
-
-STATICFILES_DIRS = [str(PROJECT_DIR / "static")]
-
-# ManifestStaticFilesStorage is recommended in production, to prevent outdated
-# Javascript / CSS assets being served from cache (e.g. after a Wagtail upgrade).
-# See https://docs.djangoproject.com/en/3.0/ref/contrib/staticfiles/#manifeststaticfilesstorage
-STATICFILES_STORAGE = "django.contrib.staticfiles.storage.ManifestStaticFilesStorage"
-
-STATIC_ROOT = str(ROOT_DIR / "static_files")
-STATIC_URL = "/static/"
-
-MEDIA_ROOT = str(ROOT_DIR / "media_files")
-MEDIA_URL = "/media/"
-
-
-# Wagtail settings
+    "handlers": {
+        "console": {
+            "level": "DEBUG",
+            "class": "logging.StreamHandler",
+            "formatter": "verbose",
+        }
+    },
+    "root": {"level": "INFO", "handlers": ["console"]},
+}
 
+# WAGTAIL SETTINGS
+# ------------------------------------------------------------------------------
 WAGTAIL_SITE_NAME = "Maják"
 
-# Base URL to use when referring to full URLs within the Wagtail admin backend -
-# e.g. in notification emails. Don't include '/admin' or a trailing slash
-BASE_URL = "http://example.com"
-
 WAGTAIL_ALLOW_UNICODE_SLUGS = False
 
 TAGGIT_CASE_INSENSITIVE = True
 
-AUTH_USER_MODEL = "users.User"
+WAGTAIL_USER_TIME_ZONES = ["Europe/Prague"]
+
+WAGTAILADMIN_NOTIFICATION_INCLUDE_SUPERUSERS = False
 
+# disable editing of user details synced from SSO
 WAGTAIL_USER_EDIT_FORM = "users.forms.CustomUserEditForm"
 WAGTAIL_USER_CREATION_FORM = "users.forms.CustomUserCreationForm"
 WAGTAIL_PASSWORD_MANAGEMENT_ENABLED = False
@@ -149,17 +183,6 @@ WAGTAILUSERS_PASSWORD_ENABLED = False
 WAGTAILUSERS_PASSWORD_REQUIRED = False
 WAGTAIL_EMAIL_MANAGEMENT_ENABLED = False
 
-AUTHENTICATION_BACKENDS = ["pirates.auth.PiratesOIDCAuthenticationBackend"]
-
-OIDC_RP_CLIENT_ID = env.str("OIDC_RP_CLIENT_ID")
-OIDC_RP_CLIENT_SECRET = env.str("OIDC_RP_CLIENT_SECRET")
-OIDC_RP_REALM_URL = env.str("OIDC_RP_REALM_URL")
-OIDC_RP_SIGN_ALGO = "RS256"
-OIDC_OP_JWKS_ENDPOINT = join(OIDC_RP_REALM_URL, "protocol/openid-connect/certs")
-OIDC_OP_AUTHORIZATION_ENDPOINT = join(OIDC_RP_REALM_URL, "protocol/openid-connect/auth")
-OIDC_OP_TOKEN_ENDPOINT = join(OIDC_RP_REALM_URL, "protocol/openid-connect/token")
-OIDC_OP_USER_ENDPOINT = join(OIDC_RP_REALM_URL, "protocol/openid-connect/userinfo")
-
-LOGIN_REDIRECT_URL = "/admin"
-LOGOUT_REDIRECT_URL = "/admin"
-LOGIN_URL = "/admin"
+# Base URL to use when referring to full URLs within the Wagtail admin backend -
+# e.g. in notification emails. Don't include '/admin' or a trailing slash
+BASE_URL = env.str("BASE_URL", default="https://majak.pirati.cz")
diff --git a/majak/settings/dev.py b/majak/settings/dev.py
index 3ae9e0c6ff57fae8b2ba31d32fcba9f2bae2dd90..14ef7e2d42b5e9a8a17a4799affb3f096f55b258 100644
--- a/majak/settings/dev.py
+++ b/majak/settings/dev.py
@@ -1,18 +1,8 @@
 from .base import *
+from .base import env
 
-# SECURITY WARNING: don't run with debug turned on in production!
-DEBUG = True
-
-# SECURITY WARNING: keep the secret key used in production secret!
-SECRET_KEY = "1vu8ve^2vdu%k00s7&)l+^a@b5aht53el96evte(7d)0@!dyk1"
-
-# SECURITY WARNING: define the correct hosts in production!
-ALLOWED_HOSTS = ["*"]
-
-EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
-
-
-try:
-    from .local import *
-except ImportError:
-    pass
+# GENERAL
+# ------------------------------------------------------------------------------
+DEBUG = env.bool("DJANGO_DEBUG", default=True)
+SECRET_KEY = env("DJANGO_SECRET_KEY", default="58asda4d6nasd*jkj!dbska83asd54")
+ALLOWED_HOSTS = env.list("DJANGO_ALLOWED_HOSTS", default=["*"])
diff --git a/majak/settings/production.py b/majak/settings/production.py
index 9ca4ed75279d4b38ece0feb0254929ed934033e4..2d7e44b39c35ff7e47c79cb95fae9a992ac31650 100644
--- a/majak/settings/production.py
+++ b/majak/settings/production.py
@@ -1,8 +1,43 @@
 from .base import *
+from .base import env
 
-DEBUG = False
+# DATABASES
+# ------------------------------------------------------------------------------
+DATABASES["default"]["CONN_MAX_AGE"] = env.int("CONN_MAX_AGE", default=60)
 
-try:
-    from .local import *
-except ImportError:
-    pass
+# SECURITY
+# ------------------------------------------------------------------------------
+ALLOWED_HOSTS = env.list("DJANGO_ALLOWED_HOSTS")
+SECRET_KEY = env("DJANGO_SECRET_KEY")
+SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
+SECURE_SSL_REDIRECT = True
+SESSION_COOKIE_SECURE = True
+CSRF_COOKIE_SECURE = True
+# set this to 60 seconds first and then to 518400 once you prove the former works
+SECURE_HSTS_SECONDS = 518400
+SECURE_HSTS_INCLUDE_SUBDOMAINS = True
+SECURE_HSTS_PRELOAD = True
+SECURE_CONTENT_TYPE_NOSNIFF = True
+
+# TEMPLATES
+# ------------------------------------------------------------------------------
+TEMPLATES[0]["OPTIONS"]["loaders"] = [
+    (
+        "django.template.loaders.cached.Loader",
+        [
+            "django.template.loaders.filesystem.Loader",
+            "django.template.loaders.app_directories.Loader",
+        ],
+    )
+]
+
+# STATIC
+# ------------------------------------------------------------------------------
+MIDDLEWARE.insert(1, "whitenoise.middleware.WhiteNoiseMiddleware")
+STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage"
+
+# LOGGING
+# ------------------------------------------------------------------------------
+LOGGING["filters"] = {
+    "require_debug_false": {"()": "django.utils.log.RequireDebugFalse"}
+}
diff --git a/requirements/base.in b/requirements/base.in
index 4b01ce6933ad6a1a9d1614e90d6bdbb9e717d9f2..29e83430e56bb22ae22bb4aeacb084104d087596 100644
--- a/requirements/base.in
+++ b/requirements/base.in
@@ -4,3 +4,4 @@ django-environ
 django-extensions
 psycopg2-binary
 pirates<=0.4
+whitenoise
diff --git a/requirements/base.txt b/requirements/base.txt
index 8f2ba5608af2333b522a00815550b223427c8a77..80fdc30acb14801820c46925a717cdc10756188e 100644
--- a/requirements/base.txt
+++ b/requirements/base.txt
@@ -42,6 +42,7 @@ urllib3==1.25.9           # via requests
 wagtail==2.9              # via -r base.in
 wagtailmenus==3.0.1       # via -r base.in
 webencodings==0.5.1       # via html5lib
+whitenoise==5.0.1         # via -r base.in
 willow==1.3               # via wagtail
 xlsxwriter==1.2.8         # via wagtail