#!/bin/sh set -eu echo "Starting IoT PreTester 4.6 Demo backend (LOG_LEVEL=${LOG_LEVEL:-info})" echo "tshark: $(tshark -v 2>/dev/null | head -n 1 || echo 'NOT FOUND')" mkdir -p /app/data /app/files/uploads /app/logs /app/django_project/staticfiles cd /app/django_project python manage.py migrate --noinput python manage.py collectstatic --noinput # Keep the configured demo administrator reproducible across container restarts. python manage.py shell <<'PY' import os from django.contrib.auth import get_user_model from django.utils.timezone import now User = get_user_model() username = os.environ.get("DJANGO_SUPERUSER_USERNAME", "admin") email = os.environ.get("DJANGO_SUPERUSER_EMAIL", "admin@example.com") password = os.environ["DJANGO_SUPERUSER_PASSWORD"] user, created = User.objects.get_or_create(username=username, defaults={"email": email}) user.email = email user.is_superuser = True user.is_staff = True user.is_active = True user.set_password(password) user.last_login = now() user.save() print("Demo administrator created" if created else "Demo administrator synchronized") PY # A restart loses in-flight background analyses. Without this the frontend # would poll a capture that is stuck in "analyzing" forever. python manage.py shell <<'PY' from IoTAnalyzer.models import File stale = File.objects.filter(status__in=["analyzing", "pending"]) count = stale.count() if count: stale.update(status="analysis_failed") print(f"Reset {count} interrupted capture analyses") PY if [ "${INIT_DATABASE:-true}" = "true" ]; then python create_models.py fi # Errors and application logs go to stdout/stderr so `docker compose logs` # shows them; /app/logs keeps rotating copies (backend.log, access.log). exec gunicorn IoTPreTester.wsgi:application \ --bind 0.0.0.0:8000 \ --workers "${GUNICORN_WORKERS:-4}" \ --timeout "${GUNICORN_TIMEOUT:-120}" \ --access-logfile /app/logs/access.log \ --error-logfile - \ --capture-output \ --log-level "${LOG_LEVEL:-info}"