A Phoenix web application with NATS integration, Protocol Buffers, and H3 hexagonal geospatial indexing designed to run on air-gapped networks.
- NATS Integration: Real-time message handling with Protocol Buffers
- H3 Geospatial Indexing: Uber's hexagonal hierarchical spatial index
- Offline Maps: Local tile server for air-gapped deployment
- Phoenix LiveView: Real-time UI updates without additional dependencies
- Tailwind CSS: Modern utility-first CSS framework
- Minimal Dependencies: Optimized for air-gapped environments
- Elixir 1.14+
- Erlang/OTP 25+
- Node.js 18+ (for assets)
- NATS Server 2.10+
- Protocol Buffer Compiler (protoc) 3.21+
- Install dependencies:
mix deps.get- Setup assets:
mix assets.setup- Generate Proto modules:
protoc --elixir_out=./lib/airgap_app/proto priv/proto/messages.proto- Download map tiles for offline use:
# Run the tile download script
./scripts/download_tiles.sh- Download Leaflet for offline use:
cd assets/vendor
wget https://unpkg.com/[email protected]/dist/leaflet.js
wget https://unpkg.com/[email protected]/dist/leaflet.css
wget -r -np -k -E https://unpkg.com/[email protected]/dist/images/Set environment variables:
export NATS_HOST=localhost
export NATS_PORT=4222- Build release:
MIX_ENV=prod mix do compile, assets.deploy, release- Package for transfer:
tar -czf airgap_app.tar.gz _build/prod/rel/airgap_app priv/static/tiles- Deploy to air-gapped system:
# On target system
tar -xzf airgap_app.tar.gz
./_build/prod/rel/airgap_app/bin/airgap_app start- Start NATS server:
nats-server- Start Phoenix server:
mix phx.serverVisit localhost:4000
mix testairgap_app/
├── lib/
│ ├── airgap_app/
│ │ ├── application.ex # Main application supervisor
│ │ ├── nats_client.ex # NATS client for Proto messages
│ │ ├── h3_service.ex # H3 geospatial operations
│ │ └── proto/ # Generated Proto modules
│ └── airgap_app_web/
│ ├── live/
│ │ └── map_live.ex # Main map LiveView
│ ├── controllers/
│ │ └── tile_controller.ex # Serve local map tiles
│ └── components/ # Phoenix components
├── assets/
│ ├── js/
│ │ └── app.js # Main JavaScript entry
│ ├── css/
│ │ └── app.css # Tailwind CSS entry
│ └── vendor/
│ └── leaflet/ # Offline Leaflet library
├── priv/
│ ├── proto/
│ │ └── messages.proto # Protocol Buffer definitions
│ └── static/
│ └── tiles/ # Offline map tiles
└── config/
├── config.exs # Base configuration
├── dev.exs # Development config
├── prod.exs # Production config
└── runtime.exs # Runtime configuration
Use the included test script to send Proto messages:
# In IEx console
AirgapApp.TestHelper.send_location_update(%{
id: "vehicle_001",
latitude: 40.7128,
longitude: -74.0060,
timestamp: System.system_time(:millisecond)
})MIT