From 9a04c0977be01944c920c3c12510f4dcb1552bba Mon Sep 17 00:00:00 2001 From: Kesara Rathnayake Date: Wed, 22 May 2024 23:41:35 +1200 Subject: [PATCH 01/22] feat: Add www.ietf.org k8s configuration --- k8s/ietfweb/django-config.yaml | 21 ++++++ k8s/ietfweb/ietfweb.yaml | 84 ++++++++++++++++++++++++ k8s/ietfweb/kustomization.yaml | 13 ++++ k8s/ietfweb/local.py | 114 +++++++++++++++++++++++++++++++++ k8s/ietfweb/memcached.yaml | 74 +++++++++++++++++++++ k8s/ietfweb/supervisord.conf | 17 +++++ 6 files changed, 323 insertions(+) create mode 100644 k8s/ietfweb/django-config.yaml create mode 100644 k8s/ietfweb/ietfweb.yaml create mode 100644 k8s/ietfweb/kustomization.yaml create mode 100644 k8s/ietfweb/local.py create mode 100644 k8s/ietfweb/memcached.yaml create mode 100644 k8s/ietfweb/supervisord.conf diff --git a/k8s/ietfweb/django-config.yaml b/k8s/ietfweb/django-config.yaml new file mode 100644 index 00000000..c501ff41 --- /dev/null +++ b/k8s/ietfweb/django-config.yaml @@ -0,0 +1,21 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: django-config +data: + # n.b., these are debug values / non-secret secrets + IETFWEB_SERVER_MODE: "development" # development for staging, production for production + IETFWEB_ADMINS: |- + Robert Sparks + Kesara Rathnayake + IETFWEB_ALLOWED_HOSTS: ".ietf.org" # newline-separated list also allowed + + IETFWEB_DJANGO_SECRET_KEY: "PDwXboUq!=hPjnrtG2=ge#N$Dwy+wn@uivrugwpic8mxyPfHk" # secret + + + # IETFWEB_MATOMO_SITE_ID: "1" # must be present to enable Matomo + # IETFWEB_MATOMO_DOMAIN_PATH: "analytics.ietf.org" + + # use this to override default - one entry per line + # IETFWEB_CSRF_TRUSTED_ORIGINS: |- + # https://www.staging.ietf.org diff --git a/k8s/ietfweb/ietfweb.yaml b/k8s/ietfweb/ietfweb.yaml new file mode 100644 index 00000000..89a2245f --- /dev/null +++ b/k8s/ietfweb/ietfweb.yaml @@ -0,0 +1,84 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ietfweb +spec: + replicas: 1 + revisionHistoryLimit: 2 + selector: + matchLabels: + app: ietfweb + strategy: + type: Recreate + template: + metadata: + labels: + app: ietfweb + spec: + securityContext: + runAsNonRoot: true + containers: + # ----------------------------------------------------- + # ietfweb Container + # ----------------------------------------------------- + - name: ietfweb + image: "ghcr.io/ietf-tools/www:$APP_IMAGE_TAG" + imagePullPolicy: Always + ports: + - containerPort: 8000 + name: http + protocol: TCP + volumeMounts: + - name: dt-vol + mountPath: /a + - name: www-tmp + mountPath: /tmp + - name: www-supervisor-cfg + mountPath: /app/supervisord.conf + subPath: supervisord.conf + - name: www-cfg + mountPath: /app/ietf/settings/local.py + subPath: local.py + env: + - name: "CONTAINER_ROLE" + value: "ietfweb" + envFrom: + - configMapRef: + name: django-config + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsUser: 1000 + runAsGroup: 1000 + volumes: + # To be overriden with the actual shared volume + - name: dt-vol + - name: www-supervisor-cfg + configMap: + name: files-supervisor-cfg + - name: www-tmp + emptyDir: + sizeLimit: "2Gi" + - name: www-cfg + configMap: + name: files-cfgmap + dnsPolicy: ClusterFirst + restartPolicy: Always + terminationGracePeriodSeconds: 30 +--- +apiVersion: v1 +kind: Service +metadata: + name: ietfweb +spec: + type: ClusterIP + ports: + - port: 80 + targetPort: http + protocol: TCP + name: http + selector: + app: ietfweb diff --git a/k8s/ietfweb/kustomization.yaml b/k8s/ietfweb/kustomization.yaml new file mode 100644 index 00000000..1f73d660 --- /dev/null +++ b/k8s/ietfweb/kustomization.yaml @@ -0,0 +1,13 @@ +namespace: ietfweb +namePrefix: ietfweb- +configMapGenerator: + - name: files-cfgmap + files: + - local.py + - name: files-supervisor-cfg + files: + - supervisord.conf +resources: + - ietfweb.yaml + - django-config.yaml + - memcached.yaml diff --git a/k8s/ietfweb/local.py b/k8s/ietfweb/local.py new file mode 100644 index 00000000..7fb287df --- /dev/null +++ b/k8s/ietfweb/local.py @@ -0,0 +1,114 @@ +# Copyright The IETF Trust 2007-2024, All Rights Reserved +# -*- coding: utf-8 -*- + +from email.utils import parseaddr +import os + +def _multiline_to_list(s): + """Helper to split at newlines and conver to list""" + return [item.strip() for item in s.split("\n")] + + +DEFAULT_FROM_EMAIL = "donotreply@ietf.org" +SERVER_EMAIL = "donotreply@ietf.org" +EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend" +EMAIL_HOST = os.environ.get("IETFWEB_EMAIL_HOST", "localhost") +EMAIL_PORT = int(os.environ.get("IETFWEB_EMAIL_PORT", "2025")) + +# Default to "development". Production _must_ set IETFWEB_SERVER_MODE="production" in the env! +SERVER_MODE = os.environ.get("IETFWEB_SERVER_MODE", "development") + +# Secrets +_SECRET_KEY = os.environ.get("IETFWEB_DJANGO_SECRET_KEY", None) +if _SECRET_KEY is not None: + SECRET_KEY = _SECRET_KEY +else: + raise RuntimeError("IETFWEB_DJANGO_SECRET_KEY must be set") + + +_csrf_trusted_origins_str = os.environ.get("IETFWEB_CSRF_TRUSTED_ORIGINS") +if _csrf_trusted_origins_str is not None: + CSRF_TRUSTED_ORIGINS = _multiline_to_list(_csrf_trusted_origins_str) + +FILE_UPLOAD_PERMISSIONS = 0o664 +_WAGTAILADMIN_BASE_URL = os.environ.get("WAGTAILADMIN_BASE_URL", None) +if _WAGTAILADMIN_BASE_URL is not None: + WAGTAILADMIN_BASE_URL = _WAGTAILADMIN_BASE_URL +else: + raise RuntimeError("WAGTAILADMIN_BASE_URL must be present") + +# Set DEBUG if IETFWEB_DEBUG env var is the word "true" +DEBUG = os.environ.get("IETFWEB_DEBUG", "false").lower() == "true" + +# IETFWEB_ALLOWED_HOSTS env var is a comma-separated list of allowed hosts +_allowed_hosts_str = os.environ.get("IETFWEB_ALLOWED_HOSTS", None) +if _allowed_hosts_str is not None: + ALLOWED_HOSTS = _multiline_to_list(_allowed_hosts_str) + +DATABASES = { + "default": { + "ENGINE": "django.db.backends.postgresql_psycopg2", + "HOST": os.environ.get("IETFWEB_DB_HOST", "db"), + "PORT": os.environ.get("IETFWEB_DB_PORT", "5432"), + "NAME": os.environ.get("IETFWEB_DB_NAME", "ietfweb"), + "USER": os.environ.get("IETFWEB_DB_USER", "django"), + "PASSWORD": os.environ.get("IETFWEB_DB_PASS", ""), + "CONN_MAX_AGE": 600, # number of seconds database connections should persist for + }, +} + +# IETFWEB_ADMINS is a newline-delimited list of addresses parseable by email.utils.parseaddr +_admins_str = os.environ.get("IETFWEB_ADMINS", None) +if _admins_str is not None: + ADMINS = [parseaddr(admin) for admin in _multiline_to_list(_admins_str)] +else: + raise RuntimeError("IETFWEB_ADMINS must be set") + +# Leave IETFWEB_MATOMO_SITE_ID unset to disable Matomo reporting +if "IETFWEB_MATOMO_SITE_ID" in os.environ: + MATOMO_DOMAIN_PATH = os.environ.get("IETFWEB_MATOMO_DOMAIN_PATH", "analytics.ietf.org") + MATOMO_SITE_ID = os.environ.get("IETFWEB_MATOMO_SITE_ID") + MATOMO_DISABLE_COOKIES = True + +# Duplicating production cache from settings.py and using it whether we're in production mode or not +MEMCACHED_HOST = os.environ.get("IETFWEB_MEMCACHED_SERVICE_HOST", "127.0.0.1") +MEMCACHED_PORT = os.environ.get("IETFWEB_MEMCACHED_SERVICE_PORT", "11211") +MEMCACHED_KEY_PREFIX = "ietf" +CACHES = { + "default": { + "BACKEND": "django.core.cache.backends.memcached.PyMemcacheCache", + "LOCATION": f"{MEMCACHED_HOST}:{MEMCACHED_PORT}", + "KEY_PREFIX": MEMCACHED_KEY_PREFIX, + }, + "sessions": { + "BACKEND": "django.core.cache.backends.memcached.PyMemcacheCache", + "LOCATION": f"{MEMCACHED_HOST}:{MEMCACHED_PORT}", + "KEY_PREFIX": MEMCACHED_KEY_PREFIX, + }, + "dummy": {"BACKEND": "django.core.cache.backends.dummy.DummyCache"}, +} + +# Logging + +LOGGING = { + "version": 1, + "disable_existing_loggers": False, + "handlers": { + "mail_admins": { + "level": "ERROR", + "class": "django.utils.log.AdminEmailHandler", + }, + }, + "loggers": { + "django.request": { + "handlers": ["mail_admins"], + "level": "ERROR", + "propagate": False, + }, + "django.security": { + "handlers": ["mail_admins"], + "level": "ERROR", + "propagate": False, + }, + }, +} diff --git a/k8s/ietfweb/memcached.yaml b/k8s/ietfweb/memcached.yaml new file mode 100644 index 00000000..bfd1093b --- /dev/null +++ b/k8s/ietfweb/memcached.yaml @@ -0,0 +1,74 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: memcached +spec: + replicas: 1 + revisionHistoryLimit: 2 + selector: + matchLabels: + app: memcached + template: + metadata: + labels: + app: memcached + spec: + securityContext: + runAsNonRoot: true + containers: + - image: "quay.io/prometheus/memcached-exporter:v0.14.3" + imagePullPolicy: IfNotPresent + name: memcached-exporter + ports: + - name: metrics + containerPort: 9150 + protocol: TCP + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsUser: 65534 # nobody + runAsGroup: 65534 # nobody + - image: "memcached:1.6-alpine" + imagePullPolicy: IfNotPresent + args: ["-m", "1024"] + name: memcached + ports: + - name: memcached + containerPort: 11211 + protocol: TCP + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + # memcached image sets up uid/gid 11211 + runAsUser: 11211 + runAsGroup: 11211 + dnsPolicy: ClusterFirst + restartPolicy: Always + terminationGracePeriodSeconds: 30 +--- +apiVersion: v1 +kind: Service +metadata: + name: memcached + annotations: + k8s.grafana.com/scrape: "true" # this is not a bool + k8s.grafana.com/metrics.portName: "metrics" +spec: + type: ClusterIP + ports: + - port: 11211 + targetPort: memcached + protocol: TCP + name: memcached + - port: 9150 + targetPort: metrics + protocol: TCP + name: metrics + selector: + app: memcached diff --git a/k8s/ietfweb/supervisord.conf b/k8s/ietfweb/supervisord.conf new file mode 100644 index 00000000..afbbfb5c --- /dev/null +++ b/k8s/ietfweb/supervisord.conf @@ -0,0 +1,17 @@ +[supervisord] +nodaemon=true +logfile=/dev/stdout +logfile_maxbytes=0 + +[program:nginx] +command=nginx -g "daemon off;" +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +redirect_stderr=true + +[program:gunicorn] +command=/usr/local/bin/gunicorn --config /app/docker/gunicorn.py ietf.wsgi +directory=/app +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +redirect_stderr=true From 32925bc80715596931a901e72ace49d675c1c03f Mon Sep 17 00:00:00 2001 From: Kesara Rathnayake Date: Tue, 4 Jun 2024 23:33:52 +1200 Subject: [PATCH 02/22] fix: Add volume mounts for static and media --- k8s/ietfweb/ietfweb.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/k8s/ietfweb/ietfweb.yaml b/k8s/ietfweb/ietfweb.yaml index 89a2245f..0dc129cd 100644 --- a/k8s/ietfweb/ietfweb.yaml +++ b/k8s/ietfweb/ietfweb.yaml @@ -33,6 +33,10 @@ spec: mountPath: /a - name: www-tmp mountPath: /tmp + - name: www-static + mountPath: /app/static + - name: www-media + mountPath: /app/media - name: www-supervisor-cfg mountPath: /app/supervisord.conf subPath: supervisord.conf @@ -62,6 +66,10 @@ spec: - name: www-tmp emptyDir: sizeLimit: "2Gi" + - name: www-static + emptyDir: + sizeLimit: "2Gi" + - name: www-media - name: www-cfg configMap: name: files-cfgmap From eb40f820a91e7feb6046e3af1838174323495da0 Mon Sep 17 00:00:00 2001 From: Kesara Rathnayake Date: Wed, 5 Jun 2024 07:44:31 +1200 Subject: [PATCH 03/22] feat: Add persistent volume for the media directory --- k8s/ietfweb/deployment.yaml | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 k8s/ietfweb/deployment.yaml diff --git a/k8s/ietfweb/deployment.yaml b/k8s/ietfweb/deployment.yaml new file mode 100644 index 00000000..885e3d93 --- /dev/null +++ b/k8s/ietfweb/deployment.yaml @@ -0,0 +1,34 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: deployment +spec: + template: + spec: + containers: + - image: "ghcr.io/ietf-tools/www:$APP_IMAGE_TAG" + name: ietfwww + volumeMounts: + - name: dt-vol + mountPath: /a + - name: www-media + mountPath: /app/media + dnsPolicy: ClusterFirst + restartPolicy: Always + terminationGracePeriodSeconds: 30 +volumeClaimTemplates: + - metadata: + name: dt-vol + spec: + accessModes: + - ReadOnlyMany + - metadata: + name: www-media + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 5Gi + storageClassName: "generic" + From 22d3c658338f8cd97fb3bdb8fe9a84143abf4643 Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Tue, 4 Jun 2024 20:40:09 -0400 Subject: [PATCH 04/22] fix: k8s deployment files --- k8s/ietfweb/deployment.yaml | 34 ---------------------- k8s/ietfweb/kustomization.yaml | 8 ++--- k8s/ietfweb/{ietfweb.yaml => wagtail.yaml} | 33 ++++++++++++--------- 3 files changed, 23 insertions(+), 52 deletions(-) delete mode 100644 k8s/ietfweb/deployment.yaml rename k8s/ietfweb/{ietfweb.yaml => wagtail.yaml} (83%) diff --git a/k8s/ietfweb/deployment.yaml b/k8s/ietfweb/deployment.yaml deleted file mode 100644 index 885e3d93..00000000 --- a/k8s/ietfweb/deployment.yaml +++ /dev/null @@ -1,34 +0,0 @@ -apiVersion: apps/v1 -kind: StatefulSet -metadata: - name: deployment -spec: - template: - spec: - containers: - - image: "ghcr.io/ietf-tools/www:$APP_IMAGE_TAG" - name: ietfwww - volumeMounts: - - name: dt-vol - mountPath: /a - - name: www-media - mountPath: /app/media - dnsPolicy: ClusterFirst - restartPolicy: Always - terminationGracePeriodSeconds: 30 -volumeClaimTemplates: - - metadata: - name: dt-vol - spec: - accessModes: - - ReadOnlyMany - - metadata: - name: www-media - spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 5Gi - storageClassName: "generic" - diff --git a/k8s/ietfweb/kustomization.yaml b/k8s/ietfweb/kustomization.yaml index 1f73d660..6c3074fb 100644 --- a/k8s/ietfweb/kustomization.yaml +++ b/k8s/ietfweb/kustomization.yaml @@ -1,13 +1,11 @@ -namespace: ietfweb -namePrefix: ietfweb- +namespace: ietfwww +namePrefix: ietfwww- configMapGenerator: - name: files-cfgmap files: - local.py - - name: files-supervisor-cfg - files: - supervisord.conf resources: - - ietfweb.yaml - django-config.yaml - memcached.yaml + - wagtail.yaml diff --git a/k8s/ietfweb/ietfweb.yaml b/k8s/ietfweb/wagtail.yaml similarity index 83% rename from k8s/ietfweb/ietfweb.yaml rename to k8s/ietfweb/wagtail.yaml index 0dc129cd..bf091864 100644 --- a/k8s/ietfweb/ietfweb.yaml +++ b/k8s/ietfweb/wagtail.yaml @@ -1,27 +1,27 @@ apiVersion: apps/v1 -kind: Deployment +kind: StatefulSet metadata: - name: ietfweb + name: wagtail spec: replicas: 1 revisionHistoryLimit: 2 selector: matchLabels: - app: ietfweb + app: wagtail strategy: type: Recreate template: metadata: labels: - app: ietfweb + app: wagtail spec: securityContext: runAsNonRoot: true containers: # ----------------------------------------------------- - # ietfweb Container + # wagtail Container # ----------------------------------------------------- - - name: ietfweb + - name: wagtail image: "ghcr.io/ietf-tools/www:$APP_IMAGE_TAG" imagePullPolicy: Always ports: @@ -37,7 +37,7 @@ spec: mountPath: /app/static - name: www-media mountPath: /app/media - - name: www-supervisor-cfg + - name: www-cfg mountPath: /app/supervisord.conf subPath: supervisord.conf - name: www-cfg @@ -60,27 +60,34 @@ spec: volumes: # To be overriden with the actual shared volume - name: dt-vol - - name: www-supervisor-cfg - configMap: - name: files-supervisor-cfg + # --- - name: www-tmp emptyDir: sizeLimit: "2Gi" - name: www-static emptyDir: sizeLimit: "2Gi" - - name: www-media - name: www-cfg configMap: name: files-cfgmap dnsPolicy: ClusterFirst restartPolicy: Always terminationGracePeriodSeconds: 30 + volumeClaimTemplates: + - metadata: + name: www-media + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 5Gi + storageClassName: "generic" --- apiVersion: v1 kind: Service metadata: - name: ietfweb + name: wagtail spec: type: ClusterIP ports: @@ -89,4 +96,4 @@ spec: protocol: TCP name: http selector: - app: ietfweb + app: wagtail From 1b8ede5da64fbe89eb48792c9431e9a02b890d44 Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Tue, 4 Jun 2024 20:42:49 -0400 Subject: [PATCH 05/22] fix: remove strategy from wagtail.yaml --- k8s/ietfweb/wagtail.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/k8s/ietfweb/wagtail.yaml b/k8s/ietfweb/wagtail.yaml index bf091864..41992a8b 100644 --- a/k8s/ietfweb/wagtail.yaml +++ b/k8s/ietfweb/wagtail.yaml @@ -8,8 +8,6 @@ spec: selector: matchLabels: app: wagtail - strategy: - type: Recreate template: metadata: labels: From abf88d335796fb24aa30ff18cb5429f0b3c2032f Mon Sep 17 00:00:00 2001 From: Kesara Rathnayake Date: Wed, 5 Jun 2024 13:17:18 +1200 Subject: [PATCH 06/22] build: Set DJANGO_SETTINGS_MODULE --- k8s/ietfweb/wagtail.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/k8s/ietfweb/wagtail.yaml b/k8s/ietfweb/wagtail.yaml index 41992a8b..17fa06dd 100644 --- a/k8s/ietfweb/wagtail.yaml +++ b/k8s/ietfweb/wagtail.yaml @@ -44,6 +44,8 @@ spec: env: - name: "CONTAINER_ROLE" value: "ietfweb" + - name: "DJANGO_SETTINGS_MODULE" + value: "ietf.settings.production" envFrom: - configMapRef: name: django-config From 1a50e97f91f3151f3bf33cb2811d6e8a0ea39e06 Mon Sep 17 00:00:00 2001 From: Kesara Rathnayake Date: Wed, 5 Jun 2024 22:42:03 +1200 Subject: [PATCH 07/22] chore: Use IETFWWW instead of IETFWEB --- k8s/ietfweb/django-config.yaml | 14 +++++----- k8s/ietfweb/local.py | 50 +++++++++++++++++----------------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/k8s/ietfweb/django-config.yaml b/k8s/ietfweb/django-config.yaml index c501ff41..2c01f7d7 100644 --- a/k8s/ietfweb/django-config.yaml +++ b/k8s/ietfweb/django-config.yaml @@ -4,18 +4,18 @@ metadata: name: django-config data: # n.b., these are debug values / non-secret secrets - IETFWEB_SERVER_MODE: "development" # development for staging, production for production - IETFWEB_ADMINS: |- + IETFWWW_SERVER_MODE: "development" # development for staging, production for production + IETFWWW_ADMINS: |- Robert Sparks Kesara Rathnayake - IETFWEB_ALLOWED_HOSTS: ".ietf.org" # newline-separated list also allowed + IETFWWW_ALLOWED_HOSTS: ".ietf.org" # newline-separated list also allowed - IETFWEB_DJANGO_SECRET_KEY: "PDwXboUq!=hPjnrtG2=ge#N$Dwy+wn@uivrugwpic8mxyPfHk" # secret + IETFWWW_DJANGO_SECRET_KEY: "PDwXboUq!=hPjnrtG2=ge#N$Dwy+wn@uivrugwpic8mxyPfHk" # secret - # IETFWEB_MATOMO_SITE_ID: "1" # must be present to enable Matomo - # IETFWEB_MATOMO_DOMAIN_PATH: "analytics.ietf.org" + # IETFWWW_MATOMO_SITE_ID: "1" # must be present to enable Matomo + # IETFWWW_MATOMO_DOMAIN_PATH: "analytics.ietf.org" # use this to override default - one entry per line - # IETFWEB_CSRF_TRUSTED_ORIGINS: |- + # IETFWWW_CSRF_TRUSTED_ORIGINS: |- # https://www.staging.ietf.org diff --git a/k8s/ietfweb/local.py b/k8s/ietfweb/local.py index 7fb287df..f5e6fe72 100644 --- a/k8s/ietfweb/local.py +++ b/k8s/ietfweb/local.py @@ -12,21 +12,21 @@ def _multiline_to_list(s): DEFAULT_FROM_EMAIL = "donotreply@ietf.org" SERVER_EMAIL = "donotreply@ietf.org" EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend" -EMAIL_HOST = os.environ.get("IETFWEB_EMAIL_HOST", "localhost") -EMAIL_PORT = int(os.environ.get("IETFWEB_EMAIL_PORT", "2025")) +EMAIL_HOST = os.environ.get("IETFWWW_EMAIL_HOST", "localhost") +EMAIL_PORT = int(os.environ.get("IETFWWW_EMAIL_PORT", "2025")) -# Default to "development". Production _must_ set IETFWEB_SERVER_MODE="production" in the env! -SERVER_MODE = os.environ.get("IETFWEB_SERVER_MODE", "development") +# Default to "development". Production _must_ set IETFWWW_SERVER_MODE="production" in the env! +SERVER_MODE = os.environ.get("IETFWWW_SERVER_MODE", "development") # Secrets -_SECRET_KEY = os.environ.get("IETFWEB_DJANGO_SECRET_KEY", None) +_SECRET_KEY = os.environ.get("IETFWWW_DJANGO_SECRET_KEY", None) if _SECRET_KEY is not None: SECRET_KEY = _SECRET_KEY else: - raise RuntimeError("IETFWEB_DJANGO_SECRET_KEY must be set") + raise RuntimeError("IETFWWW_DJANGO_SECRET_KEY must be set") -_csrf_trusted_origins_str = os.environ.get("IETFWEB_CSRF_TRUSTED_ORIGINS") +_csrf_trusted_origins_str = os.environ.get("IETFWWW_CSRF_TRUSTED_ORIGINS") if _csrf_trusted_origins_str is not None: CSRF_TRUSTED_ORIGINS = _multiline_to_list(_csrf_trusted_origins_str) @@ -37,42 +37,42 @@ def _multiline_to_list(s): else: raise RuntimeError("WAGTAILADMIN_BASE_URL must be present") -# Set DEBUG if IETFWEB_DEBUG env var is the word "true" -DEBUG = os.environ.get("IETFWEB_DEBUG", "false").lower() == "true" +# Set DEBUG if IETFWWW_DEBUG env var is the word "true" +DEBUG = os.environ.get("IETFWWW_DEBUG", "false").lower() == "true" -# IETFWEB_ALLOWED_HOSTS env var is a comma-separated list of allowed hosts -_allowed_hosts_str = os.environ.get("IETFWEB_ALLOWED_HOSTS", None) +# IETFWWW_ALLOWED_HOSTS env var is a comma-separated list of allowed hosts +_allowed_hosts_str = os.environ.get("IETFWWW_ALLOWED_HOSTS", None) if _allowed_hosts_str is not None: ALLOWED_HOSTS = _multiline_to_list(_allowed_hosts_str) DATABASES = { "default": { "ENGINE": "django.db.backends.postgresql_psycopg2", - "HOST": os.environ.get("IETFWEB_DB_HOST", "db"), - "PORT": os.environ.get("IETFWEB_DB_PORT", "5432"), - "NAME": os.environ.get("IETFWEB_DB_NAME", "ietfweb"), - "USER": os.environ.get("IETFWEB_DB_USER", "django"), - "PASSWORD": os.environ.get("IETFWEB_DB_PASS", ""), + "HOST": os.environ.get("IETFWWW_DB_HOST", "db"), + "PORT": os.environ.get("IETFWWW_DB_PORT", "5432"), + "NAME": os.environ.get("IETFWWW_DB_NAME", "ietfweb"), + "USER": os.environ.get("IETFWWW_DB_USER", "django"), + "PASSWORD": os.environ.get("IETFWWW_DB_PASS", ""), "CONN_MAX_AGE": 600, # number of seconds database connections should persist for }, } -# IETFWEB_ADMINS is a newline-delimited list of addresses parseable by email.utils.parseaddr -_admins_str = os.environ.get("IETFWEB_ADMINS", None) +# IETFWWW_ADMINS is a newline-delimited list of addresses parseable by email.utils.parseaddr +_admins_str = os.environ.get("IETFWWW_ADMINS", None) if _admins_str is not None: ADMINS = [parseaddr(admin) for admin in _multiline_to_list(_admins_str)] else: - raise RuntimeError("IETFWEB_ADMINS must be set") + raise RuntimeError("IETFWWW_ADMINS must be set") -# Leave IETFWEB_MATOMO_SITE_ID unset to disable Matomo reporting -if "IETFWEB_MATOMO_SITE_ID" in os.environ: - MATOMO_DOMAIN_PATH = os.environ.get("IETFWEB_MATOMO_DOMAIN_PATH", "analytics.ietf.org") - MATOMO_SITE_ID = os.environ.get("IETFWEB_MATOMO_SITE_ID") +# Leave IETFWWW_MATOMO_SITE_ID unset to disable Matomo reporting +if "IETFWWW_MATOMO_SITE_ID" in os.environ: + MATOMO_DOMAIN_PATH = os.environ.get("IETFWWW_MATOMO_DOMAIN_PATH", "analytics.ietf.org") + MATOMO_SITE_ID = os.environ.get("IETFWWW_MATOMO_SITE_ID") MATOMO_DISABLE_COOKIES = True # Duplicating production cache from settings.py and using it whether we're in production mode or not -MEMCACHED_HOST = os.environ.get("IETFWEB_MEMCACHED_SERVICE_HOST", "127.0.0.1") -MEMCACHED_PORT = os.environ.get("IETFWEB_MEMCACHED_SERVICE_PORT", "11211") +MEMCACHED_HOST = os.environ.get("IETFWWW_MEMCACHED_SERVICE_HOST", "127.0.0.1") +MEMCACHED_PORT = os.environ.get("IETFWWW_MEMCACHED_SERVICE_PORT", "11211") MEMCACHED_KEY_PREFIX = "ietf" CACHES = { "default": { From 8d7fd8476fe0cffb1e4bca0004445ef46ad4c1c4 Mon Sep 17 00:00:00 2001 From: Kesara Rathnayake Date: Thu, 6 Jun 2024 16:36:40 +1200 Subject: [PATCH 08/22] feat: Expose /id --- k8s/ietfweb/kustomization.yaml | 2 ++ k8s/ietfweb/nginx-default.conf | 30 +++++++++++++++++++ k8s/ietfweb/nginx.conf | 53 ++++++++++++++++++++++++++++++++++ k8s/ietfweb/wagtail.yaml | 15 ++++++++-- 4 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 k8s/ietfweb/nginx-default.conf create mode 100644 k8s/ietfweb/nginx.conf diff --git a/k8s/ietfweb/kustomization.yaml b/k8s/ietfweb/kustomization.yaml index 6c3074fb..469ee3ac 100644 --- a/k8s/ietfweb/kustomization.yaml +++ b/k8s/ietfweb/kustomization.yaml @@ -5,6 +5,8 @@ configMapGenerator: files: - local.py - supervisord.conf + - nginx-default.conf + - nginx.conf resources: - django-config.yaml - memcached.yaml diff --git a/k8s/ietfweb/nginx-default.conf b/k8s/ietfweb/nginx-default.conf new file mode 100644 index 00000000..cf314b0a --- /dev/null +++ b/k8s/ietfweb/nginx-default.conf @@ -0,0 +1,30 @@ +server { + listen 8080 default_server; + listen [::]:8080 default_server; + server_name _; + gzip on; + access_log /dev/stdout; + error_log /dev/stdout warn; + location / { + proxy_pass http://127.0.0.1:8000; + proxy_set_header Host $${keepempty}host; + proxy_set_header X-Forwarded-For $${keepempty}proxy_add_x_forwarded_for; + } + location /media/ { + alias /app/media/; + } + location /static/ { + alias /app/static/; + } + location /id { + alias /a/ietfdata/draft/archive/; + autoindex on; + autoindex_exact_size off; + autoindex_localtime on; + charset utf-8; + + location ~* \.xml$ { + add_header Content-Disposition 'attachment'; + } + } +} diff --git a/k8s/ietfweb/nginx.conf b/k8s/ietfweb/nginx.conf new file mode 100644 index 00000000..dd68b9bc --- /dev/null +++ b/k8s/ietfweb/nginx.conf @@ -0,0 +1,53 @@ +worker_processes auto; +pid /var/lib/nginx/nginx.pid; +error_log /dev/stdout; +include /etc/nginx/modules-enabled/*.conf; + +events { + worker_connections 768; + # multi_accept on; +} + +http { + + ## + # Basic Settings + ## + + sendfile on; + tcp_nopush on; + types_hash_max_size 2048; + # server_tokens off; + + # server_names_hash_bucket_size 64; + # server_name_in_redirect off; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + ## + # SSL Settings + ## + + ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE + ssl_prefer_server_ciphers on; + + ## + # Logging Settings + ## + + access_log /dev/stdout; + + ## + # Gzip Settings + ## + + gzip on; + + ## + # Virtual Host Configs + ## + + include /etc/nginx/conf.d/*.conf; + include /etc/nginx/sites-enabled/*; +} diff --git a/k8s/ietfweb/wagtail.yaml b/k8s/ietfweb/wagtail.yaml index 17fa06dd..6f1d9ad2 100644 --- a/k8s/ietfweb/wagtail.yaml +++ b/k8s/ietfweb/wagtail.yaml @@ -23,7 +23,7 @@ spec: image: "ghcr.io/ietf-tools/www:$APP_IMAGE_TAG" imagePullPolicy: Always ports: - - containerPort: 8000 + - containerPort: 8080 name: http protocol: TCP volumeMounts: @@ -31,6 +31,8 @@ spec: mountPath: /a - name: www-tmp mountPath: /tmp + - name: www-nginx + mountPath: /var/lib/nginx - name: www-static mountPath: /app/static - name: www-media @@ -41,6 +43,12 @@ spec: - name: www-cfg mountPath: /app/ietf/settings/local.py subPath: local.py + - name: www-cfg + mountPath: /etc/nginx/nginx.conf + subPath: nginx.conf + - name: www-cfg + mountPath: /etc/nginx/sites-enabled/default + subPath: nginx-default.conf env: - name: "CONTAINER_ROLE" value: "ietfweb" @@ -63,7 +71,10 @@ spec: # --- - name: www-tmp emptyDir: - sizeLimit: "2Gi" + sizeLimit: "1Gi" + - name: www-nginx + emptyDir: + sizeLimit: "1Gi" - name: www-static emptyDir: sizeLimit: "2Gi" From 071de210f5cc64400dc848c5106a19af675514d8 Mon Sep 17 00:00:00 2001 From: Kesara Rathnayake Date: Tue, 11 Jun 2024 09:18:01 +1200 Subject: [PATCH 09/22] chore: Expose /charter --- k8s/ietfweb/nginx-default.conf | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/k8s/ietfweb/nginx-default.conf b/k8s/ietfweb/nginx-default.conf index cf314b0a..3380ce8b 100644 --- a/k8s/ietfweb/nginx-default.conf +++ b/k8s/ietfweb/nginx-default.conf @@ -23,6 +23,17 @@ server { autoindex_localtime on; charset utf-8; + location ~* \.xml$ { + add_header Content-Disposition 'attachment'; + } + } + location /charter { + alias /a/ietfdata/doc/charter/; + autoindex on; + autoindex_exact_size off; + autoindex_localtime on; + charset utf-8; + location ~* \.xml$ { add_header Content-Disposition 'attachment'; } From 5ad2e5e394aa5d113f551e498aa1e47486c53770 Mon Sep 17 00:00:00 2001 From: Kesara Rathnayake Date: Tue, 11 Jun 2024 09:35:52 +1200 Subject: [PATCH 10/22] chore: Expose /cr --- k8s/ietfweb/nginx-default.conf | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/k8s/ietfweb/nginx-default.conf b/k8s/ietfweb/nginx-default.conf index 3380ce8b..a48d5e8a 100644 --- a/k8s/ietfweb/nginx-default.conf +++ b/k8s/ietfweb/nginx-default.conf @@ -34,6 +34,17 @@ server { autoindex_localtime on; charset utf-8; + location ~* \.xml$ { + add_header Content-Disposition 'attachment'; + } + } + location /cr { + alias /a/ietfdata/doc/conflict-review/; + autoindex on; + autoindex_exact_size off; + autoindex_localtime on; + charset utf-8; + location ~* \.xml$ { add_header Content-Disposition 'attachment'; } From 1a292fefd7fc2a363fd95fd55bc786f8120bed65 Mon Sep 17 00:00:00 2001 From: Kesara Rathnayake Date: Tue, 11 Jun 2024 09:47:55 +1200 Subject: [PATCH 11/22] build: Use static from the image --- k8s/ietfweb/wagtail.yaml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/k8s/ietfweb/wagtail.yaml b/k8s/ietfweb/wagtail.yaml index 6f1d9ad2..039290d8 100644 --- a/k8s/ietfweb/wagtail.yaml +++ b/k8s/ietfweb/wagtail.yaml @@ -33,8 +33,6 @@ spec: mountPath: /tmp - name: www-nginx mountPath: /var/lib/nginx - - name: www-static - mountPath: /app/static - name: www-media mountPath: /app/media - name: www-cfg @@ -75,9 +73,6 @@ spec: - name: www-nginx emptyDir: sizeLimit: "1Gi" - - name: www-static - emptyDir: - sizeLimit: "2Gi" - name: www-cfg configMap: name: files-cfgmap From a702ee36ecfc875ebf990809bcbb084b6b7b0125 Mon Sep 17 00:00:00 2001 From: Kesara Rathnayake Date: Tue, 11 Jun 2024 09:57:07 +1200 Subject: [PATCH 12/22] chore: Expose /slides --- k8s/ietfweb/nginx-default.conf | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/k8s/ietfweb/nginx-default.conf b/k8s/ietfweb/nginx-default.conf index a48d5e8a..c2544dbc 100644 --- a/k8s/ietfweb/nginx-default.conf +++ b/k8s/ietfweb/nginx-default.conf @@ -45,6 +45,17 @@ server { autoindex_localtime on; charset utf-8; + location ~* \.xml$ { + add_header Content-Disposition 'attachment'; + } + } + location /slides { + alias /a/ietfdata/doc/slides/; + autoindex on; + autoindex_exact_size off; + autoindex_localtime on; + charset utf-8; + location ~* \.xml$ { add_header Content-Disposition 'attachment'; } From 5ac0460cd1d63fe2662091525e8976940c9a794f Mon Sep 17 00:00:00 2001 From: Kesara Rathnayake Date: Tue, 11 Jun 2024 11:10:29 +1200 Subject: [PATCH 13/22] chore: Expose /archive/id --- k8s/ietfweb/nginx-default.conf | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/k8s/ietfweb/nginx-default.conf b/k8s/ietfweb/nginx-default.conf index c2544dbc..12dac7de 100644 --- a/k8s/ietfweb/nginx-default.conf +++ b/k8s/ietfweb/nginx-default.conf @@ -56,6 +56,17 @@ server { autoindex_localtime on; charset utf-8; + location ~* \.xml$ { + add_header Content-Disposition 'attachment'; + } + } + location /archive/id { + alias /a/ietfdata/draft/archive/; + autoindex on; + autoindex_exact_size off; + autoindex_localtime on; + charset utf-8; + location ~* \.xml$ { add_header Content-Disposition 'attachment'; } From c3f387f87148825a4a8cf8be62c0e3b1507d897f Mon Sep 17 00:00:00 2001 From: Kesara Rathnayake Date: Tue, 11 Jun 2024 11:13:40 +1200 Subject: [PATCH 14/22] fix: Expose correct dir for /id --- k8s/ietfweb/nginx-default.conf | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/k8s/ietfweb/nginx-default.conf b/k8s/ietfweb/nginx-default.conf index 12dac7de..3e7faca5 100644 --- a/k8s/ietfweb/nginx-default.conf +++ b/k8s/ietfweb/nginx-default.conf @@ -16,8 +16,8 @@ server { location /static/ { alias /app/static/; } - location /id { - alias /a/ietfdata/draft/archive/; + location /charter { + alias /a/ietfdata/doc/charter/; autoindex on; autoindex_exact_size off; autoindex_localtime on; @@ -27,8 +27,8 @@ server { add_header Content-Disposition 'attachment'; } } - location /charter { - alias /a/ietfdata/doc/charter/; + location /cr { + alias /a/ietfdata/doc/conflict-review/; autoindex on; autoindex_exact_size off; autoindex_localtime on; @@ -38,8 +38,8 @@ server { add_header Content-Disposition 'attachment'; } } - location /cr { - alias /a/ietfdata/doc/conflict-review/; + location /slides { + alias /a/ietfdata/doc/slides/; autoindex on; autoindex_exact_size off; autoindex_localtime on; @@ -49,8 +49,8 @@ server { add_header Content-Disposition 'attachment'; } } - location /slides { - alias /a/ietfdata/doc/slides/; + location /archive/id { + alias /a/ietfdata/draft/archive/; autoindex on; autoindex_exact_size off; autoindex_localtime on; @@ -60,8 +60,8 @@ server { add_header Content-Disposition 'attachment'; } } - location /archive/id { - alias /a/ietfdata/draft/archive/; + location /id { + alias /a/ietfdata/draft/repository; autoindex on; autoindex_exact_size off; autoindex_localtime on; From 00b8c7682ef76bc3c226cabc8330a826353e0b32 Mon Sep 17 00:00:00 2001 From: Kesara Rathnayake Date: Tue, 11 Jun 2024 13:18:12 +1200 Subject: [PATCH 15/22] chore: Expose /ietf-ftp --- k8s/ietfweb/nginx-default.conf | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/k8s/ietfweb/nginx-default.conf b/k8s/ietfweb/nginx-default.conf index 3e7faca5..a2c18b2e 100644 --- a/k8s/ietfweb/nginx-default.conf +++ b/k8s/ietfweb/nginx-default.conf @@ -67,6 +67,17 @@ server { autoindex_localtime on; charset utf-8; + location ~* \.xml$ { + add_header Content-Disposition 'attachment'; + } + } + location /ietf-ftp { + alias /a/www/ietf-ftp; + autoindex on; + autoindex_exact_size off; + autoindex_localtime on; + charset utf-8; + location ~* \.xml$ { add_header Content-Disposition 'attachment'; } From 0dbcce2233172a2524fb069756e2c2212cc75438 Mon Sep 17 00:00:00 2001 From: Kesara Rathnayake Date: Tue, 11 Jun 2024 13:21:06 +1200 Subject: [PATCH 16/22] chore: Expose /rfc --- k8s/ietfweb/nginx-default.conf | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/k8s/ietfweb/nginx-default.conf b/k8s/ietfweb/nginx-default.conf index a2c18b2e..07e81f54 100644 --- a/k8s/ietfweb/nginx-default.conf +++ b/k8s/ietfweb/nginx-default.conf @@ -78,6 +78,17 @@ server { autoindex_localtime on; charset utf-8; + location ~* \.xml$ { + add_header Content-Disposition 'attachment'; + } + } + location /rfc { + alias /a/www/ietf-ftp/rfc; + autoindex on; + autoindex_exact_size off; + autoindex_localtime on; + charset utf-8; + location ~* \.xml$ { add_header Content-Disposition 'attachment'; } From 5253c7b81e86ca85055141c750cd656a056a0edd Mon Sep 17 00:00:00 2001 From: Kesara Rathnayake Date: Wed, 12 Jun 2024 10:44:28 +1200 Subject: [PATCH 17/22] fix: Add defaults for all os.environ.get() --- k8s/ietfweb/local.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/k8s/ietfweb/local.py b/k8s/ietfweb/local.py index f5e6fe72..9b1ee7f3 100644 --- a/k8s/ietfweb/local.py +++ b/k8s/ietfweb/local.py @@ -26,7 +26,7 @@ def _multiline_to_list(s): raise RuntimeError("IETFWWW_DJANGO_SECRET_KEY must be set") -_csrf_trusted_origins_str = os.environ.get("IETFWWW_CSRF_TRUSTED_ORIGINS") +_csrf_trusted_origins_str = os.environ.get("IETFWWW_CSRF_TRUSTED_ORIGINS", None) if _csrf_trusted_origins_str is not None: CSRF_TRUSTED_ORIGINS = _multiline_to_list(_csrf_trusted_origins_str) @@ -67,7 +67,7 @@ def _multiline_to_list(s): # Leave IETFWWW_MATOMO_SITE_ID unset to disable Matomo reporting if "IETFWWW_MATOMO_SITE_ID" in os.environ: MATOMO_DOMAIN_PATH = os.environ.get("IETFWWW_MATOMO_DOMAIN_PATH", "analytics.ietf.org") - MATOMO_SITE_ID = os.environ.get("IETFWWW_MATOMO_SITE_ID") + MATOMO_SITE_ID = os.environ.get("IETFWWW_MATOMO_SITE_ID", None) MATOMO_DISABLE_COOKIES = True # Duplicating production cache from settings.py and using it whether we're in production mode or not From 6ce5f7a4556cbeedf174fdc3eff5c01ab7f8ad8a Mon Sep 17 00:00:00 2001 From: Kesara Rathnayake Date: Wed, 12 Jun 2024 10:49:22 +1200 Subject: [PATCH 18/22] fix: Consistent use of character case --- k8s/ietfweb/local.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/k8s/ietfweb/local.py b/k8s/ietfweb/local.py index 9b1ee7f3..6703dd03 100644 --- a/k8s/ietfweb/local.py +++ b/k8s/ietfweb/local.py @@ -26,9 +26,9 @@ def _multiline_to_list(s): raise RuntimeError("IETFWWW_DJANGO_SECRET_KEY must be set") -_csrf_trusted_origins_str = os.environ.get("IETFWWW_CSRF_TRUSTED_ORIGINS", None) -if _csrf_trusted_origins_str is not None: - CSRF_TRUSTED_ORIGINS = _multiline_to_list(_csrf_trusted_origins_str) +_CSRF_TRUSTED_ORIGINS_STR = os.environ.get("IETFWWW_CSRF_TRUSTED_ORIGINS", None) +if _CSRF_TRUSTED_ORIGINS_STR is not None: + CSRF_TRUSTED_ORIGINS = _multiline_to_list(_CSRF_TRUSTED_ORIGINS_STR) FILE_UPLOAD_PERMISSIONS = 0o664 _WAGTAILADMIN_BASE_URL = os.environ.get("WAGTAILADMIN_BASE_URL", None) @@ -41,9 +41,9 @@ def _multiline_to_list(s): DEBUG = os.environ.get("IETFWWW_DEBUG", "false").lower() == "true" # IETFWWW_ALLOWED_HOSTS env var is a comma-separated list of allowed hosts -_allowed_hosts_str = os.environ.get("IETFWWW_ALLOWED_HOSTS", None) -if _allowed_hosts_str is not None: - ALLOWED_HOSTS = _multiline_to_list(_allowed_hosts_str) +_ALLOWED_HOSTS_STR = os.environ.get("IETFWWW_ALLOWED_HOSTS", None) +if _ALLOWED_HOSTS_STR is not None: + ALLOWED_HOSTS = _multiline_to_list(_ALLOWED_HOSTS_STR) DATABASES = { "default": { From aead1e09ab0966e0e818728600d1ab349a1cbb94 Mon Sep 17 00:00:00 2001 From: Kesara Rathnayake Date: Wed, 12 Jun 2024 10:58:46 +1200 Subject: [PATCH 19/22] fix: Remove SERVER_MODE --- k8s/ietfweb/django-config.yaml | 2 -- k8s/ietfweb/local.py | 3 --- 2 files changed, 5 deletions(-) diff --git a/k8s/ietfweb/django-config.yaml b/k8s/ietfweb/django-config.yaml index 2c01f7d7..6aedd8f8 100644 --- a/k8s/ietfweb/django-config.yaml +++ b/k8s/ietfweb/django-config.yaml @@ -3,8 +3,6 @@ kind: ConfigMap metadata: name: django-config data: - # n.b., these are debug values / non-secret secrets - IETFWWW_SERVER_MODE: "development" # development for staging, production for production IETFWWW_ADMINS: |- Robert Sparks Kesara Rathnayake diff --git a/k8s/ietfweb/local.py b/k8s/ietfweb/local.py index 6703dd03..3392becc 100644 --- a/k8s/ietfweb/local.py +++ b/k8s/ietfweb/local.py @@ -15,9 +15,6 @@ def _multiline_to_list(s): EMAIL_HOST = os.environ.get("IETFWWW_EMAIL_HOST", "localhost") EMAIL_PORT = int(os.environ.get("IETFWWW_EMAIL_PORT", "2025")) -# Default to "development". Production _must_ set IETFWWW_SERVER_MODE="production" in the env! -SERVER_MODE = os.environ.get("IETFWWW_SERVER_MODE", "development") - # Secrets _SECRET_KEY = os.environ.get("IETFWWW_DJANGO_SECRET_KEY", None) if _SECRET_KEY is not None: From 2e05a4daee167cce2c124d78f63e02ebab3ad62a Mon Sep 17 00:00:00 2001 From: Kesara Rathnayake Date: Wed, 12 Jun 2024 11:09:51 +1200 Subject: [PATCH 20/22] fix: Change 8 spaces to 4 spaces --- k8s/ietfweb/nginx.conf | 62 +++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/k8s/ietfweb/nginx.conf b/k8s/ietfweb/nginx.conf index dd68b9bc..66790987 100644 --- a/k8s/ietfweb/nginx.conf +++ b/k8s/ietfweb/nginx.conf @@ -4,50 +4,50 @@ error_log /dev/stdout; include /etc/nginx/modules-enabled/*.conf; events { - worker_connections 768; - # multi_accept on; + worker_connections 768; + # multi_accept on; } http { - ## - # Basic Settings - ## + ## + # Basic Settings + ## - sendfile on; - tcp_nopush on; - types_hash_max_size 2048; - # server_tokens off; + sendfile on; + tcp_nopush on; + types_hash_max_size 2048; + # server_tokens off; - # server_names_hash_bucket_size 64; - # server_name_in_redirect off; + # server_names_hash_bucket_size 64; + # server_name_in_redirect off; - include /etc/nginx/mime.types; - default_type application/octet-stream; + include /etc/nginx/mime.types; + default_type application/octet-stream; - ## - # SSL Settings - ## + ## + # SSL Settings + ## - ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE - ssl_prefer_server_ciphers on; + ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE + ssl_prefer_server_ciphers on; - ## - # Logging Settings - ## + ## + # Logging Settings + ## - access_log /dev/stdout; + access_log /dev/stdout; - ## - # Gzip Settings - ## + ## + # Gzip Settings + ## - gzip on; + gzip on; - ## - # Virtual Host Configs - ## + ## + # Virtual Host Configs + ## - include /etc/nginx/conf.d/*.conf; - include /etc/nginx/sites-enabled/*; + include /etc/nginx/conf.d/*.conf; + include /etc/nginx/sites-enabled/*; } From 9038e7018b785db22de22719f212e27c62befcd7 Mon Sep 17 00:00:00 2001 From: Kesara Rathnayake Date: Wed, 12 Jun 2024 11:29:41 +1200 Subject: [PATCH 21/22] chore: Define fsGroup in securityContext --- k8s/ietfweb/wagtail.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/k8s/ietfweb/wagtail.yaml b/k8s/ietfweb/wagtail.yaml index 039290d8..9d672dc9 100644 --- a/k8s/ietfweb/wagtail.yaml +++ b/k8s/ietfweb/wagtail.yaml @@ -14,6 +14,7 @@ spec: app: wagtail spec: securityContext: + fsGroup: 1000 runAsNonRoot: true containers: # ----------------------------------------------------- From ea2e38451a7002ecdc9995851a0e95a693dd8023 Mon Sep 17 00:00:00 2001 From: Kesara Rathnayake Date: Thu, 13 Jun 2024 08:10:31 +1200 Subject: [PATCH 22/22] feat: Use wagtail 404 for all 404 errors --- k8s/ietfweb/nginx-default.conf | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/k8s/ietfweb/nginx-default.conf b/k8s/ietfweb/nginx-default.conf index 07e81f54..23e62478 100644 --- a/k8s/ietfweb/nginx-default.conf +++ b/k8s/ietfweb/nginx-default.conf @@ -12,9 +12,13 @@ server { } location /media/ { alias /app/media/; + + error_page 404 = @error_redirect; } location /static/ { alias /app/static/; + + error_page 404 = @error_redirect; } location /charter { alias /a/ietfdata/doc/charter/; @@ -26,6 +30,8 @@ server { location ~* \.xml$ { add_header Content-Disposition 'attachment'; } + + error_page 404 = @error_redirect; } location /cr { alias /a/ietfdata/doc/conflict-review/; @@ -37,6 +43,8 @@ server { location ~* \.xml$ { add_header Content-Disposition 'attachment'; } + + error_page 404 = @error_redirect; } location /slides { alias /a/ietfdata/doc/slides/; @@ -48,6 +56,8 @@ server { location ~* \.xml$ { add_header Content-Disposition 'attachment'; } + + error_page 404 = @error_redirect; } location /archive/id { alias /a/ietfdata/draft/archive/; @@ -59,6 +69,8 @@ server { location ~* \.xml$ { add_header Content-Disposition 'attachment'; } + + error_page 404 = @error_redirect; } location /id { alias /a/ietfdata/draft/repository; @@ -70,6 +82,8 @@ server { location ~* \.xml$ { add_header Content-Disposition 'attachment'; } + + error_page 404 = @error_redirect; } location /ietf-ftp { alias /a/www/ietf-ftp; @@ -81,6 +95,8 @@ server { location ~* \.xml$ { add_header Content-Disposition 'attachment'; } + + error_page 404 = @error_redirect; } location /rfc { alias /a/www/ietf-ftp/rfc; @@ -92,5 +108,12 @@ server { location ~* \.xml$ { add_header Content-Disposition 'attachment'; } + + error_page 404 = @error_redirect; + } + location @error_redirect { + proxy_pass http://127.0.0.1:8000; + proxy_set_header Host $${keepempty}host; + proxy_set_header X-Forwarded-For $${keepempty}proxy_add_x_forwarded_for; } }