From 500ddf59fe092df3fe95a773c79cfd9e07dc7b8c Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 5 Feb 2026 21:59:55 +0000 Subject: [PATCH] Add multi-arch build support and detailed antenna guide Multi-arch Docker builds: - build-multiarch.sh: Cross-compile amd64+arm64 on x64 and push to registry, so RPi5 can docker pull instead of building natively - docker-compose.yml: Add INTERCEPT_IMAGE env var to support pulling pre-built images from a registry instead of local build - README.md: Docker build section rewritten with multi-arch workflow, registry pull instructions, and build script options Weather satellite antenna guide (sidebar panel): - V-Dipole: ASCII diagram, 53.4cm element length, 120 degree angle, materials, orientation, connection instructions - Turnstile/Crossed Dipole: phasing coax length (37cm RG-58), reflector distance (52cm below), RHCP explanation - QFH Quadrifilar Helix: design overview, materials, height (46cm), hemispherical gain pattern - Placement & LNA: outdoor requirements, coax loss figures, LNA mounting position, Nooelec SAWbird+ recommendation, Bias-T - Quick reference table: wavelength, quarter-wave, elevation, duration, polarization, APT/LRPT bandwidth Also added Weather Satellites and ISS SSTV to README features list, SatDump to acknowledgments. https://claude.ai/code/session_01FjLTkyELaqh27U1wEXngFQ --- README.md | 152 ++++++++++------ build-multiarch.sh | 139 +++++++++++++++ docker-compose.yml | 9 +- .../partials/modes/weather-satellite.html | 162 +++++++++++++++--- 4 files changed, 377 insertions(+), 85 deletions(-) create mode 100755 build-multiarch.sh diff --git a/README.md b/README.md index c05dc49..b7904b4 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,8 @@ Support the developer of this open-source project - **Vessel Tracking** - AIS ship tracking with VHF DSC distress monitoring - **ACARS Messaging** - Aircraft datalink messages via acarsdec - **Listening Post** - Frequency scanner with audio monitoring +- **Weather Satellites** - NOAA APT and Meteor LRPT image decoding via SatDump +- **ISS SSTV** - Slow-scan TV image reception from the International Space Station - **Satellite Tracking** - Pass prediction using TLE data - **ADS-B History** - Persistent aircraft history with reporting dashboard (Postgres optional) - **WiFi Scanning** - Monitor mode reconnaissance via aircrack-ng @@ -55,67 +57,106 @@ cd intercept sudo -E venv/bin/python intercept.py ``` -### Docker (Alternative) +### Docker ```bash git clone https://github.com/smittix/intercept.git cd intercept -docker compose up -d +docker compose --profile basic up -d --build ``` -> **Note:** Docker requires privileged mode for USB SDR access. See `docker-compose.yml` for configuration options. - -### ADS-B History (Optional) - -The ADS-B history feature persists aircraft messages to Postgres for long-term analysis. - -```bash -# Start with ADS-B history and Postgres -docker compose --profile history up -d -``` - -Set the following environment variables (for example in a `.env` file): - -```bash -INTERCEPT_ADSB_HISTORY_ENABLED=true -INTERCEPT_ADSB_DB_HOST=adsb_db -INTERCEPT_ADSB_DB_PORT=5432 -INTERCEPT_ADSB_DB_NAME=intercept_adsb -INTERCEPT_ADSB_DB_USER=intercept -INTERCEPT_ADSB_DB_PASSWORD=intercept -``` - -### Other ADS-B Settings - -Set these as environment variables for either local installs or Docker: - -| Variable | Default | Description | -|----------|---------|-------------| -| `INTERCEPT_ADSB_AUTO_START` | `false` | Auto-start ADS-B tracking when the dashboard loads | -| `INTERCEPT_SHARED_OBSERVER_LOCATION` | `true` | Share observer location across ADS-B/AIS/SSTV/Satellite modules | - -**Local install example** - -```bash -INTERCEPT_ADSB_AUTO_START=true \ -INTERCEPT_SHARED_OBSERVER_LOCATION=false \ -python app.py -``` - -**Docker example (.env)** - -```bash -INTERCEPT_ADSB_AUTO_START=true -INTERCEPT_SHARED_OBSERVER_LOCATION=false -``` - -To store Postgres data on external storage, set `PGDATA_PATH` (defaults to `./pgdata`): - -```bash -PGDATA_PATH=/mnt/usbpi1/intercept/pgdata -``` - -Then open **/adsb/history** for the reporting dashboard. +> **Note:** Docker requires privileged mode for USB SDR access. SDR devices are passed through via `/dev/bus/usb`. + +#### Multi-Architecture Builds (amd64 + arm64) + +Cross-compile on an x64 machine and push to a registry. This is much faster than building natively on an RPi. + +```bash +# One-time setup on your x64 build machine +docker run --privileged --rm tonistiigi/binfmt --install all +docker buildx create --name intercept-builder --use --bootstrap + +# Build and push for both architectures +REGISTRY=ghcr.io/youruser ./build-multiarch.sh --push + +# On the RPi5, just pull and run +INTERCEPT_IMAGE=ghcr.io/youruser/intercept:latest docker compose --profile basic up -d +``` + +Build script options: + +| Flag | Description | +|------|-------------| +| `--push` | Push to container registry | +| `--load` | Load into local Docker (single platform only) | +| `--arm64-only` | Build arm64 only (for RPi deployment) | +| `--amd64-only` | Build amd64 only | + +Environment variables: `REGISTRY`, `IMAGE_NAME`, `IMAGE_TAG` + +#### Using a Pre-built Image + +If you've pushed to a registry, you can skip building entirely on the target machine: + +```bash +# Set in .env or export +INTERCEPT_IMAGE=ghcr.io/youruser/intercept:latest + +# Then just run +docker compose --profile basic up -d +``` + +### ADS-B History (Optional) + +The ADS-B history feature persists aircraft messages to Postgres for long-term analysis. + +```bash +# Start with ADS-B history and Postgres +docker compose --profile history up -d +``` + +Set the following environment variables (for example in a `.env` file): + +```bash +INTERCEPT_ADSB_HISTORY_ENABLED=true +INTERCEPT_ADSB_DB_HOST=adsb_db +INTERCEPT_ADSB_DB_PORT=5432 +INTERCEPT_ADSB_DB_NAME=intercept_adsb +INTERCEPT_ADSB_DB_USER=intercept +INTERCEPT_ADSB_DB_PASSWORD=intercept +``` + +### Other ADS-B Settings + +Set these as environment variables for either local installs or Docker: + +| Variable | Default | Description | +|----------|---------|-------------| +| `INTERCEPT_ADSB_AUTO_START` | `false` | Auto-start ADS-B tracking when the dashboard loads | +| `INTERCEPT_SHARED_OBSERVER_LOCATION` | `true` | Share observer location across ADS-B/AIS/SSTV/Satellite modules | + +**Local install example** + +```bash +INTERCEPT_ADSB_AUTO_START=true \ +INTERCEPT_SHARED_OBSERVER_LOCATION=false \ +python app.py +``` + +**Docker example (.env)** + +```bash +INTERCEPT_ADSB_AUTO_START=true +INTERCEPT_SHARED_OBSERVER_LOCATION=false +``` + +To store Postgres data on external storage, set `PGDATA_PATH` (defaults to `./pgdata`): + +```bash +PGDATA_PATH=/mnt/usbpi1/intercept/pgdata +``` + +Then open **/adsb/history** for the reporting dashboard. ### Open the Interface @@ -195,6 +236,7 @@ Created by **smittix** - [GitHub](https://github.com/smittix) [acarsdec](https://github.com/TLeconte/acarsdec) | [aircrack-ng](https://www.aircrack-ng.org/) | [Leaflet.js](https://leafletjs.com/) | +[SatDump](https://github.com/SatDump/SatDump) | [Celestrak](https://celestrak.org/) | [Priyom.org](https://priyom.org/) diff --git a/build-multiarch.sh b/build-multiarch.sh new file mode 100755 index 0000000..4798be8 --- /dev/null +++ b/build-multiarch.sh @@ -0,0 +1,139 @@ +#!/bin/bash +# INTERCEPT - Multi-architecture Docker image builder +# +# Builds for both linux/amd64 and linux/arm64 using Docker buildx. +# Run this on your x64 machine to cross-compile the arm64 image +# instead of building natively on the RPi5. +# +# Prerequisites (one-time setup): +# docker run --privileged --rm tonistiigi/binfmt --install all +# docker buildx create --name intercept-builder --use --bootstrap +# +# Usage: +# ./build-multiarch.sh # Build both platforms, load locally +# ./build-multiarch.sh --push # Build and push to registry +# ./build-multiarch.sh --arm64-only # Build arm64 only (for RPi) +# REGISTRY=ghcr.io/user ./build-multiarch.sh --push +# +# Environment variables: +# REGISTRY - Container registry (default: docker.io/library) +# IMAGE_NAME - Image name (default: intercept) +# IMAGE_TAG - Image tag (default: latest) + +set -euo pipefail + +# Configuration +REGISTRY="${REGISTRY:-}" +IMAGE_NAME="${IMAGE_NAME:-intercept}" +IMAGE_TAG="${IMAGE_TAG:-latest}" +BUILDER_NAME="intercept-builder" +PLATFORMS="linux/amd64,linux/arm64" + +# Parse arguments +PUSH=false +LOAD=false +ARM64_ONLY=false + +for arg in "$@"; do + case $arg in + --push) PUSH=true ;; + --load) LOAD=true ;; + --arm64-only) + ARM64_ONLY=true + PLATFORMS="linux/arm64" + ;; + --amd64-only) + PLATFORMS="linux/amd64" + ;; + --help|-h) + echo "Usage: $0 [--push] [--load] [--arm64-only] [--amd64-only]" + echo "" + echo "Options:" + echo " --push Push to container registry" + echo " --load Load into local Docker (single platform only)" + echo " --arm64-only Build arm64 only (for RPi5 deployment)" + echo " --amd64-only Build amd64 only" + echo "" + echo "Environment variables:" + echo " REGISTRY Container registry (e.g. ghcr.io/username)" + echo " IMAGE_NAME Image name (default: intercept)" + echo " IMAGE_TAG Image tag (default: latest)" + echo "" + echo "Examples:" + echo " $0 --push # Build both, push" + echo " REGISTRY=ghcr.io/myuser $0 --push # Push to GHCR" + echo " $0 --arm64-only --load # Build arm64, load locally" + echo " $0 --arm64-only --push && ssh rpi docker pull # Build + deploy to RPi" + exit 0 + ;; + *) + echo "Unknown option: $arg" + exit 1 + ;; + esac +done + +# Build full image reference +if [ -n "$REGISTRY" ]; then + FULL_IMAGE="${REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}" +else + FULL_IMAGE="${IMAGE_NAME}:${IMAGE_TAG}" +fi + +echo "============================================" +echo " INTERCEPT Multi-Architecture Builder" +echo "============================================" +echo " Image: ${FULL_IMAGE}" +echo " Platforms: ${PLATFORMS}" +echo " Push: ${PUSH}" +echo "============================================" +echo "" + +# Check if buildx builder exists, create if not +if ! docker buildx inspect "$BUILDER_NAME" >/dev/null 2>&1; then + echo "Creating buildx builder: ${BUILDER_NAME}" + docker buildx create --name "$BUILDER_NAME" --use --bootstrap + + # Check for QEMU support + if ! docker run --rm --privileged tonistiigi/binfmt --install all >/dev/null 2>&1; then + echo "WARNING: QEMU binfmt setup may have failed." + echo "Run: docker run --privileged --rm tonistiigi/binfmt --install all" + fi +else + docker buildx use "$BUILDER_NAME" +fi + +# Build command +BUILD_CMD="docker buildx build --platform ${PLATFORMS} --tag ${FULL_IMAGE}" + +if [ "$PUSH" = true ]; then + BUILD_CMD="${BUILD_CMD} --push" + echo "Will push to: ${FULL_IMAGE}" +elif [ "$LOAD" = true ]; then + # --load only works with single platform + if echo "$PLATFORMS" | grep -q ","; then + echo "ERROR: --load only works with a single platform." + echo "Use --arm64-only or --amd64-only with --load." + exit 1 + fi + BUILD_CMD="${BUILD_CMD} --load" + echo "Will load into local Docker" +fi + +echo "" +echo "Building..." +echo "Command: ${BUILD_CMD} ." +echo "" + +$BUILD_CMD . + +echo "" +echo "============================================" +echo " Build complete!" +if [ "$PUSH" = true ]; then + echo " Image pushed to: ${FULL_IMAGE}" + echo "" + echo " Pull on RPi5:" + echo " docker pull ${FULL_IMAGE}" +fi +echo "============================================" diff --git a/docker-compose.yml b/docker-compose.yml index 4039f15..be409e8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,14 +1,18 @@ # INTERCEPT - Signal Intelligence Platform # Docker Compose configuration for easy deployment # -# Basic usage: -# docker compose --profile basic up -d +# Basic usage (build locally): +# docker compose --profile basic up -d --build +# +# Basic usage (pre-built image from registry): +# INTERCEPT_IMAGE=ghcr.io/user/intercept:latest docker compose --profile basic up -d # # With ADS-B history (Postgres): # docker compose --profile history up -d services: intercept: + image: ${INTERCEPT_IMAGE:-} build: . container_name: intercept profiles: @@ -54,6 +58,7 @@ services: # ADS-B history with Postgres persistence # Enable with: docker compose --profile history up -d intercept-history: + image: ${INTERCEPT_IMAGE:-} build: . container_name: intercept-history profiles: diff --git a/templates/partials/modes/weather-satellite.html b/templates/partials/modes/weather-satellite.html index 0e557f1..04cf11b 100644 --- a/templates/partials/modes/weather-satellite.html +++ b/templates/partials/modes/weather-satellite.html @@ -31,39 +31,145 @@ +
-

