mission-control/README.md
2026-01-28 20:11:44 +01:00

2.7 KiB

🛰️ Mission Control: ISS Tracker

A production-grade, full-stack dashboard for tracking the International Space Station in real-time. This project combines orbital mechanics (SGP4 propagation), a background worker architecture, and a resilient Next.js frontend.

🚀 The Stack

  • Frontend: Next.js 15 (App Router) + Tailwind CSS + Lucide Icons
  • Backend/Worker: Node.js + satellite.js (Orbital Physics)
  • Database: SQLite (better-sqlite3)
  • Infrastructure: Docker & Docker Compose
  • CI/CD: Woodpecker CI
  • Deployment: Hetzner VPS + Caddy (Reverse Proxy)

🏗️ Architecture

The system is split into two distinct services that share a persistent SQLite volume:

  1. The Worker (iss-worker):
    • Fetches Two-Line Element (TLE) data from CelesTrak.
    • Performs SGP4 propagation to calculate ISS coordinates.
    • Determines upcoming "Pass Windows" (AOS to LOS) relative to a fixed ground station.
    • Updates the shared database with the next two valid passes.
  2. The Web App (mc-web):
    • Server-side queries the database for the next future pass.
    • Calculates real-time "T-Minus" countdowns.
    • Triggers a "Live" state when the ISS is above the horizon.
    • Uses router.refresh() with a useRef lock to transition between passes without page reloads.

🛠️ Key Technical Solutions

Orbital Propagation

Instead of relying on 3rd-party APIs for pass predictions, this project runs its own physics engine. Using satellite.js, it calculates the elevation of the ISS relative to the observer's latitude and longitude.

Self-Healing Database

The database includes an automatic migration layer in lib/db.ts. On startup, the application inspects the SQLite schema and applies necessary ALTER TABLE commands, ensuring seamless updates during CI/CD deployments without manual intervention.

Resilient Synchronization

To prevent infinite refresh loops in the Next.js frontend, the EventCard component implements a "Refresh & Quiet" logic. It uses a useRef to ensure that only one server-side data sync is requested per orbital event.

📦 Deployment

Docker Multi-Platform Build

The images are explicitly built for the linux/amd64 architecture to ensure compatibility with Node.js native modules (like better-sqlite3) on the Hetzner VPS.

docker buildx build --platform linux/amd64 -t mission-control-web .

Woodpecker CI

The pipeline is automated via .woodpecker.yaml, handling the build, registry push, and remote deployment via Docker Compose.

🚦 Getting Started

  • Clone the repo
  • Install dependencies: npm install
  • Run the worker: npx tsx scripts/update-space.ts
  • Start the dashboard: npm run dev

Ground Station Coordinates: 55.6761° N, 12.5683° E