only restart issue and logout issue debugging added
This commit is contained in:
@@ -22,6 +22,10 @@ RUN pip install --upgrade pip \
|
||||
# Copy full project
|
||||
COPY . /app/
|
||||
|
||||
# Copy startup script
|
||||
COPY container_startup.sh /app/
|
||||
RUN chmod +x /app/container_startup.sh
|
||||
|
||||
# Collect static files for WhiteNoise (skip during build if DB not available)
|
||||
# Will be run during container startup if needed
|
||||
RUN python manage.py collectstatic --noinput || echo "Skipping collectstatic during build"
|
||||
@@ -32,5 +36,7 @@ ENV DJANGO_SETTINGS_MODULE=igny8_core.settings
|
||||
# Expose port for Gunicorn (matches Portainer docker-compose config)
|
||||
EXPOSE 8010
|
||||
|
||||
# Use startup script as entrypoint to log container lifecycle
|
||||
# Start using Gunicorn (matches Portainer docker-compose config)
|
||||
ENTRYPOINT ["/app/container_startup.sh"]
|
||||
CMD ["gunicorn", "igny8_core.wsgi:application", "--bind", "0.0.0.0:8010"]
|
||||
|
||||
47
backend/container_startup.sh
Normal file
47
backend/container_startup.sh
Normal file
@@ -0,0 +1,47 @@
|
||||
#!/bin/bash
|
||||
# Container Startup Logger
|
||||
# Logs container lifecycle events for debugging restarts
|
||||
|
||||
set -e
|
||||
|
||||
echo "=========================================="
|
||||
echo "[CONTAINER-STARTUP] $(date '+%Y-%m-%d %H:%M:%S')"
|
||||
echo "Container: igny8_backend"
|
||||
echo "Hostname: $(hostname)"
|
||||
echo "PID: $$"
|
||||
echo "=========================================="
|
||||
|
||||
# Log environment info
|
||||
echo "[INFO] Python version: $(python --version 2>&1)"
|
||||
echo "[INFO] Django settings: ${DJANGO_SETTINGS_MODULE:-igny8_core.settings}"
|
||||
echo "[INFO] Debug mode: ${DEBUG:-False}"
|
||||
echo "[INFO] Database host: ${DB_HOST:-not set}"
|
||||
|
||||
# Check if this is a restart (look for previous process artifacts)
|
||||
if [ -f /tmp/container_pid ]; then
|
||||
PREV_PID=$(cat /tmp/container_pid)
|
||||
echo "[WARNING] Previous container PID found: $PREV_PID"
|
||||
echo "[WARNING] This appears to be a RESTART event"
|
||||
echo "[WARNING] Check Docker logs for SIGTERM/SIGKILL signals"
|
||||
else
|
||||
echo "[INFO] First startup (no previous PID file found)"
|
||||
fi
|
||||
|
||||
# Save current PID
|
||||
echo $$ > /tmp/container_pid
|
||||
|
||||
# Run database migrations (will skip if up to date)
|
||||
echo "[INFO] Running database migrations..."
|
||||
python manage.py migrate --noinput || echo "[WARNING] Migration failed or skipped"
|
||||
|
||||
# Collect static files (skip if already done)
|
||||
echo "[INFO] Collecting static files..."
|
||||
python manage.py collectstatic --noinput || echo "[WARNING] Collectstatic failed or skipped"
|
||||
|
||||
echo "=========================================="
|
||||
echo "[CONTAINER-STARTUP] Initialization complete"
|
||||
echo "[CONTAINER-STARTUP] Starting Gunicorn..."
|
||||
echo "=========================================="
|
||||
|
||||
# Execute the CMD passed to the script (Gunicorn command)
|
||||
exec "$@"
|
||||
@@ -2,11 +2,14 @@
|
||||
Multi-Account Middleware
|
||||
Extracts account from JWT token and injects into request context
|
||||
"""
|
||||
import logging
|
||||
from django.utils.deprecation import MiddlewareMixin
|
||||
from django.http import JsonResponse
|
||||
from django.contrib.auth import logout
|
||||
from rest_framework import status
|
||||
|
||||
logger = logging.getLogger('auth.middleware')
|
||||
|
||||
try:
|
||||
import jwt
|
||||
JWT_AVAILABLE = True
|
||||
@@ -54,6 +57,11 @@ class AccountContextMiddleware(MiddlewareMixin):
|
||||
stored_user_id = request.session.get('_user_id')
|
||||
if stored_account_id and stored_account_id != request.account.id:
|
||||
# Session contamination detected - force logout
|
||||
logger.warning(
|
||||
f"[AUTO-LOGOUT] Session contamination: account_id mismatch. "
|
||||
f"Session={stored_account_id}, Current={request.account.id}, "
|
||||
f"User={request.user.id}, Path={request.path}, IP={request.META.get('REMOTE_ADDR')}"
|
||||
)
|
||||
logout(request)
|
||||
return JsonResponse(
|
||||
{'success': False, 'error': 'Session integrity violation detected. Please login again.'},
|
||||
@@ -61,6 +69,12 @@ class AccountContextMiddleware(MiddlewareMixin):
|
||||
)
|
||||
if stored_user_id and stored_user_id != request.user.id:
|
||||
# Session contamination detected - force logout
|
||||
logger.warning(
|
||||
f"[AUTO-LOGOUT] Session contamination: user_id mismatch. "
|
||||
f"Session={stored_user_id}, Current={request.user.id}, "
|
||||
f"Account={request.account.id if request.account else None}, "
|
||||
f"Path={request.path}, IP={request.META.get('REMOTE_ADDR')}"
|
||||
)
|
||||
logout(request)
|
||||
return JsonResponse(
|
||||
{'success': False, 'error': 'Session integrity violation detected. Please login again.'},
|
||||
@@ -173,9 +187,14 @@ class AccountContextMiddleware(MiddlewareMixin):
|
||||
"""Logout session users (if any) and return a consistent JSON error."""
|
||||
try:
|
||||
if hasattr(request, 'user') and request.user and request.user.is_authenticated:
|
||||
logger.warning(
|
||||
f"[AUTO-LOGOUT] Account/plan validation failed: {error}. "
|
||||
f"User={request.user.id}, Account={getattr(request, 'account', None)}, "
|
||||
f"Path={request.path}, IP={request.META.get('REMOTE_ADDR')}"
|
||||
)
|
||||
logout(request)
|
||||
except Exception:
|
||||
pass
|
||||
except Exception as e:
|
||||
logger.error(f"[AUTO-LOGOUT] Error during logout: {e}")
|
||||
|
||||
return JsonResponse(
|
||||
{
|
||||
|
||||
@@ -604,6 +604,16 @@ LOGGING = {
|
||||
'level': 'INFO',
|
||||
'propagate': False,
|
||||
},
|
||||
'auth.middleware': {
|
||||
'handlers': ['console'],
|
||||
'level': 'INFO',
|
||||
'propagate': False,
|
||||
},
|
||||
'container.lifecycle': {
|
||||
'handlers': ['console'],
|
||||
'level': 'INFO',
|
||||
'propagate': False,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user