Antenna Guide (137 MHz)

-
-

Weather satellites transmit at ~137 MHz. Your stock SDR antenna likely won't work well at this frequency.

+

Antenna Guide

+
-
- V-Dipole (Easiest Build) -
    -
  • Two elements, ~53.4 cm each (quarter wavelength)
  • -
  • Spread at 120 angle, laid flat or tilted
  • -
  • Connect to SDR via coax with a BNC/SMA adapter
  • -
  • Cost: ~$5 in wire
  • +

    + 137 MHz band — your stock SDR antenna will NOT work. +

    +

    + Weather satellites transmit at 137.1–137.9 MHz. The quarter-wave + at this frequency is ~53 cm, + far longer than the small telescopic antenna shipped with most SDRs + (tuned for ~1 GHz). You need a purpose-built antenna. +

    + + +
    + V-Dipole (Easiest — ~$5) + +
    coax to SDR + | + ===+=== feed point + / \ + / 120 \ + / \ +/ deg \ +53.4cm 53.4cm
    + +
      +
    • Element length: 53.4 cm each (quarter wavelength at 137 MHz)
    • +
    • Angle: 120° between elements (not 180°)
    • +
    • Material: Any stiff wire, coat hanger, or copper rod
    • +
    • Orientation: Lay flat or tilt 30° toward expected pass direction
    • +
    • Polarization: The 120° angle gives partial RHCP match to satellite signal
    • +
    • Connection: Solder elements to coax center + shield, connect to SDR via SMA
    • +
    +

    + Best starter antenna. Good enough for clear NOAA images with a direct overhead pass. +

    +
    + + +
    + Turnstile / Crossed Dipole (~$10-15) + +
    53.4cm + <---------> + ====+==== dipole 1 + | + ====+==== dipole 2 + <---------> + 90 deg rotated + + reflector below
    + +
      +
    • Elements: Two crossed dipoles, each 53.4 cm per side (4 elements total)
    • +
    • Angle: 90° between the two dipole pairs
    • +
    • Phasing: Feed dipole 2 with a 90° delay (quarter-wave coax section ~37 cm of RG-58)
    • +
    • Reflector: Place ~52 cm below elements (ground plane or wire grid)
    • +
    • Polarization: Circular (RHCP) — matches satellite transmission
    • +
    +

    + Better than V-dipole. The reflector rejects ground noise and the RHCP phasing matches the satellite signal. +

    +
    + + +
    + QFH — Quadrifilar Helix (Best — ~$20-30) + +
    ___ + / \ two helix loops + | | | twisted 90 deg + | | | around a mast + \___/ + | + coax
    + +
      +
    • Design: Two bifilar helical loops, offset 90°
    • +
    • Material: Copper pipe (10mm), copper wire, or coax outer shield
    • +
    • Total height: ~46 cm (for 137 MHz)
    • +
    • Loop dimensions: Use a QFH calculator for exact bending measurements
    • +
    • Polarization: True RHCP omnidirectional — ideal for overhead satellite passes
    • +
    • Gain pattern: Hemispherical upward coverage, rejects ground interference
    • +
    +

    + Gold standard for weather satellite reception. No tracking needed — covers the whole sky. +

    +
    + + +
    + Placement & LNA +
      +
    • Location: OUTDOORS with clear sky view is critical. Roof/balcony/open field.
    • +
    • Height: Higher is better but not critical — clear horizon line matters more
    • +
    • Antenna up: Point the antenna straight UP (zenith) for best overhead coverage
    • +
    • Avoid: Metal roofs, power lines, buildings blocking the sky
    • +
    • Coax length: Keep short (<10m). Signal loss at 137 MHz is ~3 dB per 10m of RG-58
    • +
    • LNA: Mount at the antenna feed point, NOT at the SDR end. + Recommended: Nooelec SAWbird+ NOAA (137 MHz filtered LNA, ~$30)
    • +
    • Bias-T: Enable the Bias-T checkbox above if your LNA is powered via the coax from the SDR
    -
    - QFH Antenna (Best) -
      -
    • Quadrifilar helix - omnidirectional RHCP
    • -
    • Best for overhead passes, rejects ground noise
    • -
    • Build from copper pipe or coax
    • -
    • Cost: ~$20-30 in materials
    • -
    -
    - -
    - Tips -
      -
    • Outdoors with clear sky view is critical
    • -
    • LNA (e.g. Nooelec SAWbird) helps a lot
    • -
    • Enable Bias-T if using a powered LNA
    • -
    • Passes >30 elevation give best images
    • -
    + +
    + Quick Reference + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Wavelength (137 MHz)218.8 cm
    Quarter wave (element length)53.4 cm
    Best pass elevation> 30°
    Typical pass duration10-15 min
    PolarizationRHCP
    NOAA (APT) bandwidth~40 kHz
    Meteor (LRPT) bandwidth~140 kHz