- generally file cleanup and organize. - remove incorrect prompt text.

This commit is contained in:
jasonwitty 2025-11-28 10:23:53 -08:00
parent 6e48c095ab
commit a81568f907
23 changed files with 0 additions and 6020 deletions

View File

@ -1,390 +0,0 @@
# Catppuccin Frappe Styling Guide
## Overview
The socktop website now uses the beautiful **Catppuccin Frappe** color scheme throughout. This guide documents all the colors and styling conventions used.
## Color Palette
### Base Colors
```css
--ctp-base: #303446; /* Main background */
--ctp-mantle: #292c3c; /* Slightly darker background */
--ctp-crust: #232634; /* Darkest background */
```
### Surface Colors
```css
--ctp-surface0: #414559; /* UI elements background */
--ctp-surface1: #51576d; /* Slightly lighter UI elements */
--ctp-surface2: #626880; /* Even lighter UI elements */
```
### Overlay Colors
```css
--ctp-overlay0: #737994; /* Disabled text */
--ctp-overlay1: #838ba7; /* Comments, secondary text */
--ctp-overlay2: #949cbb; /* Tertiary text */
```
### Text Colors
```css
--ctp-text: #c6d0f5; /* Primary text */
--ctp-subtext1: #b5bfe2; /* Secondary text */
--ctp-subtext0: #a5adce; /* Tertiary text */
```
### Accent Colors
```css
--ctp-lavender: #babbf1; /* Links, highlights */
--ctp-blue: #8caaee; /* Information, primary actions */
--ctp-sapphire: #85c1dc; /* Special highlights */
--ctp-sky: #99d1db; /* Sky blue accent */
--ctp-teal: #81c8be; /* Teal accent */
--ctp-green: #a6d189; /* Success, positive */
--ctp-yellow: #e5c890; /* Warnings, attention */
--ctp-peach: #ef9f76; /* Rust/crates.io theme */
--ctp-maroon: #ea999c; /* Darker red variant */
--ctp-red: #e78284; /* Errors, close button */
--ctp-mauve: #ca9ee6; /* Primary brand color */
--ctp-pink: #f4b8e4; /* Pink accent */
--ctp-flamingo: #eebebe; /* Lighter pink */
--ctp-rosewater: #f2d5cf; /* Lightest pink, cursor */
```
## Component Styling
### Hero Title
- **Gradient**: Mauve to Blue (`#ca9ee6` → `#8caaee`)
- **Font**: 3rem, weight 800
- **Effect**: Text gradient with subtle glow
- **Usage**: Main "socktop" heading
### Tagline
- **Color**: `var(--ctp-subtext1)` (#b5bfe2)
- **Font**: 1.25rem, weight 400
- **Usage**: "A TUI-first remote system monitor."
### Link Buttons
#### Base Style
```css
background: rgba(65, 69, 89, 0.6);
border: 1px solid rgba(186, 187, 241, 0.2);
border-radius: 12px;
color: var(--ctp-text);
```
#### GitHub Button
- **Border hover**: `var(--ctp-lavender)` (#babbf1)
- **Shadow hover**: `rgba(186, 187, 241, 0.25)`
- **Icon**: Font Awesome `fab fa-github`
#### Crate Buttons (TUI & Agent)
- **Border hover**: `var(--ctp-peach)` (#ef9f76)
- **Shadow hover**: `rgba(239, 159, 118, 0.25)`
- **Icon**: Font Awesome `fas fa-cube`
- **Theme**: Matches Rust/crates.io orange
#### APT Repository Button
- **Border hover**: `var(--ctp-green)` (#a6d189)
- **Shadow hover**: `rgba(166, 209, 137, 0.25)`
- **Icon**: Font Awesome `fas fa-box`
### Terminal Window
#### Window Frame
```css
background: transparent;
backdrop-filter: blur(20px);
border: 1px solid rgba(186, 187, 241, 0.15);
border-radius: 12px;
box-shadow:
0 30px 60px rgba(0, 0, 0, 0.4),
0 12px 24px rgba(0, 0, 0, 0.3),
inset 0 1px 0 rgba(186, 187, 241, 0.1);
```
#### Title Bar
```css
background: rgba(41, 44, 60, 0.8);
border-bottom: 1px solid rgba(0, 0, 0, 0.3);
height: 44px;
```
#### Traffic Light Buttons
- **Close**: `var(--ctp-red)` (#e78284)
- **Minimize**: `var(--ctp-yellow)` (#e5c890)
- **Maximize**: `var(--ctp-green)` (#a6d189)
#### Terminal Title
```css
color: var(--ctp-subtext1);
font-size: 13px;
font-weight: 500;
```
### Terminal Theme (xterm.js)
```javascript
theme: {
background: "rgba(48, 52, 70, 0.75)",
foreground: "#c6d0f5",
cursor: "#f2d5cf",
cursorAccent: "#303446",
selectionBackground: "rgba(202, 158, 230, 0.3)",
// ANSI colors
black: "#51576d",
red: "#e78284",
green: "#a6d189",
yellow: "#e5c890",
blue: "#8caaee",
magenta: "#f4b8e4",
cyan: "#81c8be",
white: "#b5bfe2",
// Bright ANSI colors
brightBlack: "#626880",
brightRed: "#e78284",
brightGreen: "#a6d189",
brightYellow: "#e5c890",
brightBlue: "#8caaee",
brightMagenta: "#f4b8e4",
brightCyan: "#81c8be",
brightWhite: "#a5adce",
}
```
### Header & Footer
#### Header
```css
background: rgba(48, 52, 70, 0.3);
backdrop-filter: blur(10px);
border-bottom: 1px solid rgba(186, 187, 241, 0.1);
```
#### Footer
```css
background: rgba(35, 38, 52, 0.3);
backdrop-filter: blur(10px);
border-top: 1px solid rgba(186, 187, 241, 0.1);
color: var(--ctp-overlay1);
```
#### Footer Links
- **Normal**: `var(--ctp-mauve)` (#ca9ee6)
- **Hover**: `var(--ctp-lavender)` (#babbf1)
## Typography
### Font Families
#### Primary (UI)
```css
font-family: "Inter", "SF Pro Display", -apple-system, BlinkMacSystemFont,
"Segoe UI", Roboto, sans-serif;
```
#### Terminal (Monospace)
```css
font-family: "JetBrains Mono", "Fira Code", "Cascadia Code",
Consolas, monospace;
```
### Font Sizes
- **Hero Title**: 3rem (48px)
- **Tagline**: 1.25rem (20px)
- **Link Buttons**: 0.95rem (15.2px)
- **Terminal Title**: 13px
- **Terminal Content**: 14px
- **Footer**: 0.875rem (14px)
### Font Weights
- **Hero Title**: 800 (Extra Bold)
- **Tagline**: 400 (Regular)
- **Link Buttons**: 500 (Medium)
- **Terminal Title**: 500 (Medium)
## Effects & Transitions
### Blur Effects
- **Window Frame**: `blur(20px)`
- **Header/Footer**: `blur(10px)`
- **Title Bar**: `blur(10px)`
### Shadows
#### Window Shadow
```css
box-shadow:
0 30px 60px rgba(0, 0, 0, 0.4),
0 12px 24px rgba(0, 0, 0, 0.3),
inset 0 1px 0 rgba(186, 187, 241, 0.1);
```
#### Button Shadow
```css
/* Default */
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
/* Hover */
box-shadow: 0 8px 24px rgba(202, 158, 230, 0.2);
```
### Transitions
```css
/* Buttons */
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
/* Traffic Lights */
transition: all 0.2s ease;
/* Links */
transition: color 0.2s;
```
### Hover Effects
#### Button Hover
```css
transform: translateY(-2px);
/* Plus color-specific shadow and border */
```
#### Traffic Light Hover
- Show inner symbol (×, -, or +)
- Increase brightness slightly
## Transparency & Opacity
### Background Opacities
- **Terminal Background**: `rgba(48, 52, 70, 0.75)` - 75% opaque
- **Title Bar**: `rgba(41, 44, 60, 0.8)` - 80% opaque
- **Header**: `rgba(48, 52, 70, 0.3)` - 30% opaque
- **Footer**: `rgba(35, 38, 52, 0.3)` - 30% opaque
- **Link Buttons**: `rgba(65, 69, 89, 0.6)` - 60% opaque
### Selection Colors
```css
::selection {
background: var(--ctp-mauve);
color: var(--ctp-base);
}
```
## Responsive Design
### Mobile (≤480px)
- Logo: 150px max-width
- Hero title: 2rem
- Terminal buttons: 10px diameter
- Title bar: 40px height
### Tablet (≤768px)
- Hero title: 2rem
- Tagline: 1rem
- Link buttons: Full width stack
- Terminal: 8px border radius
## Icon Usage
### Font Awesome Icons
- **GitHub**: `fab fa-github`
- **Crates.io**: `fas fa-cube`
- **APT**: `fas fa-box`
- **Size**: 1.2rem within buttons
## Accessibility
### Contrast Ratios
All text meets WCAG AA standards:
- Primary text on base: High contrast
- Secondary text on base: Medium-high contrast
- Links have distinct colors and hover states
### Focus States
All interactive elements have visible focus states (inherit from Catppuccin theme).
### Screen Readers
- Semantic HTML structure
- ARIA labels on terminal
- Alt text on images
- Descriptive link text
## Customization Tips
### Changing Primary Brand Color
Replace `--ctp-mauve` throughout with another accent:
```css
/* Example: Use blue as primary */
.hero-title {
background: linear-gradient(135deg, var(--ctp-blue) 0%, var(--ctp-sapphire) 100%);
}
.link-button:hover {
border-color: var(--ctp-blue);
}
```
### Adjusting Transparency
More opaque terminal:
```css
theme: {
background: "rgba(48, 52, 70, 0.9)", /* Change from 0.75 */
}
```
Less blur:
```css
backdrop-filter: blur(10px); /* Change from 20px */
```
### Custom Button Colors
Add a new button style:
```css
.link-button.custom {
border-color: rgba(133, 193, 220, 0.3);
}
.link-button.custom:hover {
border-color: var(--ctp-sapphire);
box-shadow: 0 8px 24px rgba(133, 193, 220, 0.25);
}
```
## Resources
- **Catppuccin Official**: https://github.com/catppuccin/catppuccin
- **Catppuccin Frappe**: https://github.com/catppuccin/catppuccin#-frappe
- **Color Palette**: https://catppuccin.com/palette
- **Port Guide**: https://github.com/catppuccin/catppuccin/blob/main/docs/port-creation.md
## Color Reference Chart
```
Base Colors: Surface Colors: Overlay Colors:
#303446 base █ #414559 s0 █ #737994 o0
#292c3c mantle █ #51576d s1 █ #838ba7 o1
#232634 crust █ #626880 s2 █ #949cbb o2
Text Colors: Accent Colors (Part 1):
#c6d0f5 text █ #babbf1 lavender █ #8caaee blue
#b5bfe2 sub1 █ #85c1dc sapphire █ #99d1db sky
#a5adce sub0 █ #81c8be teal █ #a6d189 green
Accent Colors (Part 2):
#e5c890 yellow █ #ef9f76 peach █ #ea999c maroon
#e78284 red █ #ca9ee6 mauve █ #f4b8e4 pink
#eebebe flamingo █ #f2d5cf rosewater
```
---
**Theme**: Catppuccin Frappe
**Designed for**: socktop web demo
**Optimized for**: Dark backgrounds with colorful accents

View File

@ -1,316 +0,0 @@
# Conversation Summary: Idle Timeout Implementation
## 1. Overview
This conversation focused on addressing a critical resource management issue in the webterm project: the accumulation of orphaned terminal processes (a "grey goo" problem) when users refresh the page or abandon sessions. The solution implements an **idle timeout mechanism** that automatically cleans up inactive PTY sessions after a configurable period.
### Context
- **Project**: socktop web terminal - a Rust-based web terminal using Actix actors and xterm.js
- **Problem**: Each page refresh spawns a new `socktop-agent` process, but old processes weren't being cleaned up
- **Risk**: Over time, abandoned processes accumulate, consuming resources indefinitely
- **Solution**: Implement idle timeout tracking and automatic cleanup in the Terminal actor
---
## 2. Key Facts and Discoveries
### Architecture Understanding
- **Backend**: Rust with Actix framework (actor-based concurrency)
- **Frontend**: xterm.js 5.x with custom Terminado protocol addon
- **Process Model**: One WebSocket + one Terminal actor + one PTY/child process per session
- **Actor Lifecycle**: WebSocket and Terminal are separate actors that communicate via message passing
### The Problem in Detail
1. **Page Refresh Scenario**:
- User loads page → WebSocket created → Terminal created → PTY spawned
- User refreshes → NEW WebSocket + Terminal + PTY created
- OLD Terminal/PTY continues running because nothing explicitly stops it
- Result: Multiple `socktop-agent` processes accumulate
2. **Why It Happens**:
- WebSocket disconnection stops the WebSocket actor
- Terminal actor holds a reference to WebSocket but isn't automatically stopped
- No mechanism existed to detect idle sessions or clean them up
- PTY processes become orphaned
3. **Existing Cleanup**:
- Terminal's `stopping()` method kills the child process when stopping
- WebSocket has heartbeat/timeout for detecting dead connections (10 seconds)
- But no idle activity timeout existed
### Technical Constraints
- Actix actors don't have direct external stop() methods
- Actors must stop themselves via `ctx.stop()` from within
- Cannot send arbitrary stop signals between actors without defining message types
- Need to balance aggressive cleanup vs. allowing legitimate long-running commands
---
## 3. Implementation Details
### What Was Added
#### 1. New Constants (src/lib.rs)
```rust
const IDLE_TIMEOUT: Duration = Duration::from_secs(300); // 5 minutes
const IDLE_CHECK_INTERVAL: Duration = Duration::from_secs(30); // Check every 30 seconds
```
#### 2. Terminal Struct Fields
```rust
pub struct Terminal {
// ... existing fields
last_activity: Instant, // Tracks last user interaction
idle_timeout: Duration, // Configured timeout duration
}
```
#### 3. Initialization
- `last_activity` initialized to `Instant::now()` in `Terminal::new()`
- `idle_timeout` set to `IDLE_TIMEOUT` constant
#### 4. Periodic Idle Checker
Added to `Terminal::started()`:
- Runs every 30 seconds via `ctx.run_interval()`
- Calculates idle duration: `now - last_activity`
- If idle ≥ timeout, calls `ctx.stop()` to terminate session
- Logs timeout events for monitoring
#### 5. Activity Tracking Updates
Updated in three message handlers:
- **`Handler<event::IO>`**: Resets timer on any I/O from WebSocket
- **`Handler<TerminadoMessage::Stdin>`**: Resets timer on user input
- **`Handler<TerminadoMessage::Resize>`**: Resets timer on window resize
### What Activity Counts
**Does Reset Timer**:
- Keyboard input (Stdin)
- Terminal resize events
- Direct I/O messages from WebSocket
**Does NOT Reset Timer**:
- Output from PTY (stdout from running programs)
- Internal actor messages
- Heartbeat pings
**Rationale**: We track *user* activity, not program output. A long-running command producing output but with no user interaction should eventually timeout.
### Cleanup Behavior
When idle timeout triggers:
1. Terminal actor calls `ctx.stop()`
2. `Terminal::stopping()` is invoked
3. Child process is killed via `child.kill()`
4. PTY is closed
5. `ChildDied` message sent to WebSocket
6. WebSocket closes connection
7. Both actors cleaned up
---
## 4. Outcomes and Conclusions
### What Was Achieved
**Automatic Cleanup**: Idle sessions now timeout and clean up after 5 minutes
**Resource Protection**: Prevents grey goo accumulation of orphaned processes
**Graceful Handling**: Active sessions continue indefinitely; only idle ones timeout
**Logging**: Added INFO-level logs for timeout events to aid monitoring
**Configurable**: Constants can be easily adjusted for different use cases
**Code Compiles**: Verified with `cargo check` - no errors
### Design Decisions
#### Why 5 Minutes?
- Long enough for temporary disconnects/reconnects
- Short enough to prevent excessive resource accumulation
- Typical web session idle threshold
- Can be adjusted based on use case
#### Why Check Every 30 Seconds?
- Lightweight overhead (runs infrequently)
- Acceptable delay for cleanup (worst case: 5m30s total)
- Avoids excessive timer overhead
#### Why Not Stop Immediately on WebSocket Disconnect?
- Allows for reconnection scenarios (page reload, network hiccup)
- Gives users a grace period
- Simpler implementation (no need for custom stop messages)
- Idle timeout handles it automatically
### Trade-offs
**Advantages**:
- Simple, maintainable implementation
- Low overhead (one timer per Terminal)
- Handles multiple failure modes (disconnect, abandon, forget)
- No changes to message protocol needed
**Disadvantages**:
- Long-running unattended commands will be killed after timeout
- Fixed timeout may not suit all users/use-cases
- Slight delay in cleanup (up to timeout duration)
---
## 5. Testing and Validation
### How to Test
1. **Basic Idle Timeout**:
```bash
# Start server
cargo run
# Connect in browser, then stop interacting
# Wait 5 minutes
# Check logs for: "Terminal idle timeout reached"
# Verify process is gone: ps aux | grep socktop-agent
```
2. **Page Refresh Scenario**:
```bash
# Start server and connect
# Note PID: ps aux | grep socktop-agent
# Refresh browser page
# Old process should timeout after 5 min
# New process should be running
```
3. **Active Session**:
```bash
# Connect and actively type commands
# Session should never timeout while active
# Each keystroke resets the timer
```
4. **Quick Test** (modify code temporarily):
```rust
const IDLE_TIMEOUT: Duration = Duration::from_secs(30);
```
Then test with 30-second timeout for faster validation.
### Verification
- ✅ Code compiles without errors
- ✅ All existing functionality preserved
- ✅ Idle timeout logic is sound
- ✅ Activity tracking updates correctly
- ✅ Logging provides visibility
---
## 6. Action Items and Next Steps
### Immediate
- [x] Implement idle timeout in Terminal actor
- [x] Add activity tracking to message handlers
- [x] Add periodic idle checker
- [x] Document the feature
- [ ] **Deploy and monitor**: Push changes and observe real-world behavior
### Short-term Recommendations
1. **Monitor in Production**: Watch logs for timeout frequency and adjust if needed
2. **Add Metrics**: Track session count, average duration, timeout rate
3. **Consider Making Configurable**: Add environment variable support:
```rust
let timeout = env::var("IDLE_TIMEOUT_SECS")
.ok()
.and_then(|s| s.parse().ok())
.map(Duration::from_secs)
.unwrap_or(300);
```
### Future Enhancements
1. **Session Limits**: Add max concurrent session limits per IP or globally
2. **Activity-Aware Timeout**: Don't timeout if PTY is producing output (indicates active command)
3. **Reconnection Support**: Allow reconnecting to existing session within timeout window
4. **Graceful Warnings**: Send terminal message 1 minute before timeout
5. **Per-User Settings**: Allow users to configure their preferred timeout
6. **Session Persistence**: Integrate with tmux/screen for persistent sessions
7. **Resource-Based Timeout**: Timeout based on CPU/memory usage instead of just time
### Documentation Created
- ✅ `IDLE_TIMEOUT.md` - Comprehensive feature documentation
- ✅ `CONVERSATION_SUMMARY.md` - This summary
- In-code comments explaining the mechanism
---
## 7. Code Changes Summary
**Files Modified**: `webterm/src/lib.rs`
**Lines Added**: ~40 lines
- 2 new constants
- 2 new struct fields
- 1 idle checker interval callback
- 3 activity tracking updates
- 1 improved comment in WebSocket::stopping()
**Files Created**:
- `webterm/IDLE_TIMEOUT.md` (284 lines)
- `webterm/CONVERSATION_SUMMARY.md` (this file)
**No Breaking Changes**: All existing functionality preserved
---
## 8. Key Takeaways
### For Developers
- Actor-based systems need explicit lifecycle management
- Idle timeouts are essential for preventing resource leaks in web services
- Balance cleanup aggressiveness with user experience
- Always log lifecycle events for observability
### For Operations
- Monitor the logs for `"Terminal idle timeout reached"` messages
- Adjust `IDLE_TIMEOUT` constant based on usage patterns
- Consider resource limits (max sessions, memory caps) as additional safeguards
- Set up alerts if process count grows unexpectedly
### For Users
- Sessions timeout after 5 minutes of inactivity
- Any interaction (typing, resizing) keeps the session alive
- Page refreshes create new sessions; old ones clean up automatically
- Long-running commands need user interaction to stay alive
---
## 9. Related Context
This implementation builds on earlier work in the conversation thread:
- Upgrading xterm.js from 3.x to 5.x
- Implementing custom Terminado protocol addon
- Dockerizing the application
- Adding Catppuccin Frappe theming
- Creating desktop-like window frame
The idle timeout feature complements these improvements by ensuring the system is production-ready and resource-efficient.
---
## 10. Questions Answered
**Q**: Will terminal sessions eventually time out?
**A**: Yes, after 5 minutes of user inactivity.
**Q**: Can we make them timeout when idle?
**A**: Yes, implemented with configurable timeout.
**Q**: Can we tell when they are idle?
**A**: Yes, by tracking `last_activity` timestamp and checking periodically.
**Q**: Will this prevent grey goo?
**A**: Yes, orphaned sessions now clean up automatically instead of accumulating indefinitely.
**Q**: What if I need longer sessions?
**A**: Adjust `IDLE_TIMEOUT` constant or make it configurable via environment variable.
---
## Conclusion
The idle timeout implementation successfully addresses the resource leak issue while maintaining a good user experience. The 5-minute default timeout provides a reasonable balance between cleanup aggressiveness and allowing for temporary disconnects. The solution is simple, maintainable, and easily configurable for different deployment scenarios.
**Status**: ✅ Implementation complete and verified
**Risk Level**: 🟢 Low - backward compatible, well-tested pattern
**Recommended Action**: Deploy to production and monitor

View File

@ -1,543 +0,0 @@
# Docker Deployment Guide for socktop webterm
## Overview
This guide explains how to build and deploy the socktop webterm application in a Docker container. The container includes:
- Debian Trixie Slim base
- Rust-based webterm server
- xterm.js 5.5.0 with Catppuccin Frappe theme
- Alacritty terminal emulator
- FiraCode Nerd Font
- socktop-agent for monitoring
- All your custom configurations
## Prerequisites
- Docker (20.10 or later)
- Docker Compose (1.29 or later)
- Configuration files in the `files/` directory
## Quick Start
### 1. Prepare Configuration Files
Copy your configuration files to the `files/` directory:
```bash
cd webterm
mkdir -p files
# Copy your Alacritty configuration
cp /path/to/your/alacritty.toml files/
cp /path/to/your/catppuccin-frappe.toml files/
# Copy socktop configuration
cp /path/to/your/profiles.json files/
# Copy SSH keys (ensure correct permissions)
cp /path/to/your/*.pem files/
chmod 600 files/*.pem
```
**Required files in `files/` directory:**
- `alacritty.toml` - Alacritty terminal configuration
- `catppuccin-frappe.toml` - Catppuccin theme for Alacritty
- `profiles.json` - socktop profiles configuration
- `rpi-master.pem` - SSH key for master node
- `rpi-worker-1.pem` - SSH key for worker 1
- `rpi-worker-2.pem` - SSH key for worker 2
- `rpi-worker-3.pem` - SSH key for worker 3
**Example files:**
If you don't have these files yet, you can use the example templates:
```bash
cp files/alacritty.toml.example files/alacritty.toml
cp files/catppuccin-frappe.toml.example files/catppuccin-frappe.toml
cp files/profiles.json.example files/profiles.json
```
### 2. Build and Run with Docker Compose
```bash
# Build the image
docker-compose build
# Start the container
docker-compose up -d
# View logs
docker-compose logs -f
# Stop the container
docker-compose down
```
### 3. Access the Application
Open your browser and navigate to:
```
http://localhost:8082
```
You should see the socktop webterm interface with:
- Beautiful Catppuccin Frappe theme
- Transparent terminal window
- Link buttons to GitHub, Crates.io, and APT repository
- Terminal automatically running `socktop -P local`
## Manual Docker Commands
If you prefer not to use Docker Compose:
### Build the Image
```bash
docker build -t socktop-webterm:latest .
```
### Run the Container
```bash
docker run -d \
--name socktop-webterm \
-p 8082:8082 \
-v $(pwd)/files:/files:ro \
-v socktop-data:/home/socktop/.local/share/socktop \
--restart unless-stopped \
socktop-webterm:latest
```
### View Logs
```bash
# All logs
docker logs -f socktop-webterm
# Webterm logs only
docker exec socktop-webterm tail -f /var/log/supervisor/webterm.out.log
# Socktop agent logs only
docker exec socktop-webterm tail -f /var/log/supervisor/socktop-agent.out.log
```
### Stop and Remove
```bash
docker stop socktop-webterm
docker rm socktop-webterm
```
## Configuration
### Environment Variables
You can customize the container behavior with environment variables in `docker-compose.yml`:
```yaml
environment:
# Terminal type
- TERM=xterm-256color
# Timezone
- TZ=America/New_York
# Logging level (error, warn, info, debug, trace)
- RUST_LOG=info
```
### Port Mapping
The container exposes two ports:
- **8082**: Webterm HTTP server (web interface)
- **3000**: socktop-agent (internal, usually not exposed)
To expose the socktop-agent externally (not recommended for security):
```yaml
ports:
- "8082:8082"
- "3001:3001" # Uncomment to expose agent (container uses port 3001)
```
### Volume Mounts
#### Configuration Files (Required)
```yaml
volumes:
- ./files:/files:ro # Mount config files read-only
```
#### Persistent Data (Optional)
```yaml
volumes:
- socktop-data:/home/socktop/.local/share/socktop # Persist socktop data
- ./logs:/var/log/supervisor # Access logs on host
```
### Resource Limits
Adjust resource limits in `docker-compose.yml`:
```yaml
deploy:
resources:
limits:
cpus: '2.0' # Maximum CPU cores
memory: 1G # Maximum memory
reservations:
cpus: '0.5' # Minimum CPU cores
memory: 256M # Minimum memory
```
## Security Considerations
### Container Security
The container implements several security best practices:
1. **Non-root user**: Application runs as `socktop` user (not root)
2. **No new privileges**: `security_opt: no-new-privileges:true`
3. **Read-only config mounts**: Configuration files mounted as read-only
4. **Minimal attack surface**: Only necessary ports exposed
### SSH Key Security
**IMPORTANT**: Your SSH private keys are sensitive!
```bash
# Ensure correct permissions
chmod 600 files/*.pem
# Never commit keys to git
echo "files/*.pem" >> .gitignore
```
### Network Security
The container runs in an isolated Docker network by default. Consider:
1. **Use a reverse proxy** (nginx, Traefik) with HTTPS for production
2. **Don't expose socktop-agent port** (3000) to the internet
3. **Use firewall rules** to restrict access to port 8082
4. **Enable authentication** if exposing publicly
### Production Recommendations
For production deployments:
```bash
# Use a reverse proxy with SSL
# Example with nginx:
docker run -d \
--name nginx-proxy \
-p 80:80 \
-p 443:443 \
-v /path/to/certs:/etc/nginx/certs:ro \
-v /var/run/docker.sock:/tmp/docker.sock:ro \
jwilder/nginx-proxy
# Then expose webterm only to nginx
docker run -d \
--name socktop-webterm \
-p 127.0.0.1:8082:8082 \
-e VIRTUAL_HOST=socktop.yourdomain.com \
-e LETSENCRYPT_HOST=socktop.yourdomain.com \
socktop-webterm:latest
```
## Troubleshooting
### Container Won't Start
Check logs:
```bash
docker-compose logs
```
Common issues:
- **Missing config files**: Ensure all required files are in `files/` directory
- **Port already in use**: Change port mapping in `docker-compose.yml`
- **Permission denied**: Check file permissions, especially `.pem` files
### Terminal Not Connecting
1. Check if socktop-agent is running:
```bash
docker exec socktop-webterm ps aux | grep socktop-agent
```
2. Check agent logs:
```bash
docker exec socktop-webterm cat /var/log/supervisor/socktop-agent.out.log
```
3. Test agent connectivity:
```bash
docker exec socktop-webterm curl http://localhost:3001/health
```
### Configuration Not Loading
1. Verify files are mounted:
```bash
docker exec socktop-webterm ls -la /files
```
2. Check if files were copied:
```bash
docker exec socktop-webterm ls -la /home/socktop/.config/alacritty
docker exec socktop-webterm ls -la /home/socktop/.config/socktop
```
3. View entrypoint logs:
```bash
docker logs socktop-webterm 2>&1 | head -50
```
### Font Not Loading
1. Verify font installation:
```bash
docker exec socktop-webterm fc-list | grep -i firacode
```
2. Rebuild image if font is missing:
```bash
docker-compose build --no-cache
```
### Performance Issues
1. **Increase resource limits** in `docker-compose.yml`
2. **Check CPU/Memory usage**:
```bash
docker stats socktop-webterm
```
3. **Reduce transparency** in Alacritty config (opacity: 1.0)
4. **Disable backdrop blur** in terminal CSS
## Maintenance
### Updating the Container
```bash
# Pull latest code
git pull
# Rebuild image
docker-compose build --no-cache
# Restart container
docker-compose up -d
```
### Viewing Logs
```bash
# All supervisor logs
docker exec socktop-webterm ls /var/log/supervisor/
# Tail specific log
docker exec socktop-webterm tail -f /var/log/supervisor/webterm.out.log
# Export logs to host
docker cp socktop-webterm:/var/log/supervisor/ ./container-logs/
```
### Backing Up Configuration
```bash
# Backup volumes
docker run --rm \
-v socktop-data:/data \
-v $(pwd):/backup \
debian:trixie-slim \
tar czf /backup/socktop-backup-$(date +%Y%m%d).tar.gz /data
# Backup config files
tar czf socktop-config-backup-$(date +%Y%m%d).tar.gz files/
```
### Health Checks
The container includes a health check:
```bash
# Check health status
docker inspect --format='{{.State.Health.Status}}' socktop-webterm
# View health check logs
docker inspect socktop-webterm | jq '.[0].State.Health'
```
## Advanced Usage
### Running in Production
Example production `docker-compose.yml`:
```yaml
version: '3.8'
services:
socktop-webterm:
image: socktop-webterm:latest
container_name: socktop-webterm
restart: always
ports:
- "127.0.0.1:8082:8082" # Only localhost
volumes:
- ./files:/files:ro
- socktop-data:/home/socktop/.local/share/socktop
- /etc/localtime:/etc/localtime:ro # Use host timezone
environment:
- RUST_LOG=warn
- TZ=UTC
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
networks:
- web
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
networks:
web:
external: true
volumes:
socktop-data:
```
### Multi-Architecture Builds
Build for ARM (Raspberry Pi) and AMD64:
```bash
# Enable buildx
docker buildx create --use
# Build for multiple platforms
docker buildx build \
--platform linux/amd64,linux/arm64 \
-t socktop-webterm:latest \
--push \
.
```
### Kubernetes Deployment
Example Kubernetes manifests:
```yaml
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: socktop-webterm
spec:
replicas: 1
selector:
matchLabels:
app: socktop-webterm
template:
metadata:
labels:
app: socktop-webterm
spec:
containers:
- name: socktop-webterm
image: socktop-webterm:latest
ports:
- containerPort: 8082
volumeMounts:
- name: config
mountPath: /files
readOnly: true
resources:
limits:
memory: "1Gi"
cpu: "2"
requests:
memory: "256Mi"
cpu: "500m"
volumes:
- name: config
secret:
secretName: socktop-config
```
## Development
### Building for Development
```bash
# Build without cache
docker-compose build --no-cache
# Build with verbose output
docker-compose build --progress=plain
# Build specific stage
docker build --target builder -t socktop-webterm:builder .
```
### Interactive Debugging
```bash
# Shell into running container
docker exec -it socktop-webterm bash
# Run container with shell
docker run -it --rm \
-v $(pwd)/files:/files:ro \
socktop-webterm:latest \
/bin/bash
# Override entrypoint
docker run -it --rm \
--entrypoint /bin/bash \
socktop-webterm:latest
```
### Testing Changes
```bash
# Test with local changes
docker-compose up --build
# Watch logs
docker-compose logs -f
# Restart services
docker-compose restart
```
## Support
For issues and questions:
- **GitHub Issues**: https://github.com/jasonwitty/socktop/issues
- **Documentation**: https://jasonwitty.github.io/socktop/
- **Docker Hub**: (if you publish the image)
## License
Same as socktop project.
---
**Happy monitoring!** 🚀📊

View File

@ -1,463 +0,0 @@
# socktop webterm - Docker Deployment
🐳 **Containerized web-based terminal for socktop system monitoring**
This Docker container packages the socktop webterm application with all dependencies, providing an isolated environment for running the beautiful web-based monitoring interface.
## 🎯 What's Inside
- **Debian Trixie Slim** base image
- **Rust webterm server** (built from source)
- **xterm.js 5.5.0** with Catppuccin Frappe theme
- **Alacritty** terminal emulator with transparency
- **FiraCode Nerd Font** for beautiful monospace rendering
- **socktop-agent** installed via APT (port 3001)
- **Supervisor** for process management
- **Security hardening** (non-root user, minimal attack surface)
## 🚀 Quick Start
### Prerequisites
- Docker 20.10+
- Docker Compose 1.29+
- Your configuration files (see below)
### 1. Clone and Navigate
```bash
cd webterm
```
### 2. Set Up Configuration
```bash
# Create configuration files from examples
cd files
cp alacritty.toml.example alacritty.toml
cp catppuccin-frappe.toml.example catppuccin-frappe.toml
cp profiles.json.example profiles.json
```
### 3. Add Your SSH Keys
```bash
# Copy your SSH private keys
cp /path/to/your/rpi-master.pem files/
cp /path/to/your/rpi-worker-*.pem files/
# Set correct permissions (IMPORTANT!)
chmod 600 files/*.pem
```
### 4. Build and Run
**Option A: Use the Quick Start Script (Recommended)**
```bash
./docker-quickstart.sh start
```
This interactive script will:
- Check Docker installation
- Verify configuration files
- Build the image
- Start the container
- Show you the access URL
**Option B: Manual Docker Compose**
```bash
# Build the image
docker-compose build
# Start the container
docker-compose up -d
# View logs
docker-compose logs -f
```
### 5. Access the Application
Open your browser:
```
http://localhost:8082
```
You should see:
- ✨ Beautiful Catppuccin Frappe themed interface
- 🖼️ Terminal window with macOS-style frame
- 🔗 Links to GitHub, Crates.io, and APT repository
- 💻 Terminal automatically running `socktop -P local`
## 📋 Configuration Files
All configuration files go in the `files/` directory and are mounted into the container at runtime.
### Required Files
| File | Description | Source |
|------|-------------|--------|
| `alacritty.toml` | Alacritty terminal config | Copy from example |
| `catppuccin-frappe.toml` | Terminal color theme | Copy from example |
| `profiles.json` | socktop remote profiles | Copy from example |
| `*.pem` | SSH private keys | Your keys |
### Example Configuration
See `files/README.md` for detailed configuration instructions.
**Important**: Always set correct permissions on SSH keys:
```bash
chmod 600 files/*.pem
```
## 🛠️ Management Commands
### Using the Quick Start Script
```bash
./docker-quickstart.sh [COMMAND]
```
Available commands:
- `start` - Build and start the container (default)
- `stop` - Stop the container
- `restart` - Restart the container
- `rebuild` - Rebuild from scratch (no cache)
- `logs` - Show and follow logs
- `shell` - Open bash shell in container
- `status` - Show container status
- `clean` - Remove container and volumes
- `help` - Show help message
### Using Docker Compose Directly
```bash
# Start
docker-compose up -d
# Stop
docker-compose down
# Restart
docker-compose restart
# View logs
docker-compose logs -f
# Rebuild
docker-compose build --no-cache
# Shell access
docker exec -it socktop-webterm bash
```
## 🔍 Troubleshooting
### Container Won't Start
**Check logs:**
```bash
docker-compose logs
```
**Common issues:**
- Missing configuration files in `files/`
- Port 8082 already in use (change in `docker-compose.yml`)
- Incorrect permissions on `.pem` files (must be 600)
### Terminal Not Connecting
**Check socktop-agent status:**
```bash
docker exec socktop-webterm ps aux | grep socktop-agent
```
**View agent logs:**
```bash
docker exec socktop-webterm tail -f /var/log/supervisor/socktop-agent.out.log
```
**Test agent:**
```bash
docker exec socktop-webterm curl http://localhost:3001/health
```
### Configuration Not Loading
**Verify files are mounted:**
```bash
docker exec socktop-webterm ls -la /files
```
**Check if copied to config directories:**
```bash
docker exec socktop-webterm ls -la /home/socktop/.config/alacritty
docker exec socktop-webterm ls -la /home/socktop/.config/socktop
```
### Font Issues
**Verify font installation:**
```bash
docker exec socktop-webterm fc-list | grep -i firacode
```
If missing, rebuild:
```bash
docker-compose build --no-cache
```
## 🔒 Security
### Container Security Features
- ✅ **Non-root user**: Application runs as `socktop` user
- ✅ **No new privileges**: `security_opt: no-new-privileges:true`
- ✅ **Read-only config**: Configuration files mounted read-only
- ✅ **Minimal attack surface**: Only necessary ports exposed
- ✅ **Resource limits**: CPU and memory limits configured
- ✅ **Security updates**: Applied during build
### Best Practices
1. **Never commit SSH keys to git**
```bash
# Already in .gitignore, but verify:
git status files/
```
2. **Use correct permissions**
```bash
chmod 600 files/*.pem # SSH keys
chmod 644 files/*.toml # Config files
chmod 644 files/*.json # JSON files
```
3. **For production**
- Use a reverse proxy (nginx/Traefik) with HTTPS
- Don't expose port 3001 (socktop-agent) externally
- Use firewall rules to restrict port 8082
- Consider adding authentication
4. **Network isolation**
- Container runs in isolated Docker network
- Only exposes necessary ports
- Internal services not exposed
## 📊 Monitoring
### Health Checks
The container includes built-in health checks:
```bash
# Check health status
docker inspect --format='{{.State.Health.Status}}' socktop-webterm
# View health check logs
docker inspect socktop-webterm | jq '.[0].State.Health'
```
### Resource Usage
```bash
# Monitor CPU/Memory
docker stats socktop-webterm
# View detailed stats
docker-compose stats
```
### Logs
```bash
# All logs
docker-compose logs -f
# Specific service
docker exec socktop-webterm tail -f /var/log/supervisor/webterm.out.log
docker exec socktop-webterm tail -f /var/log/supervisor/socktop-agent.out.log
# Export logs
docker cp socktop-webterm:/var/log/supervisor/ ./logs/
```
## 🔧 Advanced Configuration
### Custom Ports
Edit `docker-compose.yml`:
```yaml
ports:
- "8080:8082" # Host:Container
```
### Environment Variables
```yaml
environment:
- TERM=xterm-256color
- TZ=America/New_York
- RUST_LOG=debug # Logging level
```
### Resource Limits
```yaml
deploy:
resources:
limits:
cpus: '4.0'
memory: 2G
```
### Volume Persistence
```yaml
volumes:
- socktop-data:/home/socktop/.local/share/socktop
- ./logs:/var/log/supervisor
```
## 📦 Building for Production
### Multi-Architecture
Build for multiple platforms (AMD64, ARM64):
```bash
docker buildx create --use
docker buildx build --platform linux/amd64,linux/arm64 -t socktop-webterm:latest --push .
```
### Optimized Build
```bash
# Build with specific target
docker build --target production -t socktop-webterm:latest .
# Build with build args
docker build --build-arg RUST_VERSION=1.70 -t socktop-webterm:latest .
```
### Image Size
Current image size: ~1.5GB (includes Rust toolchain, Node.js, fonts)
To reduce size, consider:
- Multi-stage builds (already implemented)
- Removing build dependencies after compilation
- Using Alpine base (requires significant changes)
## 🚢 Deployment Options
### Docker Compose (Recommended)
Already configured in `docker-compose.yml`
### Docker Swarm
```bash
docker stack deploy -c docker-compose.yml socktop
```
### Kubernetes
Example deployment in `DOCKER_DEPLOYMENT.md`
### Standalone Docker
```bash
docker run -d \
--name socktop-webterm \
-p 8082:8082 \
-v $(pwd)/files:/files:ro \
--restart unless-stopped \
socktop-webterm:latest
```
## 📚 Documentation
- **Full Deployment Guide**: `DOCKER_DEPLOYMENT.md` (543 lines of detailed instructions)
- **Configuration Guide**: `files/README.md`
- **Main README**: `README.md`
- **Transparency Guide**: `TRANSPARENCY_GUIDE.md`
- **Catppuccin Styling**: `CATPPUCCIN_STYLING.md`
- **Terminal Window Styling**: `TERMINAL_WINDOW_STYLING.md`
## 🆘 Getting Help
### Check Documentation
1. Read `DOCKER_DEPLOYMENT.md` for comprehensive guide
2. Check `files/README.md` for configuration help
3. Review logs with `docker-compose logs`
### Common Commands Reference
```bash
# Start everything
./docker-quickstart.sh start
# View logs
docker-compose logs -f
# Restart after config change
docker-compose restart
# Full rebuild
./docker-quickstart.sh rebuild
# Shell access for debugging
docker exec -it socktop-webterm bash
# Remove everything
./docker-quickstart.sh clean
```
### Support
- **GitHub Issues**: https://github.com/jasonwitty/socktop/issues
- **Documentation**: https://jasonwitty.github.io/socktop/
- **Source Code**: https://github.com/jasonwitty/socktop
## 🎨 Features
### Beautiful UI
- Catppuccin Frappe color scheme throughout
- Transparent terminal window with backdrop blur
- macOS-style window frame with traffic lights
- Responsive design for all screen sizes
### Terminal Features
- xterm.js 5.5.0 with modern addon system
- Auto-connects to local socktop-agent
- FiraCode Nerd Font with ligature support
- Configurable transparency and blur
### Monitoring
- socktop-agent runs on port 3001 (to avoid conflicts with host machine's agent on port 3000)
- Supports remote host monitoring via SSH
- Profile-based configuration
- Real-time system metrics
## 📝 License
Same as the socktop project.
## 🙏 Credits
- **xterm.js**: https://xtermjs.org/
- **Catppuccin**: https://github.com/catppuccin/catppuccin
- **Alacritty**: https://github.com/alacritty/alacritty
- **socktop**: https://github.com/jasonwitty/socktop
---
**Happy monitoring!** 🚀📊✨
For detailed instructions, see `DOCKER_DEPLOYMENT.md`

View File

@ -1,284 +0,0 @@
# Idle Timeout Feature
## Overview
The webterm now includes an **idle timeout mechanism** to prevent "grey goo" accumulation of orphaned terminal processes. This feature automatically cleans up inactive PTY sessions, preventing resource leaks when users refresh pages or abandon sessions.
## How It Works
### Architecture
The idle timeout is implemented in the `Terminal` actor (`src/lib.rs`):
1. **Activity Tracking**: Each `Terminal` maintains a `last_activity` timestamp that is updated whenever user interaction occurs
2. **Periodic Checking**: A background task runs every 30 seconds to check if the session has been idle
3. **Automatic Cleanup**: If a session is idle for longer than the configured timeout, the Terminal actor stops itself, cleaning up the PTY and child process
### What Counts as Activity
The `last_activity` timestamp is updated on:
- **User Input** (`TerminadoMessage::Stdin`): Keyboard input from the user
- **Terminal Resize** (`TerminadoMessage::Resize`): Window resize events
- **Direct IO** (`event::IO`): Any direct I/O from the WebSocket
Note: Output from the PTY to the terminal (stdout) does NOT reset the idle timer. This is intentional—we care about user activity, not just program output.
### Configuration
The timeout values are configured as constants in `src/lib.rs`:
```rust
const IDLE_TIMEOUT: Duration = Duration::from_secs(300); // 5 minutes
const IDLE_CHECK_INTERVAL: Duration = Duration::from_secs(30); // Check every 30 seconds
```
**Default Settings:**
- **Idle Timeout**: 5 minutes (300 seconds)
- **Check Interval**: 30 seconds
### Behavior Scenarios
#### Scenario 1: Page Refresh
1. User refreshes the browser page
2. Old WebSocket disconnects → old `Websocket` actor stops
3. Old `Terminal` actor continues running (no new messages arrive)
4. After 5 minutes of no activity, old `Terminal` times out and stops
5. New WebSocket and Terminal are created for the new page
**Result**: Old session is cleaned up within 5 minutes
#### Scenario 2: User Goes Idle
1. User leaves terminal open but inactive
2. No keyboard input or resize events occur
3. Program output (if any) continues, but doesn't reset timer
4. After 5 minutes, `Terminal` stops
**Result**: Idle session is cleaned up
#### Scenario 3: Active Use
1. User actively types commands or interacts with terminal
2. Each interaction resets `last_activity`
3. `Terminal` never reaches idle timeout
4. Session continues indefinitely while active
**Result**: Active sessions remain alive
#### Scenario 4: Long-Running Command
1. User starts a long-running command (e.g., `tail -f`, continuous monitoring)
2. Program produces output, but user doesn't interact
3. After 5 minutes of no user input, `Terminal` times out
4. Child process is killed
**Result**: Long-running unattended processes are cleaned up
> **Note**: If you need to run long-lived monitoring commands, you may want to:
> - Increase the `IDLE_TIMEOUT` constant
> - Periodically send a no-op interaction (like a resize event) to keep the session alive
> - Use a different mechanism (like tmux/screen) for persistent sessions
## Implementation Details
### Terminal Struct
```rust
pub struct Terminal {
pty_write: Option<AsyncPtyMasterWriteHalf>,
child: Option<Child>,
ws: Addr<Websocket>,
command: Command,
last_activity: Instant, // NEW: Track last activity
idle_timeout: Duration, // NEW: Timeout duration
}
```
### Initialization
In `Terminal::new()`:
```rust
Self {
pty_write: None,
child: None,
ws,
command,
last_activity: Instant::now(), // Initialize to current time
idle_timeout: IDLE_TIMEOUT, // Set configured timeout
}
```
### Periodic Check
In `Terminal::started()`:
```rust
ctx.run_interval(IDLE_CHECK_INTERVAL, |act, ctx| {
let idle_duration = Instant::now().duration_since(act.last_activity);
if idle_duration >= act.idle_timeout {
info!(
"Terminal idle timeout reached ({:?} idle), stopping session",
idle_duration
);
ctx.stop();
}
});
```
### Activity Updates
In message handlers:
```rust
// Handler<event::IO>
fn handle(&mut self, msg: event::IO, ctx: &mut Context<Self>) {
self.last_activity = Instant::now(); // Reset timer
// ... rest of handler
}
// Handler<event::TerminadoMessage>
fn handle(&mut self, msg: event::TerminadoMessage, ctx: &mut Context<Self>) {
match msg {
TerminadoMessage::Stdin(io) => {
self.last_activity = Instant::now(); // Reset on input
// ...
}
TerminadoMessage::Resize { rows, cols } => {
self.last_activity = Instant::now(); // Reset on resize
// ...
}
// ...
}
}
```
## Customization
### Changing the Timeout Duration
To adjust the idle timeout, modify the constants in `src/lib.rs`:
```rust
// For a 10-minute timeout:
const IDLE_TIMEOUT: Duration = Duration::from_secs(600);
// For a 1-minute timeout (more aggressive):
const IDLE_TIMEOUT: Duration = Duration::from_secs(60);
// For a 30-second timeout (very aggressive):
const IDLE_TIMEOUT: Duration = Duration::from_secs(30);
```
### Making It Configurable
To make the timeout configurable via environment variables:
```rust
// In Terminal::new():
let idle_timeout = std::env::var("IDLE_TIMEOUT_SECS")
.ok()
.and_then(|s| s.parse().ok())
.map(Duration::from_secs)
.unwrap_or(IDLE_TIMEOUT);
Self {
// ...
idle_timeout,
}
```
Then set it when running:
```bash
IDLE_TIMEOUT_SECS=600 cargo run
```
Or in Docker:
```dockerfile
ENV IDLE_TIMEOUT_SECS=600
```
## Monitoring and Debugging
### Log Messages
The idle timeout feature produces these log messages:
- `INFO`: `"Started Terminal"` - When a new terminal session begins
- `INFO`: `"Terminal idle timeout reached ({duration} idle), stopping session"` - When idle timeout triggers
- `INFO`: `"Stopping Terminal"` - When terminal is stopping (for any reason)
- `INFO`: `"Stopped Terminal"` - After terminal cleanup completes
### Checking Active Sessions
To see how many terminal processes are running:
```bash
# Count socktop processes
ps aux | grep socktop-agent | grep -v grep | wc -l
# See all with details
ps aux | grep socktop-agent | grep -v grep
```
### Testing the Timeout
To test with a shorter timeout (30 seconds):
1. Modify `IDLE_TIMEOUT` in `src/lib.rs`:
```rust
const IDLE_TIMEOUT: Duration = Duration::from_secs(30);
```
2. Rebuild: `cargo build`
3. Start the server and connect
4. Stop interacting and watch the logs
5. After 30 seconds, you should see: `"Terminal idle timeout reached"`
6. Verify the process is gone: `ps aux | grep socktop-agent`
## Trade-offs and Considerations
### Pros
✅ Prevents resource leaks from abandoned sessions
✅ Automatic cleanup without manual intervention
✅ Handles page refreshes gracefully
✅ Simple implementation with low overhead
### Cons
❌ Long-running unattended commands will be killed
❌ Users must stay "active" to keep sessions alive
❌ Fixed timeout may not suit all use cases
### Recommendations
**For Development**: Use a longer timeout (10-15 minutes) to avoid interruption during debugging
**For Production**:
- Start with 5 minutes (current default)
- Monitor logs to see how often timeouts occur
- Adjust based on your users' typical session patterns
- Consider making it configurable per-deployment
**For Public/Demo Instances**: Use a shorter timeout (1-2 minutes) to aggressively reclaim resources
## Future Enhancements
Possible improvements:
1. **Per-User Configurable Timeouts**: Allow users to set their preferred timeout
2. **Activity-Aware Timeout**: Don't timeout if the PTY is producing output (indicates active command)
3. **Session Persistence**: Integration with tmux/screen for sessions that survive disconnects
4. **Metrics Collection**: Track session duration, timeout frequency, resource usage
5. **Graceful Shutdown Warnings**: Send a warning message to the terminal before timeout
6. **Reconnection Support**: Allow reconnecting to an existing session within the timeout window
## Related Files
- `src/lib.rs` - Main implementation
- `src/event.rs` - Message types and events
- `Cargo.toml` - Dependencies
## See Also
- [Docker Deployment Guide](DOCKER_DEPLOYMENT.md)
- [Xterm.js Upgrade Documentation](XTERM_UPGRADE.md)
- [Catppuccin Styling Guide](CATPPUCCIN_STYLING.md)

View File

@ -1,222 +0,0 @@
# Idle Timeout Quick Reference
## TL;DR
- **Default Timeout**: 5 minutes of inactivity
- **What Triggers Cleanup**: No keyboard input, no resize events
- **What Keeps Alive**: Any typing, window resizing
- **Check Interval**: Every 30 seconds
- **Purpose**: Prevent orphaned terminal processes from accumulating
---
## Configuration (src/lib.rs)
```rust
const IDLE_TIMEOUT: Duration = Duration::from_secs(300); // 5 minutes
const IDLE_CHECK_INTERVAL: Duration = Duration::from_secs(30); // Check every 30s
```
---
## Quick Adjustments
### Conservative (10 minutes)
```rust
const IDLE_TIMEOUT: Duration = Duration::from_secs(600);
```
### Aggressive (1 minute)
```rust
const IDLE_TIMEOUT: Duration = Duration::from_secs(60);
```
### Testing (30 seconds)
```rust
const IDLE_TIMEOUT: Duration = Duration::from_secs(30);
```
---
## Environment Variable Support (Optional)
Add to `Terminal::new()`:
```rust
let idle_timeout = std::env::var("IDLE_TIMEOUT_SECS")
.ok()
.and_then(|s| s.parse().ok())
.map(Duration::from_secs)
.unwrap_or(IDLE_TIMEOUT);
```
Then run with:
```bash
IDLE_TIMEOUT_SECS=600 cargo run
```
Or in Docker:
```dockerfile
ENV IDLE_TIMEOUT_SECS=600
```
---
## Log Messages to Watch
```
INFO webterm - Started Terminal
INFO webterm - Terminal idle timeout reached (5m 0s idle), stopping session
INFO webterm - Stopping Terminal
INFO webterm - Stopped Terminal
```
---
## Testing
### Test Idle Timeout
1. Start server: `cargo run`
2. Connect in browser
3. Stop typing/interacting
4. Wait 5 minutes (or configured timeout)
5. Check logs for timeout message
6. Verify process gone: `ps aux | grep socktop-agent`
### Test Page Refresh
1. Connect and note PID: `ps aux | grep socktop-agent`
2. Refresh page (creates new session)
3. Old PID should disappear after timeout
4. New PID should be present
### Test Active Session
1. Connect and actively type
2. Session stays alive indefinitely
3. Each keystroke resets the timer
---
## Monitoring Commands
### Count Active Sessions
```bash
ps aux | grep socktop-agent | grep -v grep | wc -l
```
### List All Sessions
```bash
ps aux | grep socktop-agent | grep -v grep
```
### Watch in Real-Time
```bash
watch -n 5 'ps aux | grep socktop-agent | grep -v grep'
```
### Tail Logs for Timeouts
```bash
tail -f /path/to/logs | grep "idle timeout"
```
---
## Activity Types
| Activity | Resets Timer? | Notes |
|----------|--------------|-------|
| Keyboard input | ✅ Yes | Any typing in terminal |
| Window resize | ✅ Yes | Browser window resize |
| Mouse events | ❌ No | Not implemented |
| PTY output | ❌ No | Program output doesn't count |
| Heartbeat | ❌ No | Connection check only |
---
## Common Scenarios
### Scenario 1: User Refreshes Page
- Old session: Times out after 5 min ✅
- New session: Created immediately ✅
- Result: Clean transition, old resources freed
### Scenario 2: User Abandons Tab
- Session: Times out after 5 min ✅
- Resources: Fully cleaned up ✅
- Result: No grey goo accumulation
### Scenario 3: Long-Running Command
- User starts: `tail -f /var/log/syslog`
- User walks away
- After 5 min: Session killed ⚠️
- Solution: Increase timeout or use tmux/screen
### Scenario 4: Active Development
- User types commands frequently
- Timer resets with each command ✅
- Session never times out ✅
- Result: Uninterrupted workflow
---
## Tuning Guide
| Use Case | Recommended Timeout | Rationale |
|----------|---------------------|-----------|
| Development | 10-15 minutes | Avoid interrupting debugging |
| Production | 5 minutes | Balance UX and resources |
| Public demo | 1-2 minutes | Aggressive resource reclaim |
| Long tasks | 30-60 minutes | Allow batch jobs to complete |
| High traffic | 2-3 minutes | Prevent resource exhaustion |
---
## Troubleshooting
### Sessions Timing Out Too Quickly
- Increase `IDLE_TIMEOUT` value
- Check that activity tracking is working (look for resets in logs)
- Ensure message handlers are updating `last_activity`
### Sessions Not Cleaning Up
- Check `IDLE_CHECK_INTERVAL` is set correctly
- Verify interval callback is registered in `started()`
- Look for errors in logs preventing `ctx.stop()`
### Too Many Processes Accumulating
- Decrease `IDLE_TIMEOUT` value
- Add session limits (max concurrent)
- Check for other resource leaks
---
## Performance Impact
- **Memory**: ~16 bytes per Terminal (2 fields: Instant + Duration)
- **CPU**: Negligible (30s interval check)
- **I/O**: None (in-memory timestamp comparison)
- **Overall**: Very low overhead ✅
---
## See Also
- [IDLE_TIMEOUT.md](IDLE_TIMEOUT.md) - Full documentation
- [CONVERSATION_SUMMARY.md](CONVERSATION_SUMMARY.md) - Implementation discussion
- [DOCKER_DEPLOYMENT.md](DOCKER_DEPLOYMENT.md) - Deployment guide
---
## Quick Checklist
Before deploying:
- [ ] Set appropriate `IDLE_TIMEOUT` for your use case
- [ ] Test with quick timeout (30s) to verify behavior
- [ ] Set up log monitoring for timeout events
- [ ] Document timeout policy for users
- [ ] Consider adding metrics/alerting
- [ ] Plan for handling long-running commands
After deploying:
- [ ] Monitor timeout frequency in logs
- [ ] Check resource usage (CPU, memory, process count)
- [ ] Gather user feedback on timeout duration
- [ ] Adjust timeout based on real-world usage
- [ ] Set up alerts for abnormal process counts

View File

@ -1,235 +0,0 @@
# Quick Start Guide
## xterm.js 5.5.0 Upgrade - Quick Start
This guide will get you up and running with the upgraded xterm.js terminal in minutes.
## Prerequisites
- Rust and Cargo installed
- Node.js and npm installed
- A terminal/command line
## Installation & Running
### Step 1: Install npm Dependencies
```bash
npm install
```
This installs:
- `@xterm/xterm` v5.5.0 (the main terminal library)
- `@xterm/addon-fit` v0.10.0 (auto-sizing addon)
### Step 2: Copy Custom Addon
```bash
cp static/terminado-addon.js node_modules/
```
This makes our custom Terminado WebSocket addon available to the server.
### Step 3: Build the Rust Backend
```bash
cargo build
```
### Step 4: Run the Server
```bash
cargo run
```
The server will start on `http://127.0.0.1:8082` (localhost:8082)
### Step 5: Open in Browser
Navigate to: **http://localhost:8082/**
You should see:
- A terminal that auto-launches `socktop -P local`
- A properly sized terminal that fits the window
- A responsive terminal that resizes with the browser window
## Verify the Upgrade
Run the verification script to ensure everything is set up correctly:
```bash
./verify_upgrade.sh
```
All checks should pass with green checkmarks ✓
## Command Line Options
The server supports several command-line options:
```bash
# Run on a different port
cargo run -- --port 8080
# Run on all interfaces (0.0.0.0)
cargo run -- --host 0.0.0.0
# Use a different command
cargo run -- --command /bin/bash
# Combine options
cargo run -- --host 0.0.0.0 --port 8080 --command /bin/zsh
```
## Testing the Terminal
Open the standalone test page to verify xterm.js is working:
```bash
# Start a simple HTTP server
python3 -m http.server 8000
# Open in browser
# http://localhost:8000/test_xterm.html
```
This test page verifies:
- xterm.js 5.5.0 loads correctly
- FitAddon works
- Terminal accepts input
- Modern API is functional
## What Changed from 3.14.5 to 5.5.0?
### Package Names
- Old: `xterm`
- New: `@xterm/xterm` (scoped package)
### Addon System
- Old: `Terminal.applyAddon(fit)``term.fit()`
- New: `term.loadAddon(new FitAddon())``fitAddon.fit()`
### File Locations
- Old: `xterm/dist/xterm.js`
- New: `@xterm/xterm/lib/xterm.js`
### Custom Terminado Addon
We created a modern `TerminadoAddon` class that implements the new `ITerminalAddon` interface to handle WebSocket communication with the backend.
## Architecture
```
┌─────────────────┐
│ Browser │
│ (JavaScript) │
│ │
│ ┌───────────┐ │
│ │ xterm.js │ │
│ │ v5.5.0 │ │
│ └─────┬─────┘ │
│ │ │
│ ┌─────▼─────┐ │
│ │ FitAddon │ │
│ └───────────┘ │
│ │ │
│ ┌─────▼─────┐ │
│ │ Terminado │ │
│ │ Addon │ │
│ └─────┬─────┘ │
└────────┼────────┘
│ WebSocket
│ (JSON messages)
┌────────▼────────┐
│ Rust Backend │
│ │
│ ┌───────────┐ │
│ │ actix-web │ │
│ └─────┬─────┘ │
│ │ │
│ ┌─────▼─────┐ │
│ │ Terminado │ │
│ │ Protocol │ │
│ └─────┬─────┘ │
│ │ │
│ ┌─────▼─────┐ │
│ │ PTY │ │
│ └─────┬─────┘ │
│ │ │
│ ┌─────▼─────┐ │
│ │ socktop │ │
│ └───────────┘ │
└─────────────────┘
```
## Troubleshooting
### Terminal doesn't display
- Check browser console for JavaScript errors
- Verify WebSocket connection in DevTools Network tab
- Ensure server is running on the correct port
### Resources fail to load (404 errors)
- Run `npm install` to ensure packages are installed
- Verify `terminado-addon.js` is in `node_modules/`
- Check file paths in `templates/term.html`
### Terminal doesn't fit window
- FitAddon may not be loading correctly
- Check that `fitAddon.fit()` is called after terminal is opened
- Verify container has non-zero dimensions
### Rust compile errors
- Update Rust: `rustup update`
- Clean build: `cargo clean && cargo build`
### WebSocket connection fails
- Check firewall settings
- Try binding to `127.0.0.1` instead of `localhost`
- Verify port 8082 is not in use
## Next Steps
Now that xterm.js is upgraded, you can:
1. **Customize the terminal appearance**
- Modify colors in `templates/term.html`
- Change font size and family
- Adjust terminal dimensions
2. **Add more features**
- Install additional xterm addons
- Implement search functionality
- Add web link support
3. **Build your website**
- Use this as a foundation for your socktop website
- Add navigation and branding
- Implement user authentication
4. **Deploy to production**
- Set up HTTPS (required for secure WebSockets)
- Configure proper firewall rules
- Consider adding authentication
## Additional Resources
- **Full Documentation**: See `XTERM_UPGRADE.md`
- **Upgrade Details**: See `UPGRADE_SUMMARY.md`
- **Verification**: Run `./verify_upgrade.sh`
- **Test Page**: Open `test_xterm.html` in browser
## Getting Help
If you run into issues:
1. Run the verification script: `./verify_upgrade.sh`
2. Check the browser console for errors
3. Review server logs for backend issues
4. Consult the detailed documentation in `XTERM_UPGRADE.md`
---
**Status**: ✅ Upgrade Complete
**xterm.js Version**: 5.5.0
**FitAddon Version**: 0.10.0
**Backend**: Rust + actix-web (no changes required)

View File

@ -1,389 +0,0 @@
# Adding Static Assets to webterm
## Overview
This guide explains how to add static assets (images, fonts, CSS files, etc.) to your webterm application.
## Directory Structure
```
webterm/
├── static/ # Your custom static assets
│ ├── bg.png # Background image
│ ├── terminado-addon.js
│ └── ... # Other custom files
├── node_modules/ # npm packages (served at /static)
│ ├── @xterm/
│ └── ...
└── templates/ # HTML templates
└── term.html
```
## How Static Files Are Served
The Rust backend serves static files from two locations:
1. **`/assets/*`** → serves from `./static/` directory
2. **`/static/*`** → serves from `./node_modules/` directory
### Configuration (src/server.rs)
```rust
let factory = || {
App::new()
.service(actix_files::Files::new("/assets", "./static"))
.service(actix_files::Files::new("/static", "./node_modules"))
// ... rest of config
};
```
## Adding a Background Image
### Step 1: Add the Image File
Place your image in the `static/` directory:
```bash
cp your-background.png static/bg.png
```
### Step 2: Reference in CSS
In `templates/term.html`, add CSS to use the image:
```html
<style>
body {
background-image: url('/assets/bg.png');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
background-attachment: fixed;
}
</style>
```
### Step 3: Test
```bash
cargo run
# Open http://localhost:8082/
# Check browser DevTools Network tab to verify /assets/bg.png loads
```
## Adding Other Static Assets
### Custom CSS File
**1. Create the file:**
```bash
echo "body { font-family: 'Custom Font'; }" > static/custom.css
```
**2. Reference in HTML:**
```html
<link rel="stylesheet" href="/assets/custom.css" />
```
### Custom JavaScript
**1. Create the file:**
```bash
echo "console.log('Custom script loaded');" > static/custom.js
```
**2. Reference in HTML:**
```html
<script src="/assets/custom.js"></script>
```
### Fonts
**1. Add font files:**
```bash
mkdir -p static/fonts
cp MyFont.woff2 static/fonts/
```
**2. Use in CSS:**
```css
@font-face {
font-family: 'MyFont';
src: url('/assets/fonts/MyFont.woff2') format('woff2');
}
body {
font-family: 'MyFont', sans-serif;
}
```
### Favicon
**1. Add favicon:**
```bash
cp favicon.ico static/
```
**2. Reference in HTML:**
```html
<link rel="icon" href="/assets/favicon.ico" type="image/x-icon" />
```
## Path Reference Guide
### From HTML Template (templates/term.html)
| Asset Location | URL Path | Example |
|----------------|----------|---------|
| `static/bg.png` | `/assets/bg.png` | `url('/assets/bg.png')` |
| `static/custom.css` | `/assets/custom.css` | `href="/assets/custom.css"` |
| `node_modules/@xterm/xterm/lib/xterm.js` | `/static/@xterm/xterm/lib/xterm.js` | Use `{{ static_path }}/@xterm/xterm/lib/xterm.js` |
### Template Variables
The HTML template has access to these variables:
- `{{ static_path }}` - Resolves to `/static` (for node_modules)
- `{{ websocket_path }}` - Resolves to `/websocket` (for WebSocket connection)
**Example:**
```html
<!-- npm packages use {{ static_path }} -->
<script src="{{ static_path }}/@xterm/xterm/lib/xterm.js"></script>
<!-- Custom assets use /assets directly -->
<img src="/assets/logo.png" alt="Logo" />
```
## Best Practices
### 1. Organize Your Assets
```
static/
├── images/
│ ├── bg.png
│ └── logo.png
├── fonts/
│ └── CustomFont.woff2
├── css/
│ └── custom.css
└── js/
├── terminado-addon.js
└── custom.js
```
### 2. Reference Images in CSS
Use relative paths or absolute paths from the `/assets` root:
```css
/* Good - absolute path */
background-image: url('/assets/images/bg.png');
/* Also good - for images in CSS files in static/css/ */
background-image: url('../images/bg.png');
```
### 3. Optimize Images
Before adding large images:
```bash
# Install optimization tools
sudo apt install optipng jpegoptim
# Optimize PNG
optipng -o7 static/bg.png
# Optimize JPEG
jpegoptim --size=500k static/photo.jpg
```
### 4. Use Appropriate File Formats
- **PNG**: Screenshots, logos, images with transparency
- **JPEG**: Photos, complex images
- **SVG**: Icons, logos, simple graphics
- **WebP**: Modern format, smaller file sizes (check browser support)
## Troubleshooting
### Image Returns 404
**Problem:** `/assets/bg.png` returns 404 Not Found
**Solutions:**
1. Check file exists:
```bash
ls -la static/bg.png
```
2. Verify server is running with updated code:
```bash
cargo build
cargo run
```
3. Check server logs for errors:
```bash
# Look for actix_files errors in console output
```
4. Test the URL directly:
```bash
curl -I http://localhost:8082/assets/bg.png
```
### Image Loads But Doesn't Display
**Problem:** Network tab shows 200 OK but image doesn't appear
**Solutions:**
1. Check CSS syntax:
```css
/* Wrong */
background: /assets/bg.png;
/* Correct */
background-image: url('/assets/bg.png');
```
2. Check image path in browser DevTools:
- Open DevTools → Elements
- Inspect the element with background
- Check computed styles
3. Verify image format is supported:
```bash
file static/bg.png
# Should show: PNG image data
```
### CORS Issues
If loading assets from different origins, you may need CORS headers.
**Add to src/server.rs:**
```rust
use actix_cors::Cors;
let factory = || {
App::new()
.wrap(
Cors::default()
.allow_any_origin()
.allow_any_method()
.allow_any_header()
)
.service(actix_files::Files::new("/assets", "./static"))
// ... rest of config
};
```
**Add to Cargo.toml:**
```toml
[dependencies]
actix-cors = "0.5"
```
## Performance Considerations
### Caching
For production, consider adding cache headers:
```rust
.service(
actix_files::Files::new("/assets", "./static")
.use_etag(true)
.use_last_modified(true)
)
```
### Compression
Enable gzip compression for text assets:
```rust
use actix_web::middleware::Compress;
let factory = || {
App::new()
.wrap(Compress::default())
.service(actix_files::Files::new("/assets", "./static"))
// ... rest
};
```
### CDN for Large Assets
For production websites, consider:
- Hosting large images on a CDN
- Using external image hosting (imgur, cloudinary, etc.)
- Optimizing and compressing all assets
## Example: Complete Background Setup
Here's a complete example adding a background image:
**1. Add the image:**
```bash
cp ~/my-background.png static/bg.png
```
**2. Update templates/term.html:**
```html
<style>
body {
background-image: url('/assets/bg.png');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
background-attachment: fixed;
/* Add overlay to improve text readability */
position: relative;
}
body::before {
content: '';
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5); /* Dark overlay */
z-index: -1;
}
</style>
```
**3. Run and test:**
```bash
cargo run
# Open http://localhost:8082/
```
## Summary
- Custom static files go in `./static/` directory
- Access them via `/assets/*` URLs
- npm packages are accessed via `/static/*` URLs
- Always rebuild and restart after changing Rust code
- Use browser DevTools to debug loading issues
- Optimize images before adding them
---
**Quick Reference:**
| I want to add... | Put it in... | Access it at... |
|------------------|--------------|-----------------|
| Background image | `static/bg.png` | `/assets/bg.png` |
| Custom CSS | `static/style.css` | `/assets/style.css` |
| Custom JS | `static/script.js` | `/assets/script.js` |
| Font file | `static/fonts/font.woff2` | `/assets/fonts/font.woff2` |
| Logo | `static/logo.png` | `/assets/logo.png` |

View File

@ -1,523 +0,0 @@
# Terminal Window Styling Guide
## Overview
The terminal now has a beautiful window frame wrapper, similar to Ghostty and other modern terminal emulators. This gives your web-based terminal a native application feel.
## Features
### 1. Terminal Window Frame
- **Rounded corners** (10px border radius)
- **Deep shadow** for depth and elevation
- **Frosted glass effect** with backdrop blur
- **Semi-transparent background** that shows the page background
### 2. Title Bar
- **macOS-style traffic light buttons** (close, minimize, maximize)
- **Customizable title text**
- **Subtle border** separating it from terminal content
- **40px height** for comfortable proportions
### 3. Window Controls
- **Red button** - Close (traditionally closes the window)
- **Yellow button** - Minimize (traditionally minimizes the window)
- **Green button** - Maximize (traditionally maximizes/fullscreen)
- **Hover effect** - Buttons brighten on hover
- **12px diameter** - Classic macOS size
## Customization Options
### Change Terminal Title
In `templates/term.html`, find:
```html
<div class="terminal-title">socktop - Terminal</div>
```
Change to:
```html
<div class="terminal-title">My Awesome Terminal</div>
<div class="terminal-title">🚀 socktop v1.0</div>
<div class="terminal-title">Terminal</div>
```
### Adjust Window Size
```css
.terminal-window {
width: 80%; /* Default: 80% of viewport */
max-width: 1200px; /* Default: 1200px max */
}
```
**Options:**
```css
width: 90%; /* Larger window */
width: 60%; /* Smaller window */
width: 1000px; /* Fixed width */
max-width: 1400px; /* Bigger max */
```
### Change Border Radius (Roundness)
```css
.terminal-window {
border-radius: 10px; /* Default: 10px */
}
```
**Options:**
```css
border-radius: 6px; /* Smaller, subtle */
border-radius: 15px; /* More rounded */
border-radius: 20px; /* Very rounded */
border-radius: 0; /* Square corners */
```
### Adjust Shadow Depth
```css
.terminal-window {
box-shadow:
0 25px 50px rgba(0, 0, 0, 0.5),
0 10px 20px rgba(0, 0, 0, 0.3);
}
```
**Light shadow:**
```css
box-shadow:
0 10px 25px rgba(0, 0, 0, 0.3),
0 5px 10px rgba(0, 0, 0, 0.2);
```
**Heavy shadow:**
```css
box-shadow:
0 40px 80px rgba(0, 0, 0, 0.6),
0 20px 40px rgba(0, 0, 0, 0.4);
```
**No shadow:**
```css
box-shadow: none;
```
### Change Title Bar Color
```css
.terminal-titlebar {
background: rgba(40, 40, 40, 0.95); /* Default: dark */
}
```
**Options:**
```css
/* Lighter */
background: rgba(60, 60, 60, 0.95);
/* Darker */
background: rgba(20, 20, 20, 0.95);
/* Colored (blue) */
background: rgba(30, 40, 60, 0.95);
/* Transparent */
background: rgba(40, 40, 40, 0.7);
/* Solid */
background: rgb(40, 40, 40);
```
### Change Title Bar Height
```css
.terminal-titlebar {
height: 40px; /* Default */
}
```
**Options:**
```css
height: 32px; /* Compact */
height: 48px; /* Spacious */
height: 36px; /* Slightly smaller */
```
### Customize Traffic Light Colors
```css
.terminal-button.close {
background: #ff5f57; /* Red */
}
.terminal-button.minimize {
background: #ffbd2e; /* Yellow */
}
.terminal-button.maximize {
background: #28c840; /* Green */
}
```
**Alternative color schemes:**
**Windows style:**
```css
.terminal-button.close {
background: #e81123;
}
.terminal-button.minimize {
background: #0078d4;
}
.terminal-button.maximize {
background: #0078d4;
}
```
**Monochrome:**
```css
.terminal-button.close {
background: #999;
}
.terminal-button.minimize {
background: #777;
}
.terminal-button.maximize {
background: #555;
}
```
### Change Button Size
```css
.terminal-button {
width: 12px;
height: 12px;
}
```
**Options:**
```css
width: 10px; height: 10px; /* Smaller */
width: 14px; height: 14px; /* Larger */
width: 16px; height: 16px; /* Much larger */
```
### Adjust Button Spacing
```css
.terminal-controls {
gap: 8px; /* Default: 8px between buttons */
}
```
**Options:**
```css
gap: 6px; /* Tighter */
gap: 10px; /* Looser */
gap: 12px; /* More space */
```
### Change Window Frame Background
```css
.terminal-window {
background: rgba(30, 30, 30, 0.95); /* Default: dark */
}
```
**Options:**
```css
/* Darker */
background: rgba(20, 20, 20, 0.95);
/* Lighter */
background: rgba(50, 50, 50, 0.9);
/* Colored */
background: rgba(30, 35, 45, 0.95);
/* More transparent */
background: rgba(30, 30, 30, 0.8);
/* Fully opaque */
background: rgb(30, 30, 30);
```
### Adjust Backdrop Blur
```css
.terminal-window {
backdrop-filter: blur(20px); /* Default: 20px */
}
```
**Options:**
```css
backdrop-filter: blur(10px); /* Light blur */
backdrop-filter: blur(30px); /* Heavy blur */
backdrop-filter: blur(40px); /* Very heavy blur */
backdrop-filter: none; /* No blur */
```
## Window Styles Presets
### Ghostty Style (Default)
```css
.terminal-window {
border-radius: 10px;
box-shadow:
0 25px 50px rgba(0, 0, 0, 0.5),
0 10px 20px rgba(0, 0, 0, 0.3);
background: rgba(30, 30, 30, 0.95);
backdrop-filter: blur(20px);
}
```
### Minimal Style
```css
.terminal-window {
border-radius: 6px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
background: rgba(20, 20, 20, 0.9);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.05);
}
```
### Floating Style
```css
.terminal-window {
border-radius: 15px;
box-shadow:
0 50px 100px rgba(0, 0, 0, 0.6),
0 20px 40px rgba(0, 0, 0, 0.4);
background: rgba(25, 25, 25, 0.85);
backdrop-filter: blur(30px) saturate(180%);
}
```
### Flat Style
```css
.terminal-window {
border-radius: 0;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
background: rgba(30, 30, 30, 0.98);
backdrop-filter: none;
border: 1px solid rgba(255, 255, 255, 0.1);
}
```
### Glass Style
```css
.terminal-window {
border-radius: 12px;
box-shadow:
0 30px 60px rgba(0, 0, 0, 0.4),
inset 0 1px 0 rgba(255, 255, 255, 0.1);
background: rgba(40, 40, 40, 0.7);
backdrop-filter: blur(40px) saturate(150%);
border: 1px solid rgba(255, 255, 255, 0.15);
}
```
## Making Buttons Functional
Currently, the traffic light buttons are just decorative. To make them functional, add JavaScript:
### Close Button
```javascript
document.querySelector('.terminal-button.close').addEventListener('click', () => {
if (confirm('Close terminal?')) {
window.close(); // Or your custom close logic
}
});
```
### Minimize Button
```javascript
document.querySelector('.terminal-button.minimize').addEventListener('click', () => {
document.querySelector('.terminal-window').style.transform = 'scale(0.5)';
// Or hide: document.querySelector('.terminal-window').style.display = 'none';
});
```
### Maximize Button
```javascript
let isMaximized = false;
document.querySelector('.terminal-button.maximize').addEventListener('click', () => {
const window = document.querySelector('.terminal-window');
if (isMaximized) {
window.style.width = '80%';
window.style.maxHeight = '50vh';
} else {
window.style.width = '100%';
window.style.maxHeight = '100vh';
}
isMaximized = !isMaximized;
});
```
## Hide Traffic Lights
If you prefer no window controls:
```css
.terminal-controls {
display: none;
}
.terminal-title {
text-align: left; /* Since there's no buttons on the left */
}
```
## Center Title Without Controls
```css
.terminal-title {
text-align: center;
margin: 0 auto;
width: 100%;
}
```
## Add Icons to Title
```html
<div class="terminal-title">
<span></span> socktop - Terminal
</div>
<div class="terminal-title">
<span style="font-size: 16px;">💻</span> Terminal
</div>
```
## Title Bar Variations
### Left-aligned title with icon
```html
<div class="terminal-titlebar">
<div class="terminal-controls">...</div>
<div class="terminal-title" style="text-align: left; flex: 1;">
<span style="margin-right: 8px;">🚀</span>
socktop v1.0
</div>
</div>
```
### Title with tabs (like modern terminals)
```html
<div class="terminal-titlebar">
<div class="terminal-controls">...</div>
<div style="display: flex; gap: 4px; flex: 1;">
<div class="terminal-tab active">Terminal 1</div>
<div class="terminal-tab">Terminal 2</div>
</div>
</div>
```
Then add CSS:
```css
.terminal-tab {
padding: 8px 16px;
background: rgba(255, 255, 255, 0.05);
border-radius: 6px 6px 0 0;
color: rgba(255, 255, 255, 0.5);
font-size: 12px;
cursor: pointer;
}
.terminal-tab.active {
background: rgba(255, 255, 255, 0.1);
color: rgba(255, 255, 255, 0.9);
}
```
## Responsive Behavior
The window automatically adjusts on mobile:
```css
@media (max-width: 640px) {
.terminal-window {
width: 96%;
}
}
```
Customize:
```css
@media (max-width: 768px) {
.terminal-window {
width: 100%;
border-radius: 0; /* Remove rounded corners on mobile */
}
.terminal-titlebar {
height: 36px; /* Smaller on mobile */
}
.terminal-button {
width: 10px;
height: 10px;
}
}
```
## Accessibility
The title bar is set to `user-select: none` so users can't accidentally select the text when clicking the buttons.
To make buttons keyboard accessible:
```html
<div class="terminal-button close" role="button" tabindex="0" aria-label="Close"></div>
```
## Browser Compatibility
All features work in modern browsers:
- ✅ Chrome/Edge 76+
- ✅ Safari 9+
- ✅ Firefox 103+
`backdrop-filter` gracefully degrades in older browsers (window will just be more opaque).
## Performance Tips
1. **Reduce blur** if experiencing lag: `blur(10px)` instead of `blur(20px)`
2. **Simplify shadows** on low-end devices
3. **Use opacity carefully** - too many transparent layers can impact performance
## Quick Reference
```css
/* Size */
width: 80%;
max-width: 1200px;
border-radius: 10px;
/* Colors */
background: rgba(30, 30, 30, 0.95);
titlebar: rgba(40, 40, 40, 0.95);
/* Effects */
box-shadow: 0 25px 50px rgba(0, 0, 0, 0.5);
backdrop-filter: blur(20px);
/* Buttons */
close: #ff5f57 (red)
minimize: #ffbd2e (yellow)
maximize: #28c840 (green)
```
---
**Enjoy your beautiful terminal window frame!** 🖼️✨

View File

@ -1,326 +0,0 @@
# Terminal Transparency Guide
## Overview
The terminal now supports transparency, allowing you to see your beautiful background image through the terminal! This uses xterm.js's `allowTransparency` option combined with CSS `backdrop-filter` for a modern, polished look.
## How It Works
The transparency is achieved through three components:
1. **xterm.js `allowTransparency` option** - Enables transparency support
2. **Theme background color with alpha** - Sets the opacity level
3. **CSS backdrop-filter** - Adds optional blur effect
## Current Setup
### Terminal Configuration (JavaScript)
```javascript
var term = new Terminal({
allowTransparency: true,
theme: {
background: "rgba(0, 0, 0, 0.7)", // 70% opaque black
},
});
```
### Container Styling (CSS)
```css
#terminal {
background: transparent;
backdrop-filter: blur(10px); /* Blur effect */
border: 1px solid rgba(255, 255, 255, 0.2);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
}
```
## Customizing Transparency Level
### Option 1: Adjust Terminal Background Opacity
In `templates/term.html`, find the `Terminal` constructor and modify the alpha value:
```javascript
var term = new Terminal({
allowTransparency: true,
theme: {
background: "rgba(0, 0, 0, 0.7)", // Change the last number (0.7)
},
});
```
**Opacity Values:**
- `0.0` = Fully transparent (you'll see everything through)
- `0.3` = Very transparent (light tint)
- `0.5` = Half transparent (moderate tint)
- `0.7` = Somewhat opaque (recommended, current value)
- `0.9` = Nearly opaque (just a hint of transparency)
- `1.0` = Fully opaque (no transparency)
### Option 2: Change Background Color
You can use any color, not just black:
```javascript
// Dark blue with transparency
background: "rgba(0, 20, 40, 0.7)"
// Dark purple with transparency
background: "rgba(30, 20, 50, 0.7)"
// Dark green with transparency (Matrix style!)
background: "rgba(0, 20, 0, 0.8)"
// Use your theme colors
background: "rgba(48, 52, 70, 0.7)" // Catppuccin Frappe base
```
### Option 3: Adjust Blur Amount
In the CSS, modify the `backdrop-filter` value:
```css
/* No blur - sharp background */
backdrop-filter: none;
/* Light blur */
backdrop-filter: blur(5px);
/* Medium blur (current) */
backdrop-filter: blur(10px);
/* Heavy blur */
backdrop-filter: blur(20px);
/* Blur + brightness adjustment */
backdrop-filter: blur(10px) brightness(0.8);
```
### Option 4: Remove Blur Entirely
If you prefer sharp background with no blur:
```css
#terminal {
background: transparent;
backdrop-filter: none; /* Remove this line or set to none */
}
```
## Preset Styles
### Glassy Effect (Recommended)
```javascript
// In Terminal constructor
theme: {
background: "rgba(0, 0, 0, 0.6)",
}
```
```css
/* In CSS */
#terminal {
backdrop-filter: blur(15px);
border: 1px solid rgba(255, 255, 255, 0.2);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
}
```
### Minimal Transparency
```javascript
theme: {
background: "rgba(0, 0, 0, 0.85)",
}
```
```css
#terminal {
backdrop-filter: blur(5px);
}
```
### Maximum Transparency (Bold!)
```javascript
theme: {
background: "rgba(0, 0, 0, 0.4)",
}
```
```css
#terminal {
backdrop-filter: blur(20px) brightness(0.8);
}
```
### Frosted Glass Effect
```javascript
theme: {
background: "rgba(255, 255, 255, 0.1)", // Light background
foreground: "#000000", // Dark text
}
```
```css
#terminal {
backdrop-filter: blur(30px) saturate(180%);
border: 1px solid rgba(255, 255, 255, 0.3);
}
```
### Acrylic Effect (Windows 11 style)
```javascript
theme: {
background: "rgba(32, 32, 32, 0.7)",
}
```
```css
#terminal {
backdrop-filter: blur(40px) saturate(125%) brightness(0.9);
border: 1px solid rgba(255, 255, 255, 0.15);
box-shadow:
0 8px 32px rgba(0, 0, 0, 0.3),
inset 0 1px 0 rgba(255, 255, 255, 0.1);
}
```
## Full Theme Customization
You can customize more than just the background:
```javascript
var term = new Terminal({
allowTransparency: true,
theme: {
background: "rgba(0, 0, 0, 0.7)",
foreground: "#d4d4d4", // Text color
cursor: "#ffffff", // Cursor color
cursorAccent: "#000000", // Cursor text color
selection: "rgba(255, 255, 255, 0.3)", // Selection highlight
// ANSI Colors
black: "#000000",
red: "#e74856",
green: "#16c60c",
yellow: "#f9f1a5",
blue: "#3b78ff",
magenta: "#b4009e",
cyan: "#61d6d6",
white: "#cccccc",
// Bright ANSI Colors
brightBlack: "#767676",
brightRed: "#e74856",
brightGreen: "#16c60c",
brightYellow: "#f9f1a5",
brightBlue: "#3b78ff",
brightMagenta: "#b4009e",
brightCyan: "#61d6d6",
brightWhite: "#f2f2f2",
},
});
```
## Browser Compatibility
`backdrop-filter` is supported in:
- ✅ Chrome/Edge 76+
- ✅ Safari 9+
- ✅ Firefox 103+
- ✅ Opera 63+
For older browsers, the terminal will still work but without the blur effect.
## Performance Considerations
**Blur effects can impact performance**, especially on:
- Lower-end devices
- Large terminal windows
- Systems without GPU acceleration
If you experience lag:
1. Reduce blur amount: `blur(5px)` instead of `blur(20px)`
2. Remove blur entirely: `backdrop-filter: none;`
3. Increase opacity: Use `0.8` or `0.9` instead of `0.5`
## Tips for Best Results
1. **Match your background**: Use a background color that complements your page background
2. **Readability first**: Ensure text is still readable - don't go too transparent
3. **Test in different lighting**: What looks good in dark mode might not work in light mode
4. **Consider your content**: Busy backgrounds may need more opacity or blur
## Examples with Different Backgrounds
### Dark Background Image
```javascript
theme: { background: "rgba(0, 0, 0, 0.6)" } // More transparent OK
```
### Light Background Image
```javascript
theme: { background: "rgba(0, 0, 0, 0.8)" } // Need more opacity for contrast
```
### Busy/Complex Background
```javascript
theme: { background: "rgba(0, 0, 0, 0.75)" } // More opacity
// Plus heavy blur
backdrop-filter: blur(20px);
```
### Simple/Minimal Background
```javascript
theme: { background: "rgba(0, 0, 0, 0.5)" } // Can go more transparent
// Light or no blur
backdrop-filter: blur(5px);
```
## Troubleshooting
### Background not showing through
- Check `allowTransparency: true` is set
- Verify background has alpha channel: `rgba(r, g, b, alpha)` not `rgb(r, g, b)`
- Make sure container background is `transparent` not a solid color
### Text hard to read
- Increase opacity: Change `0.5` to `0.7` or `0.8`
- Add more blur: `blur(15px)` or `blur(20px)`
- Darken background: Use `rgba(0, 0, 0, 0.8)` instead of lighter values
### Blur not working
- Check browser compatibility
- Verify CSS syntax: `backdrop-filter: blur(10px);`
- Try without vendor prefixes first
### Performance issues
- Reduce blur amount
- Increase opacity
- Use simpler background image
- Disable backdrop-filter
## Quick Reference
```css
/* Transparency Level */
rgba(0, 0, 0, 0.5) ← Change this number (0.0 to 1.0)
/* Blur Amount */
backdrop-filter: blur(10px); ← Change this number
/* Remove blur entirely */
backdrop-filter: none;
```
---
**Enjoy your transparent terminal!** 🎨✨
Experiment with different values to find what looks best with your background image and personal style.

View File

@ -1,144 +0,0 @@
# xterm.js Upgrade Summary
## Upgrade Complete ✅
Successfully upgraded xterm.js from **version 3.14.5** to **version 5.5.0**.
## What Was Done
### 1. Updated npm Dependencies
- Replaced `xterm: ^3.14.5` with `@xterm/xterm: ^5.3.0`
- Added `@xterm/addon-fit: ^0.10.0`
- Note: npm installed version 5.5.0 (latest stable)
### 2. Created Modern Terminado Addon
**File:** `static/terminado-addon.js`
A custom addon implementing the modern `ITerminalAddon` interface that handles the Terminado WebSocket protocol. This replaced the legacy v3.x addon system.
**Key Features:**
- Bidirectional WebSocket communication
- Automatic terminal resize handling
- Buffered output for better performance
- Clean lifecycle management (activate/dispose)
- Public API: `attach()`, `detach()`, `sendSize()`, `sendCommand()`
### 3. Updated HTML Template
**File:** `templates/term.html`
- Changed script paths to new package locations
- Replaced `Terminal.applyAddon()` with `term.loadAddon()`
- Updated addon instantiation to use new class-based API
- Modernized JavaScript code structure
### 4. No Rust Changes Required
The Rust backend (`src/server.rs`, `src/lib.rs`, `src/terminado.rs`) works without modification because the Terminado protocol and WebSocket implementation remain the same.
## Key Differences Between v3.x and v5.x
| Aspect | v3.14.5 (Old) | v5.5.0 (New) |
|--------|---------------|--------------|
| Package Name | `xterm` | `@xterm/xterm` |
| Addon System | `Terminal.applyAddon()` | `term.loadAddon()` |
| Addon Location | `/dist/addons/*/` | Separate npm packages |
| Fit Method | `term.fit()` | `fitAddon.fit()` |
| CSS Path | `/dist/xterm.css` | `/css/xterm.css` |
| JS Path | `/dist/xterm.js` | `/lib/xterm.js` |
## Testing
### Verify Installation
```bash
# Check installed versions
cat node_modules/@xterm/xterm/package.json | grep version
cat node_modules/@xterm/addon-fit/package.json | grep version
```
### Run the Server
```bash
cargo build
cargo run
```
### Access the Terminal
Open http://localhost:8082/ in your browser
### Expected Behavior
- Terminal loads and displays correctly
- Terminal fits to container size
- WebSocket connects successfully
- socktop command launches automatically
- Typing works in the terminal
- Window resize updates terminal size
## Files Modified
1. ✏️ `package.json` - Updated dependencies
2. ✏️ `templates/term.html` - Updated to use v5.x API
3. ✨ `static/terminado-addon.js` - New custom addon (copied to `node_modules/`)
4. ✨ `test_xterm.html` - Test page for verification
5. ✨ `XTERM_UPGRADE.md` - Detailed upgrade documentation
6. ✨ `UPGRADE_SUMMARY.md` - This file
## Benefits of Upgrading
**Security:** Latest patches and security updates
**Performance:** Improved rendering and memory management
**Maintainability:** Cleaner, modern API design
**Features:** Access to all features added since v3.x
**Support:** Active development and community support
**Compatibility:** Better TypeScript and modern browser support
## Next Steps
### Immediate
The upgrade is complete and working. You can now:
1. Test with your socktop application
2. Customize the terminal appearance
3. Add additional features
### Future Enhancements
Consider adding these xterm addons:
- `@xterm/addon-search` - Search within terminal output
- `@xterm/addon-web-links` - Make URLs clickable
- `@xterm/addon-webgl` - Hardware-accelerated rendering
- `@xterm/addon-unicode11` - Full Unicode 11 support
## Troubleshooting
### If JavaScript console shows errors:
1. Check that all files are being served (check browser Network tab)
2. Verify paths in `templates/term.html` match file locations
3. Ensure `terminado-addon.js` is in `node_modules/`
### If terminal doesn't display:
1. Check WebSocket connection in browser DevTools
2. Verify Rust server is running on port 8082
3. Check server logs for errors
### If terminal doesn't fit properly:
1. Ensure FitAddon is loaded before calling `fit()`
2. Check that container has non-zero dimensions
3. Verify CSS is loading correctly
## Resources
- **xterm.js Documentation:** https://xtermjs.org/
- **GitHub Repository:** https://github.com/xtermjs/xterm.js
- **Detailed Upgrade Doc:** See `XTERM_UPGRADE.md` in this directory
- **Test Page:** Open `test_xterm.html` in browser (via web server)
## Questions or Issues?
If you encounter any problems:
1. Check the browser console for JavaScript errors
2. Review the server logs for backend issues
3. Verify all npm packages are installed: `npm install`
4. Ensure `terminado-addon.js` is accessible at `/static/terminado-addon.js`
---
**Status:** ✅ Upgrade Complete and Working
**Date:** 2024
**Upgraded By:** xterm.js upgrade process
**Tested:** ✅ Compiles, ✅ Runs, ✅ Loads resources, ✅ Terminal displays

View File

@ -1,230 +0,0 @@
# xterm.js Upgrade Documentation
## Overview
This document describes the upgrade of xterm.js from version 3.14.5 to 5.5.0 (latest).
## Changes Made
### 1. Package Dependencies
**Before (package.json):**
```json
{
"dependencies": {
"xterm": "^3.14.5"
}
}
```
**After (package.json):**
```json
{
"dependencies": {
"@xterm/xterm": "^5.3.0",
"@xterm/addon-fit": "^0.10.0"
}
}
```
**Installed Versions:**
- `@xterm/xterm`: 5.5.0
- `@xterm/addon-fit`: 0.10.0
### 2. Package Namespace Change
xterm.js moved from the `xterm` package to the scoped `@xterm/xterm` package. The old package is now deprecated.
### 3. Addon System Overhaul
**Old Addon System (v3.x):**
- Addons loaded via `<script>` tags from `/dist/addons/*/`
- Applied using `Terminal.applyAddon(addonName)`
- Methods added directly to Terminal prototype
- Example: `term.fit()` after applying fit addon
**New Addon System (v5.x):**
- Addons are separate npm packages under `@xterm/addon-*`
- Loaded using `term.loadAddon(new AddonClass())`
- Implements `ITerminalAddon` interface
- Methods accessed through addon instance
- Example: `fitAddon.fit()` instead of `term.fit()`
### 4. Terminado Protocol Addon
Created a custom `TerminadoAddon` class compatible with xterm 5.x that implements the Terminado WebSocket protocol.
**Location:** `static/terminado-addon.js` (also copied to `node_modules/` for serving)
**Features:**
- Implements modern `ITerminalAddon` interface
- Handles bidirectional communication over WebSocket
- Supports JSON message format: `["stdin", data]`, `["stdout", data]`, `["set_size", rows, cols]`
- Buffered output for better performance
- Automatic cleanup on dispose
- Public methods: `attach()`, `detach()`, `sendSize()`, `sendCommand()`
**API Usage:**
```javascript
const terminadoAddon = new TerminadoAddon();
term.loadAddon(terminadoAddon);
// Attach to WebSocket
terminadoAddon.attach(socket, bidirectional=true, buffered=true);
// Send size update
terminadoAddon.sendSize(rows, cols);
// Send command
terminadoAddon.sendCommand("socktop -P local\r");
// Detach when done
terminadoAddon.detach();
```
### 5. HTML Template Updates
**File:** `templates/term.html`
**Script Loading Changes:**
```html
<!-- OLD (v3.x) -->
<link rel="stylesheet" href="/static/xterm/dist/xterm.css" />
<script src="/static/xterm/dist/xterm.js"></script>
<script src="/static/xterm/dist/addons/attach/attach.js"></script>
<script src="/static/xterm/dist/addons/terminado/terminado.js"></script>
<script src="/static/xterm/dist/addons/fit/fit.js"></script>
<script src="/static/xterm/dist/addons/search/search.js"></script>
<!-- NEW (v5.x) -->
<link rel="stylesheet" href="/static/@xterm/xterm/css/xterm.css" />
<script src="/static/@xterm/xterm/lib/xterm.js"></script>
<script src="/static/@xterm/addon-fit/lib/addon-fit.js"></script>
<script src="/static/terminado-addon.js"></script>
```
**JavaScript API Changes:**
```javascript
// OLD (v3.x)
if (typeof Terminal !== 'undefined' && typeof Terminal.applyAddon === 'function') {
Terminal.applyAddon(terminado);
Terminal.applyAddon(fit);
}
var term = new Terminal();
term.open(terminalContainer);
term.terminadoAttach(sock);
term.fit();
// NEW (v5.x)
var term = new Terminal();
var fitAddon = new FitAddon.FitAddon();
term.loadAddon(fitAddon);
var terminadoAddon = new TerminadoAddon();
term.loadAddon(terminadoAddon);
term.open(terminalContainer);
fitAddon.fit();
terminadoAddon.attach(sock, true, true);
```
### 6. Rust Backend
**No changes required** - The Rust backend (`src/server.rs`, `src/lib.rs`, `src/terminado.rs`) continues to work without modification because:
- The Terminado protocol remains unchanged
- WebSocket communication is the same
- PTY handling is identical
## Migration Guide
### For Developers Using This Project
1. **Update npm packages:**
```bash
npm install
```
2. **Copy custom addon to node_modules:**
```bash
cp static/terminado-addon.js node_modules/
```
3. **Build and run:**
```bash
cargo build
cargo run
```
4. **Access the terminal:**
Open `http://localhost:8082/` in your browser
### For Projects Forking This Code
If you're building a similar project, here's what you need to know:
1. **Use scoped packages:** Install `@xterm/xterm` instead of `xterm`
2. **Install addon packages separately:** Each addon is now its own npm package
3. **Implement ITerminalAddon:** Custom addons must implement the modern interface:
```javascript
class MyAddon {
activate(terminal) { /* ... */ }
dispose() { /* ... */ }
}
```
4. **Update your HTML:** Change script paths to point to new locations
5. **Refactor addon usage:** Replace `applyAddon()` with `loadAddon()`
## Breaking Changes from v3.x to v5.x
1. **No backward compatibility:** The old addon API is completely removed
2. **Package names changed:** Must use `@xterm/*` scoped packages
3. **Addon methods moved:** Methods like `fit()` now belong to addon instances
4. **File locations changed:** Scripts moved from `dist/` to `lib/` or `css/`
5. **No global addon objects:** Addons no longer register themselves globally
## Benefits of Upgrading
1. **Modern API:** Cleaner, more maintainable code structure
2. **Better TypeScript support:** Improved type definitions
3. **Performance improvements:** Better rendering and memory management
4. **Security updates:** Patches for known vulnerabilities
5. **Active development:** v3.x is no longer maintained
6. **New features:** Access to all features added since v3.x
7. **Better addon ecosystem:** Separate packages allow independent versioning
## Testing
A test file is provided to verify the upgrade: `test_xterm.html`
Open it in a browser (served via a local web server) to verify:
- xterm.js loads correctly
- FitAddon works properly
- Terminal renders and accepts input
- Modern API is functional
## Known Issues
None at this time. The upgrade was successful with no breaking changes to functionality.
## Resources
- [xterm.js Official Documentation](https://xtermjs.org/)
- [xterm.js GitHub Repository](https://github.com/xtermjs/xterm.js)
- [Migration Guide (v3 to v4)](https://github.com/xtermjs/xterm.js/blob/master/MIGRATION.md)
- [Addon API Documentation](https://github.com/xtermjs/xterm.js/tree/master/addons)
## Future Considerations
1. **Additional addons:** Consider adding more xterm addons:
- `@xterm/addon-search`: Search functionality
- `@xterm/addon-web-links`: Clickable URLs
- `@xterm/addon-webgl`: WebGL renderer for better performance
- `@xterm/addon-unicode11`: Full Unicode 11 support
2. **WebAssembly backend:** xterm.js v5.x supports WebAssembly for improved performance
3. **Ligature support:** New versions support font ligatures for better code display
4. **Image support:** Experimental support for inline images (Sixel protocol)
## Conclusion
The upgrade to xterm.js 5.5.0 was successful. All original functionality is preserved, the codebase is now more maintainable, and we have access to the latest features and security updates.

View File

@ -85,13 +85,6 @@ show_help() {
echo " ↑/↓ - Navigate lists" echo " ↑/↓ - Navigate lists"
echo " PageUp/Down - Scroll faster" echo " PageUp/Down - Scroll faster"
echo "" echo ""
echo -e "${CYAN}Features:${NC}"
echo " ✓ Real-time CPU, memory, disk, and network monitoring"
echo " ✓ Process list with sorting and filtering"
echo " ✓ Remote monitoring via SSH"
echo " ✓ Beautiful Catppuccin Frappe theme"
echo " ✓ Lightweight and fast"
echo ""
echo -e "${CYAN}Links:${NC}" echo -e "${CYAN}Links:${NC}"
echo " GitHub: https://github.com/jasonwitty/socktop" echo " GitHub: https://github.com/jasonwitty/socktop"
echo " Documentation: https://jasonwitty.github.io/socktop/" echo " Documentation: https://jasonwitty.github.io/socktop/"

View File

@ -1,216 +0,0 @@
# Pre-Deployment Checklist for Socktop WebTerm on k3s
Use this checklist to ensure your k3s cluster is properly configured before deploying Socktop WebTerm.
## Infrastructure Requirements
### k3s Cluster
- [ ] k3s cluster is installed and running
- [ ] At least 3 nodes available (for spreading 3 replicas)
- [ ] `kubectl` is installed and configured
- [ ] Can run `kubectl get nodes` successfully
- [ ] Traefik ingress controller is running (default with k3s)
- [ ] Nodes have sufficient resources:
- [ ] 1.5+ CPU cores available per node
- [ ] 768+ MB RAM available per node
### Network Access
- [ ] k3s nodes can reach Raspberry Pi nodes on port 8443
- [ ] 192.168.1.101:8443 (rpi-master)
- [ ] 192.168.1.102:8443 (rpi-worker-1)
- [ ] 192.168.1.103:8443 (rpi-worker-2)
- [ ] 192.168.1.104:8443 (rpi-worker-3)
- [ ] Test with: `curl -k https://192.168.1.101:8443/health`
### DNS Configuration
- [ ] DNS records point to your external NGINX Proxy Manager IP:
- [ ] socktop.io → external IP
- [ ] www.socktop.io → external IP
- [ ] origin.socktop.io → external IP
- [ ] DNS propagation is complete (test with `nslookup socktop.io`)
## Required k3s Components
### Traefik Ingress Controller
- [ ] Traefik is running (comes default with k3s)
- [ ] Check with: `kubectl get pods -n kube-system | grep traefik`
- [ ] Traefik is accessible on port 80 (HTTP)
### External NGINX Proxy Manager
- [ ] External NGINX Proxy Manager is configured
- [ ] SSL certificates are set up in Proxy Manager
- [ ] Proxy hosts configured for:
- [ ] socktop.io → k3s-node-ip:8080
- [ ] www.socktop.io → k3s-node-ip:8080
- [ ] origin.socktop.io → k3s-node-ip:8080
- [ ] WebSocket support enabled in proxy hosts
- [ ] SSL termination happens at NGINX Proxy Manager
## Docker Registry Access
### Gitea Registry Configuration
- [ ] Gitea registry is accessible at 192.168.1.208:3002
- [ ] Test with: `curl http://192.168.1.208:3002/v2/`
- [ ] Image exists: `192.168.1.208:3002/jason/socktop-webterm:0.2.0`
### Insecure Registry Configuration (REQUIRED)
Since Gitea uses HTTP, you MUST configure k3s to allow insecure registries.
**On EACH k3s node** (both server and agents):
- [ ] Created `/etc/rancher/k3s/registries.yaml` with:
```yaml
mirrors:
"192.168.1.208:3002":
endpoint:
- "http://192.168.1.208:3002"
configs:
"192.168.1.208:3002":
tls:
insecure_skip_verify: true
```
- [ ] Restarted k3s services:
- [ ] Server: `sudo systemctl restart k3s`
- [ ] Agents: `sudo systemctl restart k3s-agent`
- [ ] Test image pull: `docker pull 192.168.1.208:3002/jason/socktop-webterm:0.2.0`
## TLS Certificates (Optional but Recommended)
### Raspberry Pi TLS Certificates
If you want to connect to Pi nodes via TLS:
- [ ] Have TLS CA certificates for each Pi node:
- [ ] rpi-master.pem
- [ ] rpi-worker-1.pem
- [ ] rpi-worker-2.pem
- [ ] rpi-worker-3.pem
- [ ] Certificate files are accessible on your local machine
- [ ] Know the full path to each certificate file
**Note:** If you don't have these yet, the deployment will still work, but you won't be able to connect to Pi nodes via TLS WebSocket.
## Configuration Files
### profiles.json
- [ ] Reviewed `kubernetes/01-configmap.yaml`
- [ ] Updated Raspberry Pi IP addresses if different
- [ ] Updated port numbers if different
- [ ] Updated certificate paths if different
### alacritty.toml
- [ ] Reviewed terminal configuration in `kubernetes/01-configmap.yaml`
- [ ] Adjusted font size/family if desired
- [ ] Adjusted transparency/blur settings if desired
## Deployment Files Ready
- [ ] All manifest files are present:
- [ ] `01-configmap.yaml`
- [ ] `02-secret.yaml`
- [ ] `03-deployment.yaml`
- [ ] `04-service.yaml`
- [ ] `05-ingress.yaml`
- [ ] `deploy.sh` script is executable: `chmod +x deploy.sh`
## Security Considerations
- [ ] Understand that `hostNetwork: true` reduces pod isolation
- [ ] Cluster network is trusted (not exposed to public internet directly)
- [ ] TLS certificates will be stored as Kubernetes secrets
- [ ] Consider implementing authentication (OAuth2 Proxy, etc.)
- [ ] Rate limiting is configured in ingress (100 rps by default)
## Resource Planning
With 3 replicas, total resource requirements:
- **CPU**: 1.5 cores requested, 6 cores limit
- **Memory**: 768 MB requested, 3 GB limit
- [ ] Your cluster has sufficient resources
- [ ] Check with: `kubectl describe nodes`
## Backup Plan
- [ ] Know how to view logs: `kubectl logs -l app=socktop-webterm`
- [ ] Know how to delete deployment: `kubectl delete -f kubernetes/`
- [ ] Have access to Docker logs on k3s nodes if needed
## Pre-Deployment Test Commands
Run these commands to verify everything is ready:
```bash
# Check cluster access
kubectl cluster-info
# Check nodes
kubectl get nodes
# Check Traefik ingress controller
kubectl get pods -n kube-system | grep traefik
# Check Traefik service
kubectl get svc -n kube-system traefik
# Test registry access from a node
ssh <your-k3s-node>
docker pull 192.168.1.208:3002/jason/socktop-webterm:0.2.0
# Test network access to Pi nodes
curl -k https://192.168.1.101:8443/health
```
## Ready to Deploy?
If all items above are checked ✓, you're ready to deploy!
### Choose your deployment method:
**Option 1: Automated (Recommended)**
```bash
cd kubernetes
./deploy.sh
```
**Option 2: Manual**
```bash
cd kubernetes
kubectl apply -f .
```
**Option 3: Kustomize**
```bash
cd kubernetes
kubectl apply -k .
```
## Post-Deployment Verification
After deployment, verify:
```bash
# Check pods are running
kubectl get pods -l app=socktop-webterm
# Check service is created
kubectl get svc socktop-webterm
# Check ingress is configured
kubectl get ingress socktop-webterm
# View logs
kubectl logs -l app=socktop-webterm -f
```
Configure your external NGINX Proxy Manager to forward traffic, then access:
- https://socktop.io (SSL terminated at NGINX Proxy Manager)
- https://www.socktop.io
- https://origin.socktop.io
## Troubleshooting
If something goes wrong, see:
- `QUICKSTART.md` - Common issues and quick fixes
- `README.md` - Detailed troubleshooting guide
- Pod logs: `kubectl logs -l app=socktop-webterm`
- Pod events: `kubectl describe pods -l app=socktop-webterm`

View File

@ -1,287 +0,0 @@
# Next Steps - Ready to Run After Registry Setup
## Step 1: Verify All Nodes Have the Image
Once all nodes finish pulling, verify:
```bash
# Check each node has the image cached
ssh pi@192.168.1.101 'sudo k3s crictl images | grep socktop'
ssh pi@192.168.1.102 'sudo k3s crictl images | grep socktop'
ssh pi@192.168.1.104 'sudo k3s crictl images | grep socktop'
# Should show:
# 192.168.1.208:3002/jason/socktop-webterm 0.2.0 <image-id> <size> <time>
```
## Step 2: Setup kubectl (if not done yet)
```bash
cd kubernetes
./setup-kubectl.sh
# Enter: 192.168.1.101 (your k3s server IP)
# Choose: Option 2 (save as separate file)
# Export for current session
export KUBECONFIG=~/.kube/config-k3s
# Test connection
kubectl get nodes
```
**Expected output:**
```
NAME STATUS ROLES AGE VERSION
rpi-master Ready control-plane,master 30d v1.28.x+k3s1
rpi-worker-1 Ready <none> 30d v1.28.x+k3s1
rpi-worker-2 Ready <none> 30d v1.28.x+k3s1
rpi-worker-3 Ready <none> 30d v1.28.x+k3s1
```
## Step 3: Deploy to k3s
```bash
./deploy.sh
```
**Script will ask:**
- Namespace: Press Enter for `default` or type custom name
- TLS certificates: Skip if you don't have Pi certificates yet
**Expected output:**
```
=== Socktop WebTerm - Kubernetes Deployment Script ===
✓ Connected to Kubernetes cluster
Current context: default
Enter namespace to deploy to (default: default):
Target namespace: default
Applying ConfigMap...
✓ ConfigMap applied
Applying Secret...
✓ Secret applied
Applying Deployment...
✓ Deployment applied
Applying Service...
✓ Service applied
Applying Ingress...
✓ Ingress applied
=== Deployment Complete! ===
Waiting for pods to be ready...
(This may take a minute while images are pulled)
✓ All pods are ready!
Pods:
NAME READY STATUS RESTARTS AGE
socktop-webterm-xxxxxxxxxx-xxxxx 1/1 Running 0 30s
socktop-webterm-xxxxxxxxxx-xxxxx 1/1 Running 0 30s
socktop-webterm-xxxxxxxxxx-xxxxx 1/1 Running 0 30s
```
## Step 4: Verify Deployment
```bash
# Check pods are running
kubectl get pods -l app=socktop-webterm -o wide
# Check which nodes they're on
kubectl get pods -l app=socktop-webterm -o custom-columns=NAME:.metadata.name,NODE:.spec.nodeName,STATUS:.status.phase
# Check service
kubectl get svc socktop-webterm
# Check ingress
kubectl get ingress socktop-webterm
# View logs
kubectl logs -l app=socktop-webterm --tail=20
```
## Step 5: Test Internal Access
From any k3s node:
```bash
# Test HTTP access
curl -I http://localhost:8080 -H "Host: socktop.io"
# Should return HTTP 200 OK
```
## Step 6: Configure NGINX Proxy Manager
See `NGINX-PROXY-MANAGER.md` for full details.
**Quick setup:**
1. **Log into NGINX Proxy Manager** (http://your-proxy-manager:81)
2. **Add Proxy Host → socktop.io**
- Domain Names: `socktop.io`
- Scheme: `http`
- Forward Hostname/IP: `192.168.1.101` (any k3s node)
- Forward Port: `8080`
- ✅ Websockets Support: ON
- Block Common Exploits: ON
**SSL Tab:**
- SSL Certificate: Select/create Let's Encrypt cert
- Force SSL: ON
- HTTP/2 Support: ON
**Advanced Tab:**
```nginx
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
proxy_connect_timeout 60s;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
```
3. **Repeat for www.socktop.io and origin.socktop.io**
## Step 7: Test External Access
```bash
# Test from external network or your local machine
curl -I https://socktop.io
# Should return HTTP 200 OK with SSL
```
Open browser:
- https://socktop.io
- Should see the webterm interface
- Check browser console (F12) → Network tab
- Look for WebSocket connection with status "101 Switching Protocols"
## Step 8: Test Terminal Functionality
In the browser:
1. Select "local" profile (containerized agent on port 3001)
2. Terminal should connect and show prompt
3. Try running commands: `ls`, `pwd`, `uname -a`
4. Test with Pi profiles if you have TLS certs configured
## Troubleshooting Quick Reference
### Pods not starting
```bash
kubectl describe pods -l app=socktop-webterm
kubectl logs -l app=socktop-webterm --tail=50
```
### ImagePullBackOff
```bash
# Check if image is on the node
kubectl get pods -l app=socktop-webterm -o wide
# Note which node
ssh pi@<node-ip> 'sudo k3s crictl images | grep socktop'
```
### 502 Bad Gateway
```bash
# Check pods are running
kubectl get pods -l app=socktop-webterm
# Check service endpoints
kubectl get endpoints socktop-webterm
# Test from k3s node
ssh pi@192.168.1.101 'curl http://localhost:8080 -H "Host: socktop.io"'
```
### WebSocket not connecting
- Check NGINX Proxy Manager has WebSocket Support enabled
- Check Advanced config includes upgrade headers
- Check browser console for specific errors
## Useful Commands
```bash
# Watch pod status
kubectl get pods -l app=socktop-webterm -w
# Stream logs from all pods
kubectl logs -l app=socktop-webterm -f
# Scale up
kubectl scale deployment socktop-webterm --replicas=5
# Scale down
kubectl scale deployment socktop-webterm --replicas=2
# Restart deployment (e.g., after config change)
kubectl rollout restart deployment socktop-webterm
# View rollout status
kubectl rollout status deployment socktop-webterm
# Update image to new version
kubectl set image deployment/socktop-webterm \
webterm=192.168.1.208:3002/jason/socktop-webterm:0.3.0
# Delete deployment
kubectl delete -f .
```
## Performance Testing
Once running:
```bash
# Check resource usage
kubectl top pods -l app=socktop-webterm
# Check pod distribution across nodes
kubectl get pods -l app=socktop-webterm -o wide
# Watch metrics
watch -n 2 'kubectl top pods -l app=socktop-webterm'
```
## Success Indicators
✅ 3 pods in Running state
✅ Service has 3 endpoints
✅ Ingress created successfully
✅ Can curl http://localhost:8080 from k3s node
✅ NGINX Proxy Manager forwards traffic
✅ Can access https://socktop.io in browser
✅ WebSocket connects (check browser console)
✅ Terminal sessions work
✅ Can switch between profiles
## Next Steps After Deployment
1. Monitor performance under load
2. Test failover (kill a pod, see if traffic continues)
3. Test session affinity (refresh page, stay on same pod)
4. Configure monitoring/alerting (optional)
5. Set up backup strategy for configs (optional)
6. Document your NGINX Proxy Manager config
## All Done! 🎉
Your Socktop WebTerm should now be:
- Running on 3 pods
- Distributed across k3s nodes
- Accessible via https://socktop.io
- Load balanced by Traefik
- SSL terminated at NGINX Proxy Manager
- Ready for production use!

View File

@ -1,307 +0,0 @@
# Socktop WebTerm - Kubernetes Deployment Guide
Complete Kubernetes deployment manifests and tools for running Socktop WebTerm on your k3s cluster.
## 📁 Files Overview
### Core Manifests (Deploy in Order)
1. **`01-configmap.yaml`** - Configuration files (profiles.json, alacritty.toml, theme)
2. **`02-secret.yaml`** - TLS certificates for Raspberry Pi nodes (placeholder)
3. **`03-deployment.yaml`** - Main deployment with 3 replicas, host networking
4. **`04-service.yaml`** - Service with session affinity for terminal connections
5. **`05-ingress.yaml`** - Ingress with TLS, WebSocket support, and multiple domains
### Deployment Tools
- **`deploy.sh`** - Automated deployment script (recommended)
- **`kustomization.yaml`** - Kustomize configuration for advanced deployments
### Documentation
- **`INDEX.md`** - This file - overview and quick navigation
- **`QUICKSTART.md`** - Get running in 5 minutes
- **`README.md`** - Comprehensive deployment guide
- **`CHECKLIST.md`** - Pre-deployment checklist
## 🚀 Quick Start
### Fastest Way to Deploy
```bash
cd kubernetes
./deploy.sh
```
The script handles everything automatically!
### Manual Deployment
```bash
kubectl apply -f 01-configmap.yaml
kubectl apply -f 02-secret.yaml
kubectl apply -f 03-deployment.yaml
kubectl apply -f 04-service.yaml
kubectl apply -f 05-ingress.yaml
```
Or all at once:
```bash
kubectl apply -f .
```
## 📋 Prerequisites
Before deploying, ensure you have:
- ✅ k3s cluster running (3+ nodes recommended)
- ✅ kubectl configured
- ✅ Traefik Ingress Controller (default with k3s)
- ✅ External NGINX Proxy Manager for SSL termination
- ✅ DNS records pointing to external IP (socktop.io, www.socktop.io, origin.socktop.io)
- ✅ Insecure registry configured for `192.168.1.208:3002`
- ✅ Proxy hosts configured in NGINX Proxy Manager to forward to k3s on port 8080
**See `CHECKLIST.md` for complete pre-deployment verification.**
## 🔧 Configuration Overview
### Deployment Specs
- **Replicas**: 3 (adjust in `03-deployment.yaml`)
- **Image**: `192.168.1.208:3002/jason/socktop-webterm:0.2.0`
- **Networking**: Host network mode (for accessing Pi nodes on port 8443)
- **Resources**: 500m-2000m CPU, 256Mi-1Gi RAM per pod
- **Health Checks**: HTTP liveness and readiness probes
### Exposed Services
- **Port 8082**: WebTerm HTTP interface
- **Port 3001**: Containerized socktop-agent
### Ingress Configuration
- **Ingress Controller**: Traefik (default with k3s)
- **Domains**: socktop.io, www.socktop.io, origin.socktop.io
- **TLS**: Terminated at external NGINX Proxy Manager (not in cluster)
- **WebSocket**: Supported by default in Traefik
- **Session Affinity**: Configured in Service (ClientIP)
### ConfigMap Contents
- `profiles.json` - Connection profiles for local and 4 Pi nodes
- `alacritty.toml` - Terminal emulator configuration
- `catppuccin-frappe.toml` - Color scheme
## 📚 Documentation Guide
### Start Here
1. **`CHECKLIST.md`** - Verify all prerequisites are met
2. **`QUICKSTART.md`** - Deploy in 5 minutes
3. **`README.md`** - Deep dive into configuration and troubleshooting
### Common Tasks
**First Time Deployment**
→ Read `CHECKLIST.md` then run `./deploy.sh`
**Quick Deploy**
→ See `QUICKSTART.md`
**Troubleshooting**
→ See `QUICKSTART.md` (common issues) or `README.md` (comprehensive guide)
**Update Configuration**
→ Edit ConfigMap: `kubectl edit configmap socktop-webterm-config`
→ Restart: `kubectl rollout restart deployment socktop-webterm`
**Update Image Version**
`kubectl set image deployment/socktop-webterm webterm=192.168.1.208:3002/jason/socktop-webterm:NEW_VERSION`
**Scale Replicas**
`kubectl scale deployment socktop-webterm --replicas=5`
## 🛠️ Common Commands
```bash
# Check deployment status
kubectl get pods -l app=socktop-webterm
# View logs
kubectl logs -l app=socktop-webterm -f
# Check ingress
kubectl get ingress socktop-webterm
# Check certificate status
kubectl get certificate socktop-webterm-tls
# Describe deployment
kubectl describe deployment socktop-webterm
# Scale up
kubectl scale deployment socktop-webterm --replicas=5
# Update image
kubectl set image deployment/socktop-webterm webterm=192.168.1.208:3002/jason/socktop-webterm:0.3.0
# Restart deployment
kubectl rollout restart deployment socktop-webterm
# Delete everything
kubectl delete -f .
```
## 🌐 Access URLs
After deployment and configuring NGINX Proxy Manager, access your terminal at:
- https://socktop.io (SSL terminated at NGINX Proxy Manager)
- https://www.socktop.io
- https://origin.socktop.io
Traffic flow: **Internet → NGINX Proxy Manager (port 8080) → k3s Traefik (HTTP) → Service → Pods**
## ⚙️ Architecture Highlights
### Host Networking
- Uses `hostNetwork: true` to directly access Pi nodes on port 8443
- Each pod binds to host network interface
- Containerized agent runs on port 3001 (not 3000) to avoid conflicts
### High Availability
- 3 replicas for redundancy
- k3s spreads pods across available nodes
- Session affinity keeps users on same pod
- If a pod fails, traffic routes to healthy pods
### WebSocket Support
- Ingress configured for WebSocket upgrades
- Long connection timeouts (3600s)
- Proper headers for terminal connections
### Security
- Non-root user inside container
- Read-only certificate mounts
- Security context with dropped capabilities
- TLS for external access
- Rate limiting enabled
## 🔍 Monitoring & Debugging
### Check Resource Usage
```bash
kubectl top pods -l app=socktop-webterm
```
### View Pod Distribution
```bash
kubectl get pods -l app=socktop-webterm -o wide
```
### Check Events
```bash
kubectl get events --sort-by='.lastTimestamp' | grep socktop
```
### Test Pi Connectivity
```bash
kubectl exec -it deployment/socktop-webterm -- curl -k https://192.168.1.101:8443/health
```
## 📦 What's Included
```
kubernetes/
├── 01-configmap.yaml # Configuration files
├── 02-secret.yaml # TLS certificates (placeholder)
├── 03-deployment.yaml # Main deployment (3 replicas)
├── 04-service.yaml # Service with session affinity
├── 05-ingress.yaml # Ingress with TLS and WebSocket
├── deploy.sh # Automated deployment script
├── kustomization.yaml # Kustomize configuration
├── CHECKLIST.md # Pre-deployment checklist
├── QUICKSTART.md # 5-minute quick start
├── README.md # Comprehensive guide
└── INDEX.md # This file
```
## 🚨 Important Notes
1. **Insecure Registry**: You MUST configure `/etc/rancher/k3s/registries.yaml` on all k3s nodes to allow pulling from `192.168.1.208:3002`
2. **DNS Configuration**: Ensure socktop.io domains point to your external NGINX Proxy Manager IP, not cluster IP
3. **External Proxy**: Configure NGINX Proxy Manager to forward traffic to k3s nodes on port 8080 with WebSocket support enabled
4. **SSL Termination**: SSL/TLS is handled by NGINX Proxy Manager, not in the k8s cluster
5. **TLS Certificates**: The `02-secret.yaml` is a placeholder for Pi node certificates. Use `deploy.sh` or manually create the secret
6. **Host Network**: Using `hostNetwork: true` reduces isolation but is required to reach Pi nodes
7. **Session Affinity**: Crucial for maintaining terminal connections - don't disable!
## 🆘 Need Help?
### Quick Fixes
See **`QUICKSTART.md`** for common issues and solutions
### Detailed Troubleshooting
See **`README.md`** for comprehensive troubleshooting guide
### Verify Prerequisites
Run through **`CHECKLIST.md`** to ensure everything is configured
### Check Logs
```bash
kubectl logs -l app=socktop-webterm --tail=100
```
### Describe Resources
```bash
kubectl describe deployment socktop-webterm
kubectl describe pods -l app=socktop-webterm
```
## 📈 Performance & Scaling
### Default Configuration
- 3 replicas
- 500m CPU request, 2000m limit per pod
- 256Mi RAM request, 1Gi limit per pod
### Scaling Up
```bash
kubectl scale deployment socktop-webterm --replicas=5
```
### Resource Adjustment
Edit `03-deployment.yaml` resources section, then:
```bash
kubectl apply -f 03-deployment.yaml
```
## 🔐 Security Considerations
- Run as non-root user inside container
- Drop unnecessary capabilities
- Use secrets for sensitive data (certificates)
- Enable TLS for external access
- Implement rate limiting
- Consider adding authentication layer (OAuth2 Proxy)
- Use network policies to restrict pod-to-pod traffic
## ✅ Success Indicators
Deployment is successful when:
- All 3 pods show `Running` status
- Service has endpoints: `kubectl get endpoints socktop-webterm`
- Ingress has an address: `kubectl get ingress socktop-webterm`
- Certificate shows `Ready=True`: `kubectl get certificate socktop-webterm-tls`
- Can access https://socktop.io in browser
- Terminal sessions work correctly
## 📝 Version Information
- **Application Version**: 0.2.0
- **Container Image**: 192.168.1.208:3002/jason/socktop-webterm:0.2.0
- **Kubernetes API Version**: apps/v1, networking.k8s.io/v1
- **Ingress Controller**: Traefik (default with k3s)
- **SSL Termination**: External NGINX Proxy Manager
---
**Ready to deploy?** Start with `CHECKLIST.md``./deploy.sh` → Profit! 🎉

View File

@ -1,215 +0,0 @@
# Setting Up kubectl for k3s
Since your kubectl config is empty, you need to configure it to connect to your k3s cluster.
## Quick Setup (Automated)
```bash
cd kubernetes
./setup-kubectl.sh
```
The script will:
1. Ask for your k3s server IP
2. Retrieve the kubeconfig from the server via SSH
3. Modify it to use the correct server IP
4. Save it to your local machine
5. Test the connection
### Example Run:
```bash
$ ./setup-kubectl.sh
Enter k3s server IP address: 192.168.1.101
Enter SSH username for k3s server (default: ubuntu): ubuntu
Fetching kubeconfig from k3s server...
✓ Retrieved kubeconfig from server
Choose how to save the kubeconfig:
1) Replace ~/.kube/config
2) Save as ~/.kube/config-k3s (separate file, safer)
3) Merge with existing ~/.kube/config
Enter choice (1/2/3, default: 2): 2
✓ Saved to ~/.kube/config-k3s
To use this config, run:
export KUBECONFIG=~/.kube/config-k3s
```
## Manual Setup
If you prefer to do it manually:
### Step 1: Get kubeconfig from k3s server
```bash
# SSH to your k3s server node
ssh ubuntu@192.168.1.101 # use your server IP
# View the kubeconfig
sudo cat /etc/rancher/k3s/k3s.yaml
```
### Step 2: Copy to your local machine
```bash
# On your local machine
mkdir -p ~/.kube
# Copy the config (replace 192.168.1.101 with your k3s server IP)
scp ubuntu@192.168.1.101:/tmp/k3s-config.yaml ~/.kube/config-k3s
# Or manually copy the content
nano ~/.kube/config-k3s
# Paste the content from previous step
```
### Step 3: Modify server IP
Edit the file and change the server IP from `127.0.0.1` to your actual k3s server IP:
```bash
nano ~/.kube/config-k3s
```
Change:
```yaml
server: https://127.0.0.1:6443
```
To:
```yaml
server: https://192.168.1.101:6443 # use your actual IP
```
### Step 4: Set KUBECONFIG
```bash
export KUBECONFIG=~/.kube/config-k3s
```
Make it permanent by adding to your shell config:
**For bash (~/.bashrc):**
```bash
echo 'export KUBECONFIG=~/.kube/config-k3s' >> ~/.bashrc
source ~/.bashrc
```
**For zsh (~/.zshrc):**
```bash
echo 'export KUBECONFIG=~/.kube/config-k3s' >> ~/.zshrc
source ~/.zshrc
```
**For fish (~/.config/fish/config.fish):**
```fish
echo 'set -gx KUBECONFIG ~/.kube/config-k3s' >> ~/.config/fish/config.fish
```
### Step 5: Test connection
```bash
kubectl get nodes
```
You should see your k3s nodes listed!
## Verify Setup
After configuration, verify everything works:
```bash
# Check contexts
kubectl config get-contexts
# Should show something like:
# CURRENT NAME CLUSTER AUTHINFO NAMESPACE
# * default default default
# Check nodes
kubectl get nodes
# Should show your k3s nodes:
# NAME STATUS ROLES AGE VERSION
# rpi-master Ready control-plane,master 30d v1.28.2+k3s1
# rpi-worker-1 Ready <none> 30d v1.28.2+k3s1
# rpi-worker-2 Ready <none> 30d v1.28.2+k3s1
# Check cluster info
kubectl cluster-info
```
## Troubleshooting
### Cannot connect to k3s server
**Error:** `Unable to connect to the server: dial tcp 192.168.1.101:6443: i/o timeout`
**Fix:**
- Verify the IP address is correct
- Check if port 6443 is accessible: `nc -zv 192.168.1.101 6443`
- Check firewall rules on k3s server
- Ensure k3s is running: `ssh ubuntu@192.168.1.101 'sudo systemctl status k3s'`
### Permission denied
**Error:** `error: You must be logged in to the server (Unauthorized)`
**Fix:**
- The kubeconfig may not have been copied correctly
- Re-run the setup script or manually copy the config again
### Wrong server IP
If you need to change the server IP:
```bash
nano ~/.kube/config-k3s
# Change the server: line to the correct IP
```
## Next Steps
Once kubectl is configured:
```bash
# 1. Configure registry on all k3s nodes
./setup-registry.sh
# 2. Deploy Socktop WebTerm
./deploy.sh
```
## Complete Workflow Example
```bash
# Setup kubectl
cd kubernetes
./setup-kubectl.sh
# Enter: 192.168.1.101 (your k3s server IP)
# Choose option 2 (save as separate file)
# Set environment variable for current session
export KUBECONFIG=~/.kube/config-k3s
# Verify connection
kubectl get nodes
# Configure registry
./setup-registry.sh
# Enter all node IPs
# Deploy
./deploy.sh
# Choose namespace: default
# Check status
kubectl get pods -l app=socktop-webterm
# Done!
```

View File

@ -1,311 +0,0 @@
# NGINX Proxy Manager Configuration for Socktop WebTerm
This guide explains how to configure your external NGINX Proxy Manager to route traffic to your k3s Socktop WebTerm deployment.
## Overview
Since your ISP restricts incoming ports, you're using an external NGINX Proxy Manager to:
- Terminate SSL/TLS connections
- Route traffic on port 8080 to your k3s cluster
- Handle WebSocket upgrades for terminal connections
## Architecture
```
Internet (HTTPS:443)
External NGINX Proxy Manager
↓ (SSL Termination)
k3s Traefik Ingress (HTTP:8080)
Socktop WebTerm Service
Pods (3 replicas)
```
## Prerequisites
- [ ] NGINX Proxy Manager installed and accessible
- [ ] SSL certificates ready (Let's Encrypt or custom)
- [ ] k3s cluster deployed with Socktop WebTerm
- [ ] Know your k3s node IP addresses
- [ ] DNS records pointing to your external NGINX Proxy Manager
## Configuration Steps
### Step 1: Get Your k3s Node IP
Find the IP address of any k3s node (Traefik runs on all nodes with k3s):
```bash
kubectl get nodes -o wide
```
Note any node's INTERNAL-IP (e.g., `192.168.1.101`).
### Step 2: Verify Traefik is Running
```bash
kubectl get svc -n kube-system traefik
```
You should see Traefik listening on port 80.
### Step 3: Create Proxy Host for socktop.io
In NGINX Proxy Manager web UI:
1. **Go to**: Proxy Hosts → Add Proxy Host
2. **Details Tab**:
- **Domain Names**: `socktop.io`
- **Scheme**: `http` (NOT https - SSL terminates at proxy)
- **Forward Hostname / IP**: `192.168.1.101` (your k3s node IP)
- **Forward Port**: `8080`
- **Cache Assets**: ☐ (unchecked)
- **Block Common Exploits**: ☑ (checked)
- **Websockets Support**: ☑ (IMPORTANT - check this!)
- **Access List**: None (or your preference)
3. **SSL Tab**:
- **SSL Certificate**: Select or create new Let's Encrypt certificate
- **Force SSL**: ☑ (checked)
- **HTTP/2 Support**: ☑ (checked)
- **HSTS Enabled**: ☑ (optional but recommended)
- **HSTS Subdomains**: ☐ (unless you want this)
4. **Advanced Tab** (optional but recommended):
```nginx
# Increase timeouts for long-running terminal connections
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
proxy_connect_timeout 60s;
# WebSocket upgrade headers (should be set automatically, but just in case)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Pass through real client IP
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
```
5. Click **Save**
### Step 4: Create Proxy Host for www.socktop.io
Repeat Step 3 with:
- **Domain Names**: `www.socktop.io`
- All other settings identical
### Step 5: Create Proxy Host for origin.socktop.io
Repeat Step 3 with:
- **Domain Names**: `origin.socktop.io`
- All other settings identical
## Verify Configuration
### Test 1: Check HTTP Forward
From your local machine:
```bash
curl http://<k3s-node-ip>:8080 -H "Host: socktop.io"
```
Should return the webterm HTML page.
### Test 2: Check HTTPS via Proxy
```bash
curl -I https://socktop.io
```
Should return `200 OK` with SSL certificate.
### Test 3: Check WebSocket Support
In your browser's developer console (F12), check the Network tab when connecting to the terminal. You should see:
- WebSocket connection established
- Status: `101 Switching Protocols`
## Troubleshooting
### 502 Bad Gateway
**Cause**: NGINX Proxy Manager can't reach k3s
**Fix**:
- Verify k3s node IP is correct
- Check port 8080 is accessible: `curl http://<node-ip>:8080`
- Ensure firewall allows traffic from proxy to k3s
- Check Traefik is running: `kubectl get pods -n kube-system | grep traefik`
### SSL Certificate Error
**Cause**: SSL certificate not properly configured
**Fix**:
- Verify DNS points to NGINX Proxy Manager IP
- Wait for Let's Encrypt validation (can take a few minutes)
- Check NGINX Proxy Manager logs for certificate errors
### WebSocket Connection Fails
**Cause**: WebSocket support not enabled or timeouts too short
**Fix**:
- Enable "Websockets Support" checkbox in proxy host
- Add custom nginx configuration with longer timeouts (see Step 3, Advanced tab)
- Check browser console for specific WebSocket errors
### Terminal Disconnects After 60 Seconds
**Cause**: Default proxy timeouts are too short
**Fix**: Add to Advanced tab in proxy host:
```nginx
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
```
### Can Access HTTP but not HTTPS
**Cause**: DNS records still point to old IP or wrong IP
**Fix**:
- Verify DNS with: `nslookup socktop.io`
- Should return your external NGINX Proxy Manager IP
- Wait for DNS propagation (up to 24 hours, usually minutes)
## Load Balancing (Optional)
If you want to load balance across multiple k3s nodes:
### Option 1: Use Multiple Upstream Servers in Advanced Config
```nginx
# Add to Advanced tab
upstream k3s_backend {
server 192.168.1.101:8080;
server 192.168.1.102:8080;
server 192.168.1.104:8080;
}
# Then change proxy_pass to use upstream
proxy_pass http://k3s_backend;
```
### Option 2: Use k3s LoadBalancer Service
Change the Service type in `04-service.yaml` to `LoadBalancer` and use the assigned external IP.
## Security Best Practices
1. **Enable Force SSL**: Always redirect HTTP to HTTPS
2. **Enable HSTS**: Tells browsers to always use HTTPS
3. **Enable Block Common Exploits**: Provides basic protection
4. **Add Access List**: Restrict by IP if possible
5. **Use Strong SSL**: Enable HTTP/2, disable old TLS versions
6. **Keep Timeouts Reasonable**: 3600s (1 hour) for terminal sessions
## Example Complete Advanced Configuration
For best results, use this in the Advanced tab:
```nginx
# Timeouts for long-running connections
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
proxy_connect_timeout 60s;
keepalive_timeout 3600s;
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Pass through client information
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
# Buffering (disable for WebSockets)
proxy_buffering off;
# Security headers
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
```
## Testing Checklist
After configuration, verify:
- [ ] Can access https://socktop.io and see login/terminal page
- [ ] Can access https://www.socktop.io (same result)
- [ ] Can access https://origin.socktop.io (same result)
- [ ] SSL certificate shows as valid (no browser warnings)
- [ ] Terminal connections work and stay connected
- [ ] WebSocket shows as connected in browser dev tools
- [ ] Can switch between different profiles
- [ ] Terminal sessions survive page refresh (with session affinity)
## Monitoring
### Check NGINX Proxy Manager Logs
In NGINX Proxy Manager UI:
- Go to proxy host → Click on host → View logs
### Check k3s Side
```bash
# Check ingress
kubectl get ingress socktop-webterm
# Check service endpoints
kubectl get endpoints socktop-webterm
# Check pod logs
kubectl logs -l app=socktop-webterm -f
```
## Common Traffic Flow Issues
| Symptom | Likely Cause | Check |
|---------|--------------|-------|
| 404 Not Found | Traefik routing issue | `kubectl describe ingress socktop-webterm` |
| 502 Bad Gateway | Can't reach k3s | Firewall, k3s node IP, port 8080 |
| 503 Service Unavailable | Pods not ready | `kubectl get pods -l app=socktop-webterm` |
| SSL Error | Certificate issue | NGINX Proxy Manager SSL tab |
| WebSocket fails | WS not enabled | Enable WebSocket support checkbox |
## Summary
Your complete setup should be:
1. **DNS**: socktop.io → Your external IP (NGINX Proxy Manager)
2. **NGINX Proxy Manager**:
- Listens on 443 (HTTPS)
- Terminates SSL
- Forwards to k3s-node:8080 (HTTP)
- WebSocket support enabled
3. **k3s Traefik**:
- Receives HTTP on port 8080
- Routes to socktop-webterm service
4. **Service**:
- Routes to healthy pods
- Session affinity enabled
5. **Pods**:
- 3 replicas running webterm
- Host network for Pi access
All working? You should now have a secure, load-balanced terminal interface! 🎉

View File

@ -1,476 +0,0 @@
# Socktop WebTerm - Complete Setup Guide
This guide covers the complete setup process for deploying Socktop WebTerm to your k3s cluster.
## Prerequisites
- ✅ k3s cluster running (3+ nodes recommended)
- ✅ kubectl installed on your local machine
- ✅ SSH access to all k3s nodes
- ✅ Image published to Gitea registry: `192.168.1.208:3002/jason/socktop-webterm:0.2.0`
- ✅ External NGINX Proxy Manager configured
## Step-by-Step Setup
### Step 0: Configure kubectl Context
Before deploying, make sure kubectl is configured to connect to your k3s cluster.
#### Option A: Using your k3s kubeconfig
From your k3s server node:
```bash
# On k3s server node, get the kubeconfig
sudo cat /etc/rancher/k3s/k3s.yaml
```
Copy this content to your local machine:
```bash
# On your local machine
mkdir -p ~/.kube
nano ~/.kube/config-k3s
# Paste the content and modify the server IP from 127.0.0.1 to your k3s server IP
```
Example modification:
```yaml
# Change this:
server: https://127.0.0.1:6443
# To this (use your k3s server IP):
server: https://192.168.1.101:6443
```
#### Option B: Merge with existing kubeconfig
If you already have a kubectl config:
```bash
# Backup existing config
cp ~/.kube/config ~/.kube/config.backup
# Add k3s config as a new context
export KUBECONFIG=~/.kube/config:~/.kube/config-k3s
kubectl config view --flatten > ~/.kube/config-merged
mv ~/.kube/config-merged ~/.kube/config
```
#### Verify Connection
```bash
# List available contexts
kubectl config get-contexts
# Switch to k3s context (replace with your context name)
kubectl config use-context default
# Test connection
kubectl get nodes
# You should see your k3s nodes listed
```
Expected output:
```
NAME STATUS ROLES AGE VERSION
rpi-master Ready control-plane,master 30d v1.28.2+k3s1
rpi-worker-1 Ready <none> 30d v1.28.2+k3s1
rpi-worker-2 Ready <none> 30d v1.28.2+k3s1
```
### Step 1: Configure k3s Insecure Registry
Your Gitea registry uses HTTP (not HTTPS), so you need to configure k3s to allow "insecure" registries.
#### Automated Method (Recommended)
Use the provided script to configure all nodes:
```bash
cd kubernetes
./setup-registry.sh
```
The script will:
1. Ask for your k3s node IP addresses
2. Ask for SSH username (default: ubuntu)
3. Copy the registry config to each node
4. Restart k3s services
5. Test image pulling
#### Manual Method
If the script doesn't work or you prefer manual setup:
**For each k3s node**, do the following:
1. **SSH to the node:**
```bash
ssh ubuntu@192.168.1.101 # replace with your node IP
```
2. **Create the k3s config directory:**
```bash
sudo mkdir -p /etc/rancher/k3s
```
3. **Create the registries.yaml file:**
```bash
sudo nano /etc/rancher/k3s/registries.yaml
```
4. **Paste this content:**
```yaml
mirrors:
"192.168.1.208:3002":
endpoint:
- "http://192.168.1.208:3002"
configs:
"192.168.1.208:3002":
tls:
insecure_skip_verify: true
```
5. **Save and exit** (Ctrl+O, Enter, Ctrl+X)
6. **Restart k3s:**
```bash
# On server nodes
sudo systemctl restart k3s
# On agent/worker nodes
sudo systemctl restart k3s-agent
```
7. **Verify the service is running:**
```bash
sudo systemctl status k3s # on server
sudo systemctl status k3s-agent # on agents
```
8. **Test image pull:**
```bash
sudo k3s crictl pull 192.168.1.208:3002/jason/socktop-webterm:0.2.0
```
**Repeat for ALL k3s nodes** (both server and agents).
#### Troubleshooting Registry Setup
**Problem: systemctl restart fails**
```bash
# Check logs
sudo journalctl -u k3s -n 50 # on server
sudo journalctl -u k3s-agent -n 50 # on agents
# Look for syntax errors in registries.yaml
sudo cat /etc/rancher/k3s/registries.yaml
```
**Problem: Image pull fails**
```bash
# Test registry access from node
curl http://192.168.1.208:3002/v2/
# Should return {} or a Docker registry response
```
**Problem: Permission denied**
```bash
# Ensure correct permissions
sudo chmod 644 /etc/rancher/k3s/registries.yaml
sudo chown root:root /etc/rancher/k3s/registries.yaml
```
### Step 2: Deploy to k3s
Once all nodes are configured, deploy the application:
#### Using the Automated Script
```bash
cd kubernetes
./deploy.sh
```
The script will:
1. Check kubectl connection
2. Show current context
3. Ask for target namespace (default: `default`)
4. Create namespace if needed
5. Optionally configure Pi TLS certificates
6. Deploy all manifests
7. Wait for pods to be ready
8. Show status and helpful commands
#### Manual Deployment
If you prefer to deploy manually:
```bash
# Deploy to default namespace
kubectl apply -f 01-configmap.yaml
kubectl apply -f 02-secret.yaml
kubectl apply -f 03-deployment.yaml
kubectl apply -f 04-service.yaml
kubectl apply -f 05-ingress.yaml
# Or deploy to custom namespace
kubectl create namespace socktop
kubectl apply -f . -n socktop
```
#### Verify Deployment
```bash
# Check pods
kubectl get pods -l app=socktop-webterm -n default
# Expected output (3 pods):
# NAME READY STATUS RESTARTS AGE
# socktop-webterm-xxxxxxxxxx-xxxxx 1/1 Running 0 30s
# socktop-webterm-xxxxxxxxxx-xxxxx 1/1 Running 0 30s
# socktop-webterm-xxxxxxxxxx-xxxxx 1/1 Running 0 30s
# Check service
kubectl get svc socktop-webterm -n default
# Check ingress
kubectl get ingress socktop-webterm -n default
```
#### Common Deployment Issues
**Pods stuck in ImagePullBackOff:**
- Registry not configured on all nodes
- Go back to Step 1 and verify each node
**Pods stuck in Pending:**
- Not enough resources
- Check: `kubectl describe pods -l app=socktop-webterm -n default`
**Pods in CrashLoopBackOff:**
- Check logs: `kubectl logs -l app=socktop-webterm -n default --tail=100`
### Step 3: Configure External NGINX Proxy Manager
See `NGINX-PROXY-MANAGER.md` for detailed instructions.
Quick summary:
1. **Log into NGINX Proxy Manager web UI**
2. **Create proxy host for socktop.io:**
- Domain: `socktop.io`
- Scheme: `http`
- Forward Hostname/IP: `192.168.1.101` (any k3s node IP)
- Forward Port: `8080`
- ✅ Enable WebSocket Support
- SSL: Select/create certificate
- ✅ Force SSL
3. **Repeat for www.socktop.io and origin.socktop.io**
4. **Advanced config (optional but recommended):**
```nginx
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
proxy_connect_timeout 60s;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
```
### Step 4: Test Access
1. **Test internal access (from k3s node):**
```bash
curl http://localhost:8080 -H "Host: socktop.io"
```
2. **Test external access:**
- Open browser to https://socktop.io
- Should see the webterm interface
- Check browser console (F12) for WebSocket connection
3. **Test terminal functionality:**
- Select a profile (local or a Pi node)
- Terminal should connect and be interactive
## Complete Example Walkthrough
Here's a complete example from start to finish:
```bash
# 1. Configure kubectl
export KUBECONFIG=~/.kube/config
kubectl config use-context default
kubectl get nodes # verify connection
# 2. Navigate to kubernetes directory
cd /path/to/webterm/kubernetes
# 3. Configure registry on all nodes
./setup-registry.sh
# Enter node IPs: 192.168.1.101, 192.168.1.102, 192.168.1.104
# Enter SSH user: ubuntu
# 4. Wait for script to complete (will test image pull)
# 5. Deploy to k3s
./deploy.sh
# Choose namespace: default (or create new one)
# Skip TLS cert config if you don't have Pi certs yet
# 6. Wait for deployment to complete
# 7. Verify pods are running
kubectl get pods -l app=socktop-webterm -n default
# 8. Configure NGINX Proxy Manager (see NGINX-PROXY-MANAGER.md)
# 9. Test access
curl -I https://socktop.io
# 10. Open browser and test
# https://socktop.io
```
## Kubernetes Context Quick Reference
### View Available Contexts
```bash
kubectl config get-contexts
```
### Switch Context
```bash
kubectl config use-context <context-name>
```
### View Current Context
```bash
kubectl config current-context
```
### Set Default Namespace
```bash
kubectl config set-context --current --namespace=socktop
```
### View Cluster Info
```bash
kubectl cluster-info
```
## Node Configuration Quick Reference
### Check k3s Service Status
```bash
# On server node
sudo systemctl status k3s
# On agent/worker node
sudo systemctl status k3s-agent
```
### View k3s Logs
```bash
sudo journalctl -u k3s -f # server
sudo journalctl -u k3s-agent -f # agent
```
### Verify Registry Config
```bash
sudo cat /etc/rancher/k3s/registries.yaml
```
### Test Image Pull
```bash
sudo k3s crictl pull 192.168.1.208:3002/jason/socktop-webterm:0.2.0
```
### List Images on Node
```bash
sudo k3s crictl images | grep socktop
```
## Helpful kubectl Commands
```bash
# Get all resources in namespace
kubectl get all -n default
# Describe deployment
kubectl describe deployment socktop-webterm -n default
# View pod logs
kubectl logs -l app=socktop-webterm -n default -f
# Execute command in pod
kubectl exec -it deployment/socktop-webterm -n default -- /bin/bash
# Port forward for testing
kubectl port-forward svc/socktop-webterm 8082:8082 -n default
# Then access http://localhost:8082
# Scale deployment
kubectl scale deployment socktop-webterm --replicas=5 -n default
# Restart deployment
kubectl rollout restart deployment socktop-webterm -n default
# View rollout status
kubectl rollout status deployment socktop-webterm -n default
# Delete everything
kubectl delete -f . -n default
```
## Summary Checklist
- [ ] kubectl configured and connected to k3s cluster
- [ ] Registry config copied to ALL k3s nodes
- [ ] k3s services restarted on all nodes
- [ ] Image pull tested successfully on at least one node
- [ ] Deployed to k3s using deploy.sh or manual kubectl apply
- [ ] Pods showing as Running (3/3)
- [ ] Service has endpoints
- [ ] Ingress created successfully
- [ ] NGINX Proxy Manager configured with 3 proxy hosts
- [ ] DNS pointing to NGINX Proxy Manager
- [ ] Can access https://socktop.io in browser
- [ ] WebSocket connections working
- [ ] Terminal sessions functional
## Next Steps
Once deployed successfully:
1. **Monitor Performance**: `kubectl top pods -l app=socktop-webterm -n default`
2. **Check Logs**: Look for any errors or warnings
3. **Test Load Balancing**: Verify traffic distributes across 3 pods
4. **Configure Monitoring**: Set up Prometheus/Grafana if desired
5. **Add Alerts**: Configure alerts for pod failures
## Getting Help
If you encounter issues:
1. Check `TROUBLESHOOTING.md` (if exists) or `README.md`
2. View pod logs: `kubectl logs -l app=socktop-webterm -n default`
3. Describe pods: `kubectl describe pods -l app=socktop-webterm -n default`
4. Check events: `kubectl get events -n default --sort-by='.lastTimestamp'`
5. Verify registry config on all nodes
6. Check NGINX Proxy Manager logs
## Additional Resources
- `QUICKSTART.md` - Fast deployment guide
- `README.md` - Comprehensive documentation
- `CHECKLIST.md` - Pre-deployment verification
- `NGINX-PROXY-MANAGER.md` - Proxy configuration guide
- `INDEX.md` - File overview and navigation

Binary file not shown.

Before

Width:  |  Height:  |  Size: 478 KiB

View File

@ -1,129 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>xterm.js 5.3 Test</title>
<link
rel="stylesheet"
href="node_modules/@xterm/xterm/css/xterm.css"
/>
<script src="node_modules/@xterm/xterm/lib/xterm.js"></script>
<script src="node_modules/@xterm/addon-fit/lib/addon-fit.js"></script>
<style>
body {
margin: 0;
padding: 20px;
font-family: Arial, sans-serif;
background: #1e1e1e;
color: #fff;
}
h1 {
margin-bottom: 10px;
}
.info {
margin-bottom: 20px;
padding: 10px;
background: #2d2d2d;
border-radius: 4px;
}
#terminal {
width: 100%;
height: 500px;
border: 1px solid #444;
border-radius: 4px;
}
</style>
</head>
<body>
<h1>xterm.js 5.3 Test Page</h1>
<div class="info">
<p><strong>xterm.js version:</strong> <span id="version">Loading...</span></p>
<p><strong>FitAddon:</strong> <span id="fit-status">Loading...</span></p>
<p><strong>Test Status:</strong> <span id="test-status">Initializing...</span></p>
</div>
<div id="terminal"></div>
<script>
try {
// Check if Terminal is available
if (typeof Terminal === 'undefined') {
document.getElementById('test-status').textContent = 'FAILED - Terminal not loaded';
throw new Error('Terminal not loaded');
}
// Create terminal instance
const term = new Terminal({
cursorBlink: true,
fontSize: 14,
fontFamily: 'Menlo, Monaco, "Courier New", monospace',
theme: {
background: '#1e1e1e',
foreground: '#d4d4d4'
}
});
// Check FitAddon
if (typeof FitAddon === 'undefined') {
document.getElementById('fit-status').textContent = 'FAILED - FitAddon not loaded';
throw new Error('FitAddon not loaded');
}
// Load FitAddon
const fitAddon = new FitAddon.FitAddon();
term.loadAddon(fitAddon);
document.getElementById('fit-status').textContent = 'OK - FitAddon loaded successfully';
// Open terminal
const terminalElement = document.getElementById('terminal');
term.open(terminalElement);
// Fit terminal to container
fitAddon.fit();
// Display version info
// xterm 5.3 doesn't expose version directly, so we'll check for key features
document.getElementById('version').textContent = '5.3.0 (confirmed by API)';
// Write welcome message
term.writeln('\x1b[1;32mxterm.js 5.3 Test Terminal\x1b[0m');
term.writeln('');
term.writeln('This terminal demonstrates the new xterm.js 5.3 API:');
term.writeln('');
term.writeln('✓ New loadAddon() method (replaces applyAddon)');
term.writeln('✓ @xterm/xterm package (replaces xterm)');
term.writeln('✓ @xterm/addon-fit package');
term.writeln('✓ Modern ITerminalAddon interface');
term.writeln('');
term.writeln('Terminal dimensions: ' + term.cols + 'x' + term.rows);
term.writeln('');
term.writeln('\x1b[1;36mType something to test input:\x1b[0m ');
// Handle input
term.onData((data) => {
term.write(data);
});
// Handle resize
window.addEventListener('resize', () => {
fitAddon.fit();
console.log('Terminal resized to: ' + term.cols + 'x' + term.rows);
});
document.getElementById('test-status').textContent = 'SUCCESS - All tests passed!';
document.getElementById('test-status').style.color = '#4ec9b0';
} catch (error) {
console.error('Test failed:', error);
document.getElementById('test-status').textContent = 'FAILED - ' + error.message;
document.getElementById('test-status').style.color = '#f48771';
}
</script>
</body>
</html>

BIN
tmp_bind

Binary file not shown.

View File

@ -1,7 +0,0 @@
use std::net::TcpListener;
fn main(){
match TcpListener::bind("0.0.0.0:8082") {
Ok(_) => println!("std TcpListener bind ok"),
Err(e) => println!("std TcpListener bind failed: {}", e),
}
}