# Styrene Deployment Modes

Styrene is self-contained and can run in multiple contexts without external dependencies.

## Core Principle

**Every Styrene instance is a complete mesh node**. It embeds Reticulum and creates appropriate interfaces based on context.

## Deployment Modes

### 1. Standalone/Mobile (Default)

**Use case**: Laptop, tablet, portable device
**Transport**: Local only (AutoInterface)
**Depends on**: Nothing

```yaml
# ~/.config/styrene/config.yaml (or defaults)
reticulum:
  mode: standalone

interfaces:
  auto: true      # UDP broadcast for local discovery
  server: false   # Don't accept external connections
  peers: []       # Don't connect to external hubs
```

**What happens**:
- Styrene starts its own RNS instance
- Creates AutoInterface for local network/LoRa
- Discovers nearby devices via announces
- Self-sufficient mesh node

**Commands**:
```bash
styrene                    # Runs in standalone mode
styrene --mode standalone  # Explicit
```

### 2. Hub Mode

**Use case**: Fixed deployment acting as transport node
**Transport**: Accepts connections (TCPServerInterface)
**Depends on**: Nothing (but others can depend on it)

```yaml
reticulum:
  mode: hub

interfaces:
  auto: true
  server:
    enabled: true
    port: 4242
  peers: []       # Or peer with other hubs
```

**What happens**:
- Runs as standalone node
- Also accepts TCP connections from other devices
- Acts as transport node (routes packets)
- Others can connect to this node

**Commands**:
```bash
styrene --mode hub
styrene --mode hub --port 4242
```

**Systemd service** for permanent deployment:
```ini
[Unit]
Description=Styrene Hub
After=network.target

[Service]
Type=simple
User=styrene
ExecStart=/usr/local/bin/styrene --mode hub --headless
Restart=always

[Install]
WantedBy=multi-user.target
```

### 3. Peer Mode

**Use case**: Connect to specific hubs while remaining independent
**Transport**: Local + remote peers
**Depends on**: Optional peering (but still works if peers offline)

```yaml
reticulum:
  mode: peer

interfaces:
  auto: true
  server: false
  peers:
    - host: home.vanderlyn.house
      port: 4242
    - host: dublin.connect.reticulum.network
      port: 4965
```

**What happens**:
- Runs standalone functionality
- Adds TCP client connections to specified hubs
- Discovers devices locally AND through peers
- Falls back to local-only if peers unreachable

**Commands**:
```bash
styrene --mode peer --peer home.vanderlyn.house:4242
styrene --mode peer --config custom-peers.yaml
```

### 4. Headless Mode

**Use case**: Edge device, server, no TUI needed
**Transport**: Any of the above, without TUI
**Depends on**: Same as chosen mode

```yaml
reticulum:
  mode: hub  # or standalone, peer

headless: true
api:
  enabled: true
  port: 8000
```

**What happens**:
- Runs Styrene service without TUI
- Provides HTTP API for remote management
- Can be controlled by TUI running elsewhere
- Announces as Styrene node

**Commands**:
```bash
styrene --headless                      # Standalone headless
styrene --headless --mode hub           # Hub without TUI
styrene --headless --api-port 8000      # With API
```

## Configuration Hierarchy

```
1. CLI flags (highest priority)
2. Environment variables
3. Config file (~/.config/styrene/config.yaml)
4. Defaults (lowest priority)
```

### CLI Flags
```bash
--mode [standalone|hub|peer]
--headless
--port <port>               # TCPServer port
--peer <host:port>          # Add peer (repeatable)
--api-port <port>           # HTTP API port
--config <path>             # Custom config file
```

### Environment Variables
```bash
STYRENE_MODE=hub
STYRENE_HEADLESS=true
STYRENE_PORT=4242
STYRENE_PEERS=home.vanderlyn.house:4242,dublin.connect.reticulum.network:4965
```

### Config File
```yaml
# ~/.config/styrene/config.yaml

reticulum:
  mode: standalone  # standalone, hub, peer
  enable_transport: auto  # auto (based on mode), true, false

interfaces:
  auto: true  # AutoInterface (local discovery)

  server:
    enabled: false  # TCPServerInterface
    listen_ip: 0.0.0.0
    port: 4242

  peers:  # TCPClientInterface (multiple)
    - host: home.vanderlyn.house
      port: 4242
      name: "Home Hub"

operator:
  identity_path: ~/.config/styrene/operator.key
  announce_interval: 300  # seconds

api:
  enabled: false
  host: 0.0.0.0
  port: 8000

headless: false
```

## Use Cases

### Personal Laptop
```bash
styrene  # Default standalone mode
```
- Discovers local devices
- Portable
- No external dependencies

### Edge Device (Raspberry Pi)
```bash
styrene --headless --mode hub
```
- Runs as systemd service
- Accepts connections from other devices
- No TUI overhead

### Mobile Device (Tablet with LoRa)
```bash
styrene --mode standalone
```
- AutoInterface discovers via LoRa
- Self-sufficient in the field
- No internet needed

### Home Server (Fixed Hub)
```bash
styrene --headless --mode hub --peer dublin.connect.reticulum.network:4965
```
- Acts as local transport node
- Peers with global Reticulum
- API for remote management

### Remote Management
```bash
# On server (brutus)
styrene --headless --mode hub --api-port 8000

# On laptop
styrene --remote https://styrene.vanderlyn.house
```
- TUI connects to remote API
- Manages server's mesh view
- No local RNS needed in TUI

## Brutus K8s Deployment (Headless Hub)

For the cluster deployment, use **headless hub mode**:

```yaml
# Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: styrene-node
  namespace: styrene
spec:
  replicas: 1
  template:
    spec:
      containers:
      - name: styrene
        image: ghcr.io/styrene-lab/styrene:latest
        args:
        - "--headless"
        - "--mode"
        - "hub"
        - "--api-port"
        - "8000"
        - "--port"
        - "4242"
        env:
        - name: STYRENE_MODE
          value: "hub"
        ports:
        - containerPort: 8000
          name: api
        - containerPort: 4242
          name: rns-tcp
---
# Services
apiVersion: v1
kind: Service
metadata:
  name: styrene-api
  namespace: styrene
spec:
  selector:
    app: styrene-node
  ports:
  - port: 8000
    name: api
---
apiVersion: v1
kind: Service
metadata:
  name: styrene-rns
  namespace: styrene
spec:
  type: LoadBalancer
  selector:
    app: styrene-node
  ports:
  - port: 4242
    name: rns-tcp
```

**Key points**:
- Runs Styrene in hub mode (transport enabled)
- Exposes API for remote TUI access
- Exposes RNS port for device connections
- Self-contained, doesn't need reticulum-hub

## Relationship to Reticulum Hub

The existing `reticulum-hub` (rnsd + LXMF + NomadNet) remains independent:

```
Reticulum Hub (brutus)         Styrene Hub (brutus or elsewhere)
├── rnsd (transport)           ├── Styrene service
├── LXMF propagation           ├── Embedded RNS (transport)
└── NomadNet (BBS)             ├── Device discovery
                               └── HTTP API

        Both are independent transport nodes
        They can peer with each other (optional)
        Styrene focuses on device management
        Reticulum hub focuses on community services
```

**Optional peering**:
```yaml
# styrene config
interfaces:
  peers:
    - host: reticulum-hub.reticulum.svc.cluster.local
      port: 4242
      name: "Community Hub"
```

This allows Styrene devices to reach devices connected to the community hub.

## Summary

| Mode | Transport | Accepts Connections | Peers | Use Case |
|------|-----------|---------------------|-------|----------|
| **standalone** | Local only | No | No | Laptop, mobile, field use |
| **hub** | Local + TCP server | Yes | Optional | Fixed installation, edge device |
| **peer** | Local + TCP client | No | Yes | Connect to specific hubs |
| **headless** | Any of above | Depends | Depends | Server, no TUI |

**Philosophy**: Styrene is self-sufficient. External infrastructure is optional, not required.
