Configuration Reference

βš™οΈ Configuration Reference

Premium Documentation β€” Everything you need to configure SkysPy for any environment


πŸ“‹ Quick Reference Card

πŸ“Œ

Info Copy these essential settings to get started quickly!

# Minimum Required Configuration
DJANGO_SECRET_KEY=your-secure-random-key-here
FEEDER_LAT=47.9377
FEEDER_LON=-121.9687
AUTH_MODE=hybrid
SettingPurposeGet Started
πŸ”‘ DJANGO_SECRET_KEYCryptographic securitypython -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())"
πŸ“ FEEDER_LAT/LONYour antenna locationUse GPS coordinates in decimal degrees
πŸ” AUTH_MODEAccess controlpublic / private / hybrid
πŸ—„οΈ DATABASE_URLDatabase connectionpostgresql://user:pass@host:5432/db

πŸ—οΈ Configuration Architecture

flowchart TD
    subgraph Sources["πŸ“ Configuration Sources"]
        ENV["πŸ”§ .env File"]
        DOCKER["🐳 Docker Environment"]
        RUNTIME["⚑ Runtime / Admin"]
    end

    subgraph Layers["🎚️ Configuration Layers"]
        ENV --> DJANGO["🐍 Django Settings"]
        DOCKER --> DJANGO
        DJANGO --> COMPOSE["πŸ“¦ Docker Compose"]
        COMPOSE --> RUNTIME
    end

    subgraph Outputs["🎯 Applied To"]
        RUNTIME --> API["🌐 API Server"]
        RUNTIME --> CELERY["⏰ Celery Workers"]
        RUNTIME --> WS["πŸ“‘ Socket.IO Channels"]
        RUNTIME --> FRONTEND["πŸ’» Frontend"]
    end

    style ENV fill:#e1f5fe
    style DJANGO fill:#fff3e0
    style COMPOSE fill:#f3e5f5
    style RUNTIME fill:#e8f5e9

πŸš€ Quick Start Steps

  1. Copy .env.example to .env
  2. Set DJANGO_SECRET_KEY to a secure random value
  3. Configure FEEDER_LAT and FEEDER_LON for your antenna location
  4. Set AUTH_MODE based on your security requirements
  5. Run docker-compose up -d

πŸ”§ Core Django Settings

⚠️

Warning Never enable DEBUG=True in production environments. This exposes sensitive debugging information.

VariableDescriptionDefaultStatus
DEBUGEnable Django debug modeFalseβšͺ Optional
DJANGO_SECRET_KEYDjango secret key for cryptographic signingNoneπŸ”΄ Required
ALLOWED_HOSTSComma-separated list of allowed host/domain nameslocalhost,127.0.0.1,[::1]βšͺ Optional
DJANGO_LOG_LEVELLog level for Django frameworkINFOβšͺ Optional
BUILD_MODESet to True during Docker builds to skip external connectionsFalseβšͺ Optional
DJANGO_SETTINGS_MODULEPython path to settings moduleskyspy.settingsβšͺ Optional
πŸ’‘

Tip For Raspberry Pi deployments, use DJANGO_SETTINGS_MODULE=skyspy.settings_rpi for optimized performance.

πŸ‘€ Default Superuser (Auto-Created on Startup)

VariableDescriptionDefaultStatus
DJANGO_SUPERUSER_USERNAMEUsername for auto-created admin accountadminβšͺ Optional
DJANGO_SUPERUSER_EMAILEmail for auto-created admin account[email protected]βšͺ Optional
DJANGO_SUPERUSER_PASSWORDPassword for auto-created admin accountchangeme🟑 Change in production

πŸ” Authentication & Authorization

Authentication Modes

flowchart LR
    subgraph Modes["πŸ” AUTH_MODE Options"]
        PUBLIC["🌍 public<br/>No auth required"]
        HYBRID["πŸ”€ hybrid<br/>Per-feature control"]
        PRIVATE["πŸ”’ private<br/>Full authentication"]
    end

    PUBLIC -.->|"Development"| DEV["πŸ’» Local Dev"]
    HYBRID -.->|"Recommended"| PROD["🏭 Production"]
    PRIVATE -.->|"High Security"| ENT["🏒 Enterprise"]

    style PUBLIC fill:#fff9c4
    style HYBRID fill:#c8e6c9
    style PRIVATE fill:#ffcdd2
