From a0e0c4c621bcc372aeb334dc7fbc5107be4c4e30 Mon Sep 17 00:00:00 2001 From: Ochieng Paul Date: Tue, 10 Dec 2024 15:43:30 +0300 Subject: [PATCH 1/4] updating settings file --- src/website/core/settings.py | 87 ++++++++++++++++++++++++++++++++++-- src/website/entrypoint.sh | 24 ++++++++-- 2 files changed, 104 insertions(+), 7 deletions(-) diff --git a/src/website/core/settings.py b/src/website/core/settings.py index 80b50328d9..2dda70d5fd 100644 --- a/src/website/core/settings.py +++ b/src/website/core/settings.py @@ -55,7 +55,7 @@ def require_env_var(env_var: str) -> str: ALLOWED_HOSTS = parse_env_list('ALLOWED_HOSTS', default='localhost,127.0.0.1') # --------------------------------------------------------- -# Applications +# Installed Apps # --------------------------------------------------------- INSTALLED_APPS = [ # Django Defaults @@ -115,9 +115,11 @@ def require_env_var(env_var: str) -> str: CORS_ALLOWED_ORIGIN_REGEXES = parse_env_list('CORS_ORIGIN_REGEX_WHITELIST') CSRF_TRUSTED_ORIGINS = parse_env_list('CSRF_TRUSTED_ORIGINS') -# If no CORS settings provided, consider defaulting to empty lists -CORS_ALLOWED_ORIGINS = CORS_ALLOWED_ORIGINS if CORS_ALLOWED_ORIGINS else [] -CORS_ALLOWED_ORIGIN_REGEXES = CORS_ALLOWED_ORIGIN_REGEXES if CORS_ALLOWED_ORIGIN_REGEXES else [] +# Ensure no trailing slashes and correct schemes +CORS_ALLOWED_ORIGINS = [origin.rstrip('/') for origin in CORS_ALLOWED_ORIGINS] +CORS_ALLOWED_ORIGIN_REGEXES = [regex.rstrip( + '/') for regex in CORS_ALLOWED_ORIGIN_REGEXES] +CSRF_TRUSTED_ORIGINS = [origin.rstrip('/') for origin in CSRF_TRUSTED_ORIGINS] # Security cookies CSRF_COOKIE_SECURE = not DEBUG @@ -269,3 +271,80 @@ def require_env_var(env_var: str) -> str: 'scrollingContainer': '#scrolling-container', }, } + +# --------------------------------------------------------- +# File Upload Settings +# --------------------------------------------------------- +# Increase these values as needed to handle larger uploads +FILE_UPLOAD_MAX_MEMORY_SIZE = 10485760 # 10 MB +DATA_UPLOAD_MAX_MEMORY_SIZE = 10485760 # 10 MB + +# --------------------------------------------------------- +# SSL and Proxy Settings (if behind a reverse proxy) +# --------------------------------------------------------- +# Uncomment and configure if your Django app is behind a reverse proxy like Nginx +SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') +USE_X_FORWARDED_HOST = True + +# --------------------------------------------------------- +# Logging Configuration +# --------------------------------------------------------- +LOG_DIR = BASE_DIR / 'logs' +LOG_DIR.mkdir(exist_ok=True) # Ensure log directory exists + +LOGGING = { + 'version': 1, + 'disable_existing_loggers': False, + # Formatters + 'formatters': { + 'verbose': { + 'format': '[%(asctime)s] %(levelname)s %(name)s [%(filename)s:%(lineno)d] %(message)s', + 'datefmt': '%Y-%m-%d %H:%M:%S' + }, + 'simple': { + 'format': '%(levelname)s %(message)s' + }, + }, + # Handlers + 'handlers': { + 'console': { + 'class': 'logging.StreamHandler', + 'formatter': 'verbose', + 'level': 'DEBUG' if DEBUG else 'INFO', + }, + 'file': { + 'class': 'logging.FileHandler', + 'filename': LOG_DIR / 'django.log', + 'formatter': 'verbose', + 'level': 'INFO', + }, + 'error_file': { + 'class': 'logging.FileHandler', + 'filename': LOG_DIR / 'django_errors.log', + 'formatter': 'verbose', + 'level': 'ERROR', + }, + }, + # Loggers + 'loggers': { + # Django Logs + 'django': { + 'handlers': ['console', 'file', 'error_file'], + 'level': 'INFO', + 'propagate': True, + }, + # Cloudinary Logs + 'cloudinary': { + 'handlers': ['console', 'file', 'error_file'], + 'level': 'INFO', + 'propagate': True, + }, + # Event App Logs + 'apps.event': { + 'handlers': ['console', 'file', 'error_file'], + 'level': 'DEBUG' if DEBUG else 'INFO', + 'propagate': False, + }, + # Add other app loggers here if needed + } +} diff --git a/src/website/entrypoint.sh b/src/website/entrypoint.sh index 915d69698b..cc23b20934 100644 --- a/src/website/entrypoint.sh +++ b/src/website/entrypoint.sh @@ -3,15 +3,33 @@ # Exit immediately if a command exits with a non-zero status set -e +# Function to handle signals and gracefully shut down Gunicorn +_term() { + echo "Caught SIGTERM signal! Shutting down Gunicorn..." + kill -TERM "$child" 2>/dev/null +} + +# Trap SIGTERM signal +trap _term SIGTERM + # Run Django migrations echo "Running migrations..." python manage.py migrate --noinput -# Collect static files (ensure the static files directory exists) +# Collect static files echo "Collecting static files..." python manage.py collectstatic --noinput +# Pre-create logs directory if not exists +echo "Ensuring log directory exists..." +mkdir -p /app/logs + # Start Gunicorn server to serve the Django application echo "Starting Gunicorn server..." -exec gunicorn core.wsgi:application --bind 0.0.0.0:8000 --timeout 600 --log-level info -# exec gunicorn core.wsgi:application --bind 0.0.0.0:8000 --timeout 600 --workers ${GUNICORN_WORKERS:-3} --log-level info +exec gunicorn core.wsgi:application \ + --bind 0.0.0.0:8000 \ + --timeout 600 \ + --log-level info \ + --workers "${GUNICORN_WORKERS:-3}" \ + --access-logfile '-' \ + --error-logfile '-' From ef2bccee9667c3901a5a319b201dc14b9dbf5efd Mon Sep 17 00:00:00 2001 From: Ochieng Paul Date: Tue, 10 Dec 2024 16:02:55 +0300 Subject: [PATCH 2/4] update --- src/website/Dockerfile | 2 +- src/website/core/settings.py | 1 - src/website/entrypoint.sh | 4 ++-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/website/Dockerfile b/src/website/Dockerfile index 449e362eac..dfe98b351b 100644 --- a/src/website/Dockerfile +++ b/src/website/Dockerfile @@ -22,7 +22,7 @@ RUN pip install --no-cache-dir -r requirements.txt COPY . . # Expose the port the Django app will run on -EXPOSE 8000 +EXPOSE 8080 # Add execution permissions to entrypoint.sh RUN chmod +x /app/entrypoint.sh diff --git a/src/website/core/settings.py b/src/website/core/settings.py index 2dda70d5fd..437d9088dd 100644 --- a/src/website/core/settings.py +++ b/src/website/core/settings.py @@ -282,7 +282,6 @@ def require_env_var(env_var: str) -> str: # --------------------------------------------------------- # SSL and Proxy Settings (if behind a reverse proxy) # --------------------------------------------------------- -# Uncomment and configure if your Django app is behind a reverse proxy like Nginx SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') USE_X_FORWARDED_HOST = True diff --git a/src/website/entrypoint.sh b/src/website/entrypoint.sh index cc23b20934..a7ac8823cc 100644 --- a/src/website/entrypoint.sh +++ b/src/website/entrypoint.sh @@ -25,9 +25,9 @@ echo "Ensuring log directory exists..." mkdir -p /app/logs # Start Gunicorn server to serve the Django application -echo "Starting Gunicorn server..." +echo "Starting Gunicorn server on port $PORT..." exec gunicorn core.wsgi:application \ - --bind 0.0.0.0:8000 \ + --bind 0.0.0.0:$PORT \ --timeout 600 \ --log-level info \ --workers "${GUNICORN_WORKERS:-3}" \ From afc8bbef837ef284eb3bc2e2ff976b1418a138d9 Mon Sep 17 00:00:00 2001 From: Ochieng Paul Date: Tue, 10 Dec 2024 16:07:30 +0300 Subject: [PATCH 3/4] updates --- src/website/Dockerfile | 2 +- src/website/entrypoint.sh | 25 +++---------------------- 2 files changed, 4 insertions(+), 23 deletions(-) diff --git a/src/website/Dockerfile b/src/website/Dockerfile index dfe98b351b..449e362eac 100644 --- a/src/website/Dockerfile +++ b/src/website/Dockerfile @@ -22,7 +22,7 @@ RUN pip install --no-cache-dir -r requirements.txt COPY . . # Expose the port the Django app will run on -EXPOSE 8080 +EXPOSE 8000 # Add execution permissions to entrypoint.sh RUN chmod +x /app/entrypoint.sh diff --git a/src/website/entrypoint.sh b/src/website/entrypoint.sh index a7ac8823cc..217438654c 100644 --- a/src/website/entrypoint.sh +++ b/src/website/entrypoint.sh @@ -3,33 +3,14 @@ # Exit immediately if a command exits with a non-zero status set -e -# Function to handle signals and gracefully shut down Gunicorn -_term() { - echo "Caught SIGTERM signal! Shutting down Gunicorn..." - kill -TERM "$child" 2>/dev/null -} - -# Trap SIGTERM signal -trap _term SIGTERM - # Run Django migrations echo "Running migrations..." python manage.py migrate --noinput -# Collect static files +# Collect static files (ensure the static files directory exists) echo "Collecting static files..." python manage.py collectstatic --noinput -# Pre-create logs directory if not exists -echo "Ensuring log directory exists..." -mkdir -p /app/logs - # Start Gunicorn server to serve the Django application -echo "Starting Gunicorn server on port $PORT..." -exec gunicorn core.wsgi:application \ - --bind 0.0.0.0:$PORT \ - --timeout 600 \ - --log-level info \ - --workers "${GUNICORN_WORKERS:-3}" \ - --access-logfile '-' \ - --error-logfile '-' +echo "Starting Gunicorn server..." +exec gunicorn core.wsgi:application --bind 0.0.0.0:8000 --timeout 600 --workers 3 --log-level info From fff06671f8be3c8f19f86afa8e17d0fe6a19f149 Mon Sep 17 00:00:00 2001 From: Ochieng Paul Date: Tue, 10 Dec 2024 16:15:30 +0300 Subject: [PATCH 4/4] updates --- src/website/core/settings.py | 73 +++++++++++++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) diff --git a/src/website/core/settings.py b/src/website/core/settings.py index 437d9088dd..5bffef8789 100644 --- a/src/website/core/settings.py +++ b/src/website/core/settings.py @@ -344,6 +344,77 @@ def require_env_var(env_var: str) -> str: 'level': 'DEBUG' if DEBUG else 'INFO', 'propagate': False, }, - # Add other app loggers here if needed + # CleanAir App Logs + 'apps.cleanair': { + 'handlers': ['console', 'file', 'error_file'], + 'level': 'DEBUG' if DEBUG else 'INFO', + 'propagate': False, + }, + # AfricanCities App Logs + 'apps.africancities': { + 'handlers': ['console', 'file', 'error_file'], + 'level': 'DEBUG' if DEBUG else 'INFO', + 'propagate': False, + }, + # Publications App Logs + 'apps.publications': { + 'handlers': ['console', 'file', 'error_file'], + 'level': 'DEBUG' if DEBUG else 'INFO', + 'propagate': False, + }, + # Press App Logs + 'apps.press': { + 'handlers': ['console', 'file', 'error_file'], + 'level': 'DEBUG' if DEBUG else 'INFO', + 'propagate': False, + }, + # Impact App Logs + 'apps.impact': { + 'handlers': ['console', 'file', 'error_file'], + 'level': 'DEBUG' if DEBUG else 'INFO', + 'propagate': False, + }, + # FAQs App Logs + 'apps.faqs': { + 'handlers': ['console', 'file', 'error_file'], + 'level': 'DEBUG' if DEBUG else 'INFO', + 'propagate': False, + }, + # Highlights App Logs + 'apps.highlights': { + 'handlers': ['console', 'file', 'error_file'], + 'level': 'DEBUG' if DEBUG else 'INFO', + 'propagate': False, + }, + # Career App Logs + 'apps.career': { + 'handlers': ['console', 'file', 'error_file'], + 'level': 'DEBUG' if DEBUG else 'INFO', + 'propagate': False, + }, + # Partners App Logs + 'apps.partners': { + 'handlers': ['console', 'file', 'error_file'], + 'level': 'DEBUG' if DEBUG else 'INFO', + 'propagate': False, + }, + # Board App Logs + 'apps.board': { + 'handlers': ['console', 'file', 'error_file'], + 'level': 'DEBUG' if DEBUG else 'INFO', + 'propagate': False, + }, + # Team App Logs + 'apps.team': { + 'handlers': ['console', 'file', 'error_file'], + 'level': 'DEBUG' if DEBUG else 'INFO', + 'propagate': False, + }, + # ExternalTeams App Logs + 'apps.externalteams': { + 'handlers': ['console', 'file', 'error_file'], + 'level': 'DEBUG' if DEBUG else 'INFO', + 'propagate': False, + }, } }