ModeDescriptionUse Case
🌍 publicNo authentication required for any endpointLocal/development use
πŸ”€ hybridPer-feature access control with granular permissionsProduction (recommended)
πŸ”’ privateAuthentication required for all endpointsMaximum security
VariableDescriptionDefaultStatus
AUTH_MODEAuthentication modehybridβšͺ Optional
LOCAL_AUTH_ENABLEDEnable local username/password authenticationTrueβšͺ Optional
API_KEY_ENABLEDEnable API key authenticationTrueβšͺ Optional

🎫 JWT Configuration

VariableDescriptionDefaultStatus
JWT_SECRET_KEYSecret key for JWT signingUses DJANGO_SECRET_KEY🟑 Recommended
JWT_ACCESS_TOKEN_LIFETIME_MINUTESAccess token validity period60βšͺ Optional
JWT_REFRESH_TOKEN_LIFETIME_DAYSRefresh token validity period2βšͺ Optional
JWT_AUTH_COOKIEUse httpOnly cookie for refresh token storageFalseβšͺ Optional
πŸ’‘

Tip Use a different secret key for JWT_SECRET_KEY than your DJANGO_SECRET_KEY for better security isolation.

πŸ”— OIDC / SSO Configuration

Enable Single Sign-On with identity providers like Keycloak, Authentik, Azure AD, Okta, or Auth0.

VariableDescriptionDefaultStatus
OIDC_ENABLEDEnable OIDC authenticationFalseβšͺ Optional
OIDC_PROVIDER_NAMEDisplay name shown on login buttonSSOβšͺ Optional
OIDC_PROVIDER_URLAuthorization server base URLNoneπŸ”΄ If OIDC enabled
OIDC_CLIENT_IDClient ID from your OIDC providerNoneπŸ”΄ If OIDC enabled
OIDC_CLIENT_SECRETClient secret from your OIDC providerNoneπŸ”΄ If OIDC enabled
OIDC_SCOPESSpace-separated OAuth scopes to requestopenid profile email groupsβšͺ Optional
OIDC_DEFAULT_ROLEDefault role for new OIDC usersviewerβšͺ Optional
πŸ“š OIDC Provider Configuration Examples

Keycloak

OIDC_ENABLED=True
OIDC_PROVIDER_NAME=Keycloak
OIDC_PROVIDER_URL=https://keycloak.example.com/realms/skyspy
OIDC_CLIENT_ID=skyspy-client
OIDC_CLIENT_SECRET=<client-secret>

Authentik

OIDC_ENABLED=True
OIDC_PROVIDER_NAME=Authentik
OIDC_PROVIDER_URL=https://authentik.example.com/application/o/skyspy
OIDC_CLIENT_ID=<client-id>
OIDC_CLIENT_SECRET=<client-secret>

Azure AD / Entra ID

OIDC_ENABLED=True
OIDC_PROVIDER_NAME=Microsoft
OIDC_PROVIDER_URL=https://login.microsoftonline.com/{tenant-id}/v2.0
OIDC_CLIENT_ID=<application-client-id>
OIDC_CLIENT_SECRET=<client-secret-value>
OIDC_SCOPES=openid profile email

πŸ—„οΈ Database & Cache

PostgreSQL Configuration

VariableDescriptionDefaultStatus
DATABASE_URLPostgreSQL connection URLpostgresql://adsb:adsb@postgres:5432/adsbβšͺ Optional
POSTGRES_USERPostgreSQL username (Docker Compose)adsbβšͺ Optional
POSTGRES_PASSWORDPostgreSQL password (Docker Compose)adsbβšͺ Optional
POSTGRES_DBPostgreSQL database name (Docker Compose)adsbβšͺ Optional

Redis Configuration

VariableDescriptionDefaultStatus
REDIS_URLRedis connection URL for Celery, cache, and channelsredis://redis:6379/0βšͺ Optional

Caching Settings

VariableDescriptionDefaultStatus
CACHE_TTLDefault cache time-to-live in seconds5βšͺ Optional
UPSTREAM_API_MIN_INTERVALMinimum seconds between upstream API calls60βšͺ Optional

πŸ“‘ ADS-B Data Sources

Feeder Configuration

πŸ“Œ

Info Accurate feeder location is essential for distance calculations and range analytics.

VariableDescriptionDefaultStatus
FEEDER_LATLatitude of your antenna position (decimal degrees)47.9377🟑 Recommended
FEEDER_LONLongitude of your antenna position (decimal degrees)-121.9687🟑 Recommended
ULTRAFEEDER_HOSTHostname of Ultrafeeder/readsb/tar1090 serviceultrafeederβšͺ Optional
ULTRAFEEDER_PORTHTTP port of Ultrafeeder service80βšͺ Optional
DUMP978_HOSTHostname of dump978 UAT servicedump978βšͺ Optional
DUMP978_PORTHTTP port of dump978 service80βšͺ Optional

Polling & Session Configuration

VariableDescriptionDefaultStatus
POLLING_INTERVALSeconds between ADS-B polls from data sources2βšͺ Optional
DB_STORE_INTERVALSeconds between database position writes5βšͺ Optional
SESSION_TIMEOUT_MINUTESMinutes of inactivity before aircraft session ends30βšͺ Optional

πŸ›‘οΈ Safety Monitoring

⚠️

Warning Safety monitoring generates alerts for potential aviation safety events. Review thresholds carefully for your environment.

VariableDescriptionDefaultStatus
SAFETY_MONITORING_ENABLEDEnable safety event detection and alertsTrueβšͺ Optional
SAFETY_VS_CHANGE_THRESHOLDVertical speed change threshold (ft/min)2000βšͺ Optional
SAFETY_VS_EXTREME_THRESHOLDExtreme vertical speed threshold (ft/min)6000βšͺ Optional
SAFETY_PROXIMITY_NMProximity alert distance in nautical miles0.5βšͺ Optional
SAFETY_ALTITUDE_DIFF_FTAltitude difference for proximity alerts (feet)500βšͺ Optional
SAFETY_CLOSURE_RATE_KTClosure rate threshold for alerts (knots)200βšͺ Optional
SAFETY_TCAS_VS_THRESHOLDTCAS vertical speed threshold (ft/min)1500βšͺ Optional

πŸ”” Alerts & Notifications

Default Alert Configuration

VariableDescriptionDefaultStatus
PROXIMITY_ALERT_NMDefault proximity alert radius in nautical miles5.0βšͺ Optional
WATCH_ICAO_LISTComma-separated ICAO hex codes to watchEmptyβšͺ Optional
WATCH_FLIGHT_LISTComma-separated flight numbers to watchEmptyβšͺ Optional
ALERT_MILITARYGenerate alerts for military aircraftTrueβšͺ Optional
ALERT_EMERGENCYGenerate alerts for emergency squawks (7500, 7600, 7700)Trueβšͺ Optional

πŸ“² Apprise Notifications

SkysPy uses Apprise for multi-platform notifications.

VariableDescriptionDefaultStatus
APPRISE_URLSComma-separated Apprise notification URLsEmptyβšͺ Optional
NOTIFICATION_COOLDOWNSeconds between duplicate notifications300βšͺ Optional
πŸ“š Apprise URL Examples
# Telegram
APPRISE_URLS=telegram://bot_token/chat_id

# Discord
APPRISE_URLS=discord://webhook_id/webhook_token

# Slack
APPRISE_URLS=slack://token_a/token_b/token_c

# Pushover
APPRISE_URLS=pushover://user_key/app_token

# Email
APPRISE_URLS=email://user:[email protected]

# Multiple services (comma-separated)
APPRISE_URLS=telegram://...,discord://...,email://...

πŸ“» ACARS / VDL2 Configuration

VariableDescriptionDefaultStatus
ACARS_ENABLEDEnable ACARS message processingTrueβšͺ Optional
ACARS_PORTUDP port for ACARS messages5555βšͺ Optional
VDLM2_PORTUDP port for VDL Mode 2 messages5556βšͺ Optional

πŸŽ™οΈ Radio & Audio

Radio Configuration

VariableDescriptionDefaultStatus
RADIO_ENABLEDEnable radio transmission processingTrueβšͺ Optional
RADIO_AUDIO_DIRDirectory for audio file storage/data/radioβšͺ Optional
RADIO_MAX_FILE_SIZE_MBMaximum audio file size in megabytes50βšͺ Optional
RADIO_RETENTION_DAYSDays to retain audio files7βšͺ Optional
RADIO_S3_PREFIXS3 prefix for radio file storageradio-transmissionsβšͺ Optional

🎀 Transcription Configuration

VariableDescriptionDefaultStatus
TRANSCRIPTION_ENABLEDEnable audio transcriptionFalseβšͺ Optional
TRANSCRIPTION_SERVICE_URLExternal transcription service URLNoneπŸ”΄ If using external
TRANSCRIPTION_MODELModel to use for transcriptionNoneβšͺ Optional
TRANSCRIPTION_API_KEYAPI key for transcription serviceNoneπŸ”΄ If using external

Whisper Configuration

VariableDescriptionDefaultStatus
WHISPER_ENABLEDEnable local Whisper transcriptionFalseβšͺ Optional
WHISPER_URLURL of Whisper servicehttp://whisper:9000βšͺ Optional
🎯 ATC-Whisper Configuration (Specialized ATC Transcription)
VariableDescriptionDefaultStatus
ATC_WHISPER_ENABLEDEnable ATC-optimized Whisper transcriptionFalseβšͺ Optional
ATC_WHISPER_MAX_CONCURRENTMaximum concurrent transcription jobs2βšͺ Optional
ATC_WHISPER_SEGMENT_BY_VADUse voice activity detection for segmentationTrueβšͺ Optional
ATC_WHISPER_PREPROCESSEnable audio preprocessingTrueβšͺ Optional
ATC_WHISPER_NOISE_REDUCEEnable noise reductionTrueβšͺ Optional
ATC_WHISPER_POSTPROCESSEnable post-processing cleanupTrueβšͺ Optional

πŸ€– LLM API Configuration

Optional LLM integration for improved callsign extraction accuracy from transcripts.

VariableDescriptionDefaultStatus
LLM_ENABLEDEnable LLM-enhanced transcript analysisFalseβšͺ Optional
LLM_API_URLOpenAI-compatible API endpointhttps://api.openai.com/v1βšͺ Optional
LLM_API_KEYAPI key (not needed for local Ollama)EmptyπŸ”΄ If using cloud
LLM_MODELModel to usegpt-4o-miniβšͺ Optional
LLM_TIMEOUTRequest timeout in seconds30βšͺ Optional
LLM_MAX_RETRIESMaximum retries on failure3βšͺ Optional
LLM_CACHE_TTLCache TTL in seconds3600βšͺ Optional
LLM_MAX_TOKENSMaximum response tokens500βšͺ Optional
LLM_TEMPERATURETemperature (lower = more deterministic)0.1βšͺ Optional
πŸ“š LLM Provider Examples

OpenAI

LLM_ENABLED=True
LLM_API_URL=https://api.openai.com/v1
LLM_API_KEY=sk-xxx
LLM_MODEL=gpt-4o-mini

Local Ollama

LLM_ENABLED=True
LLM_API_URL=http://localhost:11434/v1
LLM_API_KEY=ollama
LLM_MODEL=llama3.2

Anthropic via OpenRouter

LLM_ENABLED=True
LLM_API_URL=https://openrouter.ai/api/v1
LLM_API_KEY=sk-or-xxx
LLM_MODEL=anthropic/claude-3-haiku

πŸ“· Photo Cache Configuration

VariableDescriptionDefaultStatus
PHOTO_CACHE_ENABLEDEnable aircraft photo cachingTrueβšͺ Optional
PHOTO_CACHE_DIRDirectory for cached photos/data/photosβšͺ Optional
PHOTO_AUTO_DOWNLOADAutomatically download photos for tracked aircraftTrueβšͺ Optional

☁️ S3 / Object Storage

VariableDescriptionDefaultStatus
S3_ENABLEDEnable S3 storage for photos and audioFalseβšͺ Optional
S3_BUCKETS3 bucket nameEmptyπŸ”΄ If S3 enabled
S3_REGIONAWS regionus-east-1βšͺ Optional
S3_ACCESS_KEYAWS access key IDNoneπŸ”΄ If S3 enabled
S3_SECRET_KEYAWS secret access keyNoneπŸ”΄ If S3 enabled
S3_ENDPOINT_URLCustom endpoint URL for S3-compatible storageNoneβšͺ Optional
S3_PREFIXPrefix for photo storageaircraft-photosβšͺ Optional
S3_PUBLIC_URLPublic URL for serving filesNoneβšͺ Optional

🌐 External Data Sources

OpenSky Database

VariableDescriptionDefaultStatus
OPENSKY_DB_ENABLEDEnable OpenSky aircraft database lookupTrueβšͺ Optional
OPENSKY_DB_PATHPath to OpenSky CSV database file/data/opensky/aircraft-database.csvβšͺ Optional
🌍 External API Integrations

CheckWX Weather API

VariableDescriptionDefaultStatus
CHECKWX_ENABLEDEnable CheckWX weather data (3,000 req/day free)Falseβšͺ Optional
CHECKWX_API_KEYCheckWX API keyEmptyπŸ”΄ If enabled

AVWX Weather API

VariableDescriptionDefaultStatus
AVWX_ENABLEDEnable AVWX weather data (unlimited basic)Trueβšͺ Optional
AVWX_API_KEYAVWX API key (optional, higher rate limits)Emptyβšͺ Optional

OpenAIP Airspace

VariableDescriptionDefaultStatus
OPENAIP_ENABLEDEnable OpenAIP airspace dataFalseβšͺ Optional
OPENAIP_API_KEYOpenAIP API keyEmptyπŸ”΄ If enabled

OpenSky Network Live API

VariableDescriptionDefaultStatus
OPENSKY_LIVE_ENABLEDEnable OpenSky live data (4,000 credits/day free)Falseβšͺ Optional
OPENSKY_USERNAMEOpenSky Network usernameEmptyπŸ”΄ If enabled
OPENSKY_PASSWORDOpenSky Network passwordEmptyπŸ”΄ If enabled

ADS-B Exchange Live API

VariableDescriptionDefaultStatus
ADSBX_LIVE_ENABLEDEnable ADS-B Exchange live data via RapidAPIFalseβšͺ Optional
ADSBX_RAPIDAPI_KEYRapidAPI key for ADS-B ExchangeEmptyπŸ”΄ If enabled

Aviationstack Flight Schedules

VariableDescriptionDefaultStatus
AVIATIONSTACK_ENABLEDEnable Aviationstack schedules (100 req/month free)Falseβšͺ Optional
AVIATIONSTACK_API_KEYAviationstack API keyEmptyπŸ”΄ If enabled

πŸ“Š Monitoring & Observability

Sentry Error Tracking

VariableDescriptionDefaultStatus
SENTRY_DSNSentry DSN for error trackingEmptyβšͺ Optional
SENTRY_ENVIRONMENTEnvironment tag (e.g., production, staging)developmentβšͺ Optional
SENTRY_TRACES_SAMPLE_RATEPerformance tracing sample rate (0.0 to 1.0)0.1βšͺ Optional
SENTRY_PROFILES_SAMPLE_RATEProfiling sample rate (0.0 to 1.0)0.1βšͺ Optional

Prometheus Metrics

VariableDescriptionDefaultStatus
PROMETHEUS_ENABLEDEnable Prometheus metrics endpointTrueβšͺ Optional

🌍 CORS Configuration

VariableDescriptionDefaultStatus
CORS_ALLOWED_ORIGINSComma-separated list of allowed CORS originsEmptyβšͺ Optional
CORS_ALLOWED_ORIGINS=http://localhost:3000,http://127.0.0.1:3000,https://skyspy.example.com

πŸ”’ Security Settings

VariableDescriptionDefaultStatus
FORCE_SECURE_COOKIESForce secure cookie flags in debug modeFalseβšͺ Optional

🐍 Django Settings Files

settings.py (Standard Configuration)

The main settings file provides the default configuration for most deployments.

CharacteristicValue
Polling Interval2 seconds
Database Store Interval5 seconds
All FeaturesEnabled
Cache TTL5 seconds
Logging LevelINFO (DEBUG when DEBUG=True)

settings_rpi.py (Raspberry Pi Optimization)

πŸ’‘

Tip Use DJANGO_SETTINGS_MODULE=skyspy.settings_rpi for resource-constrained deployments.

# Enable RPi settings via environment
export DJANGO_SETTINGS_MODULE=skyspy.settings_rpi

# Or in Docker Compose
environment:
  - DJANGO_SETTINGS_MODULE=skyspy.settings_rpi
πŸ“ Raspberry Pi Optimization Details

Performance Comparison

SettingStandardRPi-OptimizedImpact
POLLING_INTERVAL2s3s~33% CPU reduction
DB_STORE_INTERVAL5s10s50% fewer DB writes
CACHE_TTL5s10sFewer cache refreshes
MAX_SEEN_AIRCRAFT10,0005,00050% memory savings
ACARS_BUFFER_SIZE5030Reduced buffer memory
WEBSOCKET_CAPACITY1,5001,000Lower memory usage
CONN_MAX_AGE60s120sFewer DB connections

Task Interval Overrides

TaskStandardRPi-Optimized
Flight pattern/geographic stats2 min10 min
Time comparison stats5 min15 min
Tracking quality stats2 min10 min
Engagement stats2 min10 min
Antenna analytics5 min10 min
ACARS stats60s2 min
Stats cache60s90s
Safety stats30s60s

Data Retention (Reduced)

Data TypeStandardRPi
Sighting retention30 days7 days
Session retention90 days14 days
Alert history30 days7 days
Antenna snapshots7 days3 days

Query Limits

LimitValue
MAX_HISTORY_HOURS72 hours
MAX_QUERY_RESULTS10,000
MAX_STATS_SAMPLE_SIZE1,000

πŸ’» Frontend Configuration

The frontend stores user preferences in browser localStorage via /web/src/utils/config.js.

Default Configuration

{
  apiBaseUrl: '',              // Always empty (uses relative URLs)
  mapMode: 'pro',              // Map display mode
  mapDarkMode: true,           // Dark mode enabled
  browserNotifications: false, // Browser notification permission
  shortTrackLength: 15,        // Track trail positions (5-50)
}

πŸ—ΊοΈ Map Modes

ModeDescription
πŸ“‘ radarClassic radar sweep display
πŸ–₯️ crtRetro CRT monitor aesthetic
✈️ proProfessional aviation display
πŸ—ΊοΈ mapStandard map view
🎨 Default Overlay Settings
{
  aircraft: true,       // Aircraft icons
  vors: true,           // VOR navigation aids
  airports: true,       // Airport locations
  airspace: true,       // Airspace boundaries
  metars: false,        // Weather observations
  pireps: false,        // Pilot reports

  // Terrain overlays (pro mode)
  water: false,
  counties: false,
  states: false,
  countries: false,

  // Aviation overlays (pro mode)
  usArtcc: false,       // US ARTCC boundaries
  usRefueling: false,   // US A2A refueling tracks
  ukMilZones: false,    // UK military zones
  euMilAwacs: false,    // EU military AWACS orbits
  trainingAreas: false  // IFT/USAFA training areas
}

Vite Development Configuration

VariableDescriptionDefault
VITE_API_TARGETBackend API URL for proxyhttp://localhost:8000
NODE_ENVNode environmentdevelopment
DASHBOARD_PORTFrontend dev server port3000

🚩 Feature Flags

πŸ“‹ Complete Feature Flag Reference

Core Features

FeatureEnvironment VariableDefault
Safety MonitoringSAFETY_MONITORING_ENABLEDTrue
ACARS ProcessingACARS_ENABLEDTrue
Photo CachingPHOTO_CACHE_ENABLEDTrue
Auto Photo DownloadPHOTO_AUTO_DOWNLOADTrue
Radio ProcessingRADIO_ENABLEDTrue
OpenSky DatabaseOPENSKY_DB_ENABLEDTrue
PrometheusPROMETHEUS_ENABLEDTrue
Local AuthLOCAL_AUTH_ENABLEDTrue
API Key AuthAPI_KEY_ENABLEDTrue

Optional Features (Disabled by Default)

FeatureEnvironment VariableDefault
TranscriptionTRANSCRIPTION_ENABLEDFalse
WhisperWHISPER_ENABLEDFalse
ATC WhisperATC_WHISPER_ENABLEDFalse
LLM AnalysisLLM_ENABLEDFalse
S3 StorageS3_ENABLEDFalse
OIDC/SSOOIDC_ENABLEDFalse

External Data Sources

FeatureEnvironment VariableDefault
AVWX WeatherAVWX_ENABLEDTrue
CheckWX WeatherCHECKWX_ENABLEDFalse
OpenAIP AirspaceOPENAIP_ENABLEDFalse
OpenSky LiveOPENSKY_LIVE_ENABLEDFalse
ADS-B ExchangeADSBX_LIVE_ENABLEDFalse
AviationstackAVIATIONSTACK_ENABLEDFalse

⚑ Performance Tuning

πŸ“‘ Socket.IO Rate Limiting

Control Socket.IO broadcast frequencies to prevent client overload:

WS_RATE_LIMITS = {
    'aircraft:update': 10,      # Max 10 Hz
    'aircraft:position': 5,     # Max 5 Hz for position-only
    'aircraft:delta': 10,       # Max 10 Hz for delta updates
    'stats:update': 0.5,        # Max 0.5 Hz (2s minimum)
    'default': 5,               # Default rate limit
}
πŸ“¦ Message Batching

Configure message batching for efficiency:

WS_BATCH_WINDOW_MS = 50         # Collect messages for 50ms
WS_MAX_BATCH_SIZE = 50          # Maximum messages per batch
WS_IMMEDIATE_TYPES = [          # Types that bypass batching
    'alert', 'safety', 'emergency',
    'aircraft:update', 'aircraft:new', 'aircraft:position',
]
⏰ Celery Worker Configuration
# docker-compose.yml
celery-worker:
  command: >
    celery -A skyspy worker
    --loglevel=info
    --concurrency=100          # Adjust based on resources
    --queues=polling,default,database,transcription,notifications
    --pool=gevent              # Greenlet-based concurrency

Task Queue Routing

QueueTasksPriority
pollingAircraft polling, stats updatesHigh
defaultGeneral tasksNormal
databaseExternal DB sync, cleanupLow
transcriptionAudio transcriptionLow
notificationsAlert notificationsNormal
low_priorityAnalytics, cleanupLowest
πŸ”΄ Redis Configuration
redis:
  command: >
    redis-server
    --appendonly yes
    --maxmemory 256mb
    --maxmemory-policy allkeys-lru
πŸ“‘ Channel Layer Configuration
CHANNEL_LAYERS = {
    'default': {
        'BACKEND': 'channels_redis.core.RedisChannelLayer',
        'CONFIG': {
            'hosts': [REDIS_URL],
            'capacity': 1500,      # Message capacity per channel
            'expiry': 60,          # Message expiry (seconds)
            'group_expiry': 300,   # Group membership expiry
        },
    },
}
πŸ—„οΈ Database Connection Pooling
DATABASES = {
    'default': {
        'CONN_MAX_AGE': 60,        # Connection lifetime (seconds)
        'OPTIONS': {
            'connect_timeout': 10,  # Connection timeout
        },
    }
}

For high-load deployments, consider PgBouncer:

pgbouncer:
  environment:
    - POOL_MODE=transaction
    - MAX_CLIENT_CONN=1000
    - DEFAULT_POOL_SIZE=20

πŸ“ Debug and Logging

Log Levels

LoggerDebug ModeProduction
rootINFOINFO
djangoConfigurable via DJANGO_LOG_LEVELINFO
skyspyDEBUGINFO
celeryINFOINFO
πŸ“‹ Logging Configuration
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'verbose': {
            'format': '{levelname} {asctime} {module} {process:d} {thread:d} {message}',
            'style': '{',
        },
        'simple': {
            'format': '{levelname} {message}',
            'style': '{',
        },
    },
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
            'formatter': 'simple',
        },
    },
    'loggers': {
        'django': {
            'level': os.environ.get('DJANGO_LOG_LEVEL', 'INFO'),
        },
        'skyspy': {
            'level': 'DEBUG' if DEBUG else 'INFO',
        },
        'celery': {
            'level': 'INFO',
        },
    },
}

RPi Logging (Reduced Verbosity)

# settings_rpi.py
LOGGING['root']['level'] = 'WARNING'
LOGGING['loggers']['skyspy']['level'] = 'INFO'
LOGGING['loggers']['django']['level'] = 'WARNING'

Debug Mode Behaviors

When DEBUG=True:

  • Django debug toolbar enabled
  • Detailed error pages
  • Auto-generated secret key (development only)
  • Default ALLOWED_HOSTS includes localhost
  • skyspy logger set to DEBUG level
  • Stack traces in API error responses

Viewing Logs

# Docker Compose logs
docker-compose logs -f api
docker-compose logs -f celery-worker
docker-compose logs -f celery-beat

# Filter by service
docker-compose logs -f api celery-worker

# Last 100 lines
docker-compose logs --tail=100 api

🚦 API Rate Limiting

User TypeRate Limit
Anonymous100 requests/minute
Authenticated1,000 requests/minute
βš™οΈ Rate Limiting Configuration
REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_CLASSES': [
        'rest_framework.throttling.AnonRateThrottle',
        'rest_framework.throttling.UserRateThrottle',
    ],
    'DEFAULT_THROTTLE_RATES': {
        'anon': '100/minute',
        'user': '1000/minute',
    }
}

βœ… Security Best Practices

⚠️

Warning Complete this checklist before deploying to production!

Production Checklist

  • Set unique DJANGO_SECRET_KEY
  • Set unique JWT_SECRET_KEY (different from Django secret)
  • Set DEBUG=False
  • Configure ALLOWED_HOSTS explicitly
  • Use AUTH_MODE=private or AUTH_MODE=hybrid
  • Change default superuser password
  • Configure CORS_ALLOWED_ORIGINS
  • Enable HTTPS (via reverse proxy)
  • Review and restrict API rate limits
  • Enable Sentry for error tracking
  • Secure Redis with password if exposed
  • Use strong PostgreSQL credentials

πŸ”‘ Generating Secure Keys

# Django Secret Key
python -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())"

# JWT Secret Key (use a different value)
python -c "import secrets; print(secrets.token_urlsafe(64))"

🐳 Docker Configuration

Docker Compose Profiles

ProfileDescriptionUsage
(default)Core services: api, postgres, redis, celerydocker-compose up -d
acarsInclude ACARS UDP listenerdocker-compose --profile acars up -d
devDevelopment with hot-reloaddocker-compose -f docker-compose.test.yaml --profile dev up
testRun test suitedocker-compose -f docker-compose.test.yaml --profile test up

Volume Mounts

VolumePathDescription
postgres_data/var/lib/postgresql/dataPostgreSQL database
redis_data/dataRedis persistence
photo_cache/data/photosCached aircraft photos
radio_data/data/radioAudio transmissions
opensky_data/data/openskyOpenSky database

Network Configuration

Default Docker network: skyspy-network

ServiceInternal PortDefault External Port
API8000$API_PORT (8000)
PostgreSQL5432Not exposed
Redis6379Not exposed
ACARS (UDP)5555$ACARS_PORT (5555)
VDL2 (UDP)5556$VDLM2_PORT (5556)

πŸ”§ Troubleshooting

🚨 Common Issues and Solutions

Secret Key Error in Production

ImproperlyConfigured: DJANGO_SECRET_KEY must be set in production

Solution: Set DJANGO_SECRET_KEY environment variable.


Database Connection Failed

could not connect to server: Connection refused

Solution: Ensure PostgreSQL container is healthy before starting API.


Redis Connection Failed

redis.exceptions.ConnectionError

Solution: Check REDIS_URL and ensure Redis container is running.


CORS Errors

Access-Control-Allow-Origin header missing

Solution: Add your frontend origin to CORS_ALLOWED_ORIGINS.


JWT Token Invalid

Token is invalid or expired

Solution: Ensure JWT_SECRET_KEY is consistent across all services.


πŸ“š Related Documentation

DocumentDescription
Installation GuideGetting started with SkysPy
API ReferenceREST API documentation
Socket.IO EventsReal-time event reference
Deployment GuideProduction deployment