From 42273ab2faa4f6ac28565262a8916093b670c423 Mon Sep 17 00:00:00 2001 From: Silberengel Date: Sun, 21 Sep 2025 08:57:27 +0200 Subject: [PATCH] Add Docker deployment and Apache reverse proxy setup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ๐Ÿณ Docker Implementation: - Add Dockerfile with Alpine Linux (46MB image) - Add docker-compose.yml with production-ready config - Add manage-relay.sh for easy local management - Add stella-relay.service for systemd auto-start - Published images: silberengel/orly-relay:latest, :v1, :v2 ๐Ÿ”ง Apache Reverse Proxy: - Add comprehensive Apache proxy guide for Plesk and standard Apache - Add working WebSocket proxy configuration (ws:// not http://) - Add troubleshooting guide based on real deployment experience - Add debug-websocket.sh script for systematic diagnosis --- APACHE-PROXY-GUIDE.md | 364 ++++++++++++++++++++++++++++++++++++++++++ DOCKER.md | 188 ++++++++++++++++++++++ Dockerfile | 78 +++++++++ SERVICE-WORKER-FIX.md | 101 ++++++++++++ WEBSOCKET-DEBUG.md | 109 +++++++++++++ debug-websocket.sh | 116 ++++++++++++++ docker-compose.yml | 93 +++++++++++ manage-relay.sh | 89 +++++++++++ stella-relay.service | 39 +++++ 9 files changed, 1177 insertions(+) create mode 100644 APACHE-PROXY-GUIDE.md create mode 100644 DOCKER.md create mode 100644 Dockerfile create mode 100644 SERVICE-WORKER-FIX.md create mode 100644 WEBSOCKET-DEBUG.md create mode 100755 debug-websocket.sh create mode 100644 docker-compose.yml create mode 100755 manage-relay.sh create mode 100644 stella-relay.service diff --git a/APACHE-PROXY-GUIDE.md b/APACHE-PROXY-GUIDE.md new file mode 100644 index 0000000..1fbfb13 --- /dev/null +++ b/APACHE-PROXY-GUIDE.md @@ -0,0 +1,364 @@ +# Apache Reverse Proxy Guide for Docker Apps + +**Complete guide for WebSocket-enabled applications - covers both Plesk and Standard Apache** +**Updated with real-world troubleshooting solutions** + +## ๐ŸŽฏ **What This Solves** +- WebSocket connection failures (`NS_ERROR_WEBSOCKET_CONNECTION_REFUSED`) +- Nostr relay connectivity issues (`HTTP 426` instead of WebSocket upgrade) +- Docker container proxy configuration +- SSL certificate integration +- Plesk configuration conflicts and virtual host precedence issues + +## ๐Ÿณ **Step 1: Deploy Your Docker Application** + +### **For Stella's Orly Relay:** +```bash +# Pull and run the relay +docker run -d \ + --name stella-relay \ + --restart unless-stopped \ + -p 127.0.0.1:7777:7777 \ + -v /data/orly-relay:/data \ + -e ORLY_OWNERS=npub1v30tsz9vw6ylpz63g0a702nj3xa26t3m7p5us8f2y2sd8v6cnsvq465zjx \ + -e ORLY_ADMINS=npub1v30tsz9vw6ylpz63g0a702nj3xa26t3m7p5us8f2y2sd8v6cnsvq465zjx,npub1l5sga6xg72phsz5422ykujprejwud075ggrr3z2hwyrfgr7eylqstegx9z \ + silberengel/orly-relay:latest + +# Test the relay +curl -I http://127.0.0.1:7777 +# Should return: HTTP/1.1 426 Upgrade Required +``` + +### **For Web Apps (like Jumble):** +```bash +# Run with fixed port for easier proxy setup +docker run -d \ + --name jumble-app \ + --restart unless-stopped \ + -p 127.0.0.1:3000:80 \ + -e NODE_ENV=production \ + silberengel/imwald-jumble:latest + +# Test the app +curl -I http://127.0.0.1:3000 +``` + +## ๐Ÿ”ง **Step 2A: PLESK Configuration** + +### **For Your Friend's Standard Apache Setup:** + +**Tell your friend to create `/etc/apache2/sites-available/domain.conf`:** + +```apache + + ServerName your-domain.com + + # SSL Configuration (Let's Encrypt) + SSLEngine on + SSLCertificateFile /etc/letsencrypt/live/your-domain.com/fullchain.pem + SSLCertificateKeyFile /etc/letsencrypt/live/your-domain.com/privkey.pem + + # Enable required modules first: + # sudo a2enmod proxy proxy_http proxy_wstunnel rewrite headers ssl + + # Proxy settings + ProxyPreserveHost On + ProxyRequests Off + + # WebSocket upgrade handling - CRITICAL for apps with WebSockets + RewriteEngine On + RewriteCond %{HTTP:Upgrade} websocket [NC] + RewriteCond %{HTTP:Connection} upgrade [NC] + RewriteRule ^/?(.*) "ws://127.0.0.1:PORT/$1" [P,L] + + # Regular HTTP proxy + ProxyPass / http://127.0.0.1:PORT/ + ProxyPassReverse / http://127.0.0.1:PORT/ + + # Headers for modern web apps + Header always set X-Forwarded-Proto "https" + Header always set X-Forwarded-Port "443" + Header always set X-Forwarded-For %{REMOTE_ADDR}s + + # Security headers + Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains" + Header always set X-Content-Type-Options nosniff + Header always set X-Frame-Options SAMEORIGIN + + +# Redirect HTTP to HTTPS + + ServerName your-domain.com + Redirect permanent / https://your-domain.com/ + +``` + +**Then enable it:** +```bash +sudo a2ensite domain.conf +sudo systemctl reload apache2 +``` + +### **For Plesk Users (You):** + +โš ๏ธ **Important**: Plesk often doesn't apply Apache directives correctly through the interface. If the interface method fails, use the "Direct Apache Override" method below. + +#### **Method 1: Plesk Interface (Try First)** + +1. **Go to Plesk** โ†’ Websites & Domains โ†’ **your-domain.com** +2. **Click "Apache & nginx Settings"** +3. **DISABLE nginx** (uncheck "Proxy mode" and "Smart static files processing") +4. **Clear HTTP section** (leave empty) +5. **In HTTPS section, add:** + +**For Nostr Relay (port 7777):** +```apache +ProxyRequests Off +ProxyPreserveHost On +ProxyPass / ws://127.0.0.1:7777/ +ProxyPassReverse / ws://127.0.0.1:7777/ +Header always set Access-Control-Allow-Origin "*" +``` + +6. **Click "Apply"** and wait 60 seconds + +#### **Method 2: Direct Apache Override (If Plesk Interface Fails)** + +If Plesk doesn't apply your configuration (common issue), bypass it entirely: + +```bash +# Create direct Apache override +sudo tee /etc/apache2/conf-available/relay-override.conf << 'EOF' + + ServerName your-domain.com + ServerAlias www.your-domain.com + ServerAlias ipv4.your-domain.com + + SSLEngine on + SSLCertificateFile /etc/letsencrypt/live/your-domain.com/fullchain.pem + SSLCertificateKeyFile /etc/letsencrypt/live/your-domain.com/privkey.pem + + DocumentRoot /var/www/relay + + # For Nostr relay - proxy everything to WebSocket + ProxyRequests Off + ProxyPreserveHost On + ProxyPass / ws://127.0.0.1:7777/ + ProxyPassReverse / ws://127.0.0.1:7777/ + + # CORS headers + Header always set Access-Control-Allow-Origin "*" + Header always set Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, Authorization" + + # Logging + ErrorLog /var/log/apache2/relay-error.log + CustomLog /var/log/apache2/relay-access.log combined + +EOF + +# Enable the override +sudo a2enconf relay-override +sudo mkdir -p /var/www/relay +sudo systemctl restart apache2 + +# Remove Plesk config if it conflicts +sudo rm /etc/apache2/plesk.conf.d/vhosts/your-domain.com.conf +``` + +#### **Method 3: Debugging Plesk Issues** + +If configurations aren't being applied: + +```bash +# Check if Plesk applied your config +grep -E "(ProxyPass|proxy)" /etc/apache2/plesk.conf.d/vhosts/your-domain.com.conf + +# Check virtual host precedence +apache2ctl -S | grep your-domain.com + +# Check Apache modules +apache2ctl -M | grep -E "(proxy|rewrite)" +``` + +#### **For Web Apps (port 3000 or 32768):** +```apache +ProxyPreserveHost On +ProxyRequests Off + +# WebSocket upgrade handling +RewriteEngine On +RewriteCond %{HTTP:Upgrade} websocket [NC] +RewriteCond %{HTTP:Connection} upgrade [NC] +RewriteRule ^/?(.*) "ws://127.0.0.1:32768/$1" [P,L] + +# Regular HTTP proxy +ProxyPass / http://127.0.0.1:32768/ +ProxyPassReverse / http://127.0.0.1:32768/ + +# Headers +ProxyAddHeaders On +Header always set X-Forwarded-Proto "https" +Header always set X-Forwarded-Port "443" +``` + +### **Method B: Direct Apache Override (RECOMMENDED for Plesk)** + +โš ๏ธ **Use this if Plesk interface doesn't work** (common issue): + +```bash +# Create direct Apache override with your server's IP +sudo tee /etc/apache2/conf-available/relay-override.conf << 'EOF' + + ServerName your-domain.com + ServerAlias www.your-domain.com + ServerAlias ipv4.your-domain.com + + SSLEngine on + SSLCertificateFile /etc/letsencrypt/live/your-domain.com/fullchain.pem + SSLCertificateKeyFile /etc/letsencrypt/live/your-domain.com/privkey.pem + + DocumentRoot /var/www/relay + + # For Nostr relay - proxy everything to WebSocket + ProxyRequests Off + ProxyPreserveHost On + ProxyPass / ws://127.0.0.1:7777/ + ProxyPassReverse / ws://127.0.0.1:7777/ + + # CORS headers + Header always set Access-Control-Allow-Origin "*" + + # Logging + ErrorLog /var/log/apache2/relay-error.log + CustomLog /var/log/apache2/relay-access.log combined + +EOF + +# Enable override and create directory +sudo a2enconf relay-override +sudo mkdir -p /var/www/relay +sudo systemctl restart apache2 + +# Remove conflicting Plesk config if needed +sudo rm /etc/apache2/plesk.conf.d/vhosts/your-domain.com.conf +``` + +## โšก **Step 3: Enable Required Modules** + +In Plesk, you might need to enable modules. SSH to your server: + +```bash +# Enable Apache modules +sudo a2enmod proxy +sudo a2enmod proxy_http +sudo a2enmod proxy_wstunnel +sudo a2enmod rewrite +sudo systemctl restart apache2 +``` + +## โšก **Step 4: Alternative - Nginx in Plesk** + +If Apache keeps giving issues, switch to Nginx in Plesk: + +1. Go to Plesk โ†’ Websites & Domains โ†’ orly-relay.imwald.eu +2. Click "Apache & nginx Settings" +3. Enable "nginx" and set it to serve static files +4. In "Additional nginx directives" add: + +```nginx +location / { + proxy_pass http://127.0.0.1:7777; + 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; +} +``` + +## ๐Ÿงช **Testing** + +After making changes: + +1. **Apply settings** in Plesk +2. **Wait 30 seconds** for changes to take effect +3. **Test WebSocket**: + ```bash + # From your server + echo '["REQ","test",{}]' | websocat wss://orly-relay.imwald.eu/ + ``` + +## ๐ŸŽฏ **Expected Result** + +- โœ… No more "websocket error" in browser console +- โœ… `wss://orly-relay.imwald.eu/` connects successfully +- โœ… Jumble app can publish notes + +## ๐Ÿšจ **Real-World Troubleshooting Guide** + +*Based on actual deployment experience with Plesk and WebSocket issues* + +### **Critical Issues & Solutions:** + +#### **๐Ÿ”ด HTTP 503 Service Unavailable** +- **Cause**: Docker container not running +- **Check**: `docker ps | grep relay` +- **Fix**: `docker start container-name` + +#### **๐Ÿ”ด HTTP 426 Instead of WebSocket Upgrade** +- **Cause**: Apache using `http://` proxy instead of `ws://` +- **Fix**: Use `ProxyPass / ws://127.0.0.1:7777/` (not `http://`) + +#### **๐Ÿ”ด Plesk Configuration Not Applied** +- **Symptom**: Config not in `/etc/apache2/plesk.conf.d/vhosts/domain.conf` +- **Solution**: Use Direct Apache Override method (bypass Plesk interface) + +#### **๐Ÿ”ด Virtual Host Conflicts** +- **Check**: `apache2ctl -S | grep domain.com` +- **Fix**: Remove Plesk config: `sudo rm /etc/apache2/plesk.conf.d/vhosts/domain.conf` + +#### **๐Ÿ”ด Nginx Intercepting (Plesk)** +- **Symptom**: Response shows `Server: nginx` +- **Fix**: Disable nginx in Plesk settings + +### **Debug Commands:** +```bash +# Essential debugging +docker ps | grep relay # Container running? +curl -I http://127.0.0.1:7777 # Local relay (should return 426) +apache2ctl -S | grep domain.com # Virtual host precedence +grep ProxyPass /etc/apache2/plesk.conf.d/vhosts/domain.conf # Config applied? + +# WebSocket testing +echo '["REQ","test",{}]' | websocat wss://domain.com/ # Root path +echo '["REQ","test",{}]' | websocat wss://domain.com/ws/ # /ws/ path +``` + +### **Working Solution (Proven):** +```apache + + ServerName domain.com + SSLEngine on + SSLCertificateFile /etc/letsencrypt/live/domain.com/fullchain.pem + SSLCertificateKeyFile /etc/letsencrypt/live/domain.com/privkey.pem + DocumentRoot /var/www/relay + + # Direct WebSocket proxy - this is the key! + ProxyRequests Off + ProxyPreserveHost On + ProxyPass / ws://127.0.0.1:7777/ + ProxyPassReverse / ws://127.0.0.1:7777/ + + Header always set Access-Control-Allow-Origin "*" + +``` + +--- + +**Key Lessons**: +1. Plesk interface often fails to apply Apache directives +2. Use `ws://` proxy for Nostr relays, not `http://` +3. Direct Apache config files are more reliable than Plesk interface +4. Always check virtual host precedence with `apache2ctl -S` diff --git a/DOCKER.md b/DOCKER.md new file mode 100644 index 0000000..8e23e4a --- /dev/null +++ b/DOCKER.md @@ -0,0 +1,188 @@ +# Docker Deployment Guide + +## Quick Start + +### 1. Basic Relay Setup + +```bash +# Build and start the relay +docker-compose up -d + +# View logs +docker-compose logs -f stella-relay + +# Stop the relay +docker-compose down +``` + +### 2. With Nginx Proxy (for SSL/domain setup) + +```bash +# Start relay with nginx proxy +docker-compose --profile proxy up -d + +# Configure SSL certificates in nginx/ssl/ +# Then update nginx/nginx.conf to enable HTTPS +``` + +## Configuration + +### Environment Variables + +Copy `env.example` to `.env` and customize: + +```bash +cp env.example .env +# Edit .env with your settings +``` + +Key settings: +- `ORLY_OWNERS`: Owner npubs (comma-separated, full control) +- `ORLY_ADMINS`: Admin npubs (comma-separated, deletion permissions) +- `ORLY_PORT`: Port to listen on (default: 7777) +- `ORLY_MAX_CONNECTIONS`: Max concurrent connections +- `ORLY_CONCURRENT_WORKERS`: CPU cores for concurrent processing (0 = auto) + +### Data Persistence + +The relay data is stored in `./data` directory which is mounted as a volume. + +### Performance Tuning + +Based on the v0.4.8 optimizations: +- Concurrent event publishing using all CPU cores +- Optimized BadgerDB access patterns +- Configurable batch sizes and cache settings + +## Development + +### Local Build + +```bash +# Pull the latest image (recommended) +docker pull silberengel/orly-relay:latest + +# Or build locally if needed +docker build -t silberengel/orly-relay:latest . + +# Run with custom settings +docker run -p 7777:7777 -v $(pwd)/data:/data silberengel/orly-relay:latest +``` + +### Testing + +```bash +# Test WebSocket connection +websocat ws://localhost:7777 + +# Run stress tests (if available in cmd/stresstest) +go run ./cmd/stresstest -relay ws://localhost:7777 +``` + +## Production Deployment + +### SSL Setup + +1. Get SSL certificates (Let's Encrypt recommended) +2. Place certificates in `nginx/ssl/` +3. Update `nginx/nginx.conf` to enable HTTPS +4. Start with proxy profile: `docker-compose --profile proxy up -d` + +### Monitoring + +- Health checks are configured for both services +- Logs are rotated (max 10MB, 3 files) +- Resource limits are set to prevent runaway processes + +### Security + +- Runs as non-root user (uid 1000) +- Rate limiting configured in nginx +- Configurable authentication and event size limits + +## Troubleshooting + +### Common Issues (Real-World Experience) + +#### **Container Issues:** +1. **Port already in use**: Change `ORLY_PORT` in docker-compose.yml +2. **Permission denied**: Ensure `./data` directory is writable +3. **Container won't start**: Check logs with `docker logs container-name` + +#### **WebSocket Issues:** +4. **HTTP 426 instead of WebSocket upgrade**: + - Use `ws://127.0.0.1:7777` in proxy config, not `http://` + - Ensure `proxy_wstunnel` module is enabled +5. **Connection refused in browser but works with websocat**: + - Clear browser cache and service workers + - Try incognito mode + - Add CORS headers to Apache/nginx config + +#### **Plesk-Specific Issues:** +6. **Plesk not applying Apache directives**: + - Check if config appears in `/etc/apache2/plesk.conf.d/vhosts/domain.conf` + - Use direct Apache override if Plesk interface fails +7. **Virtual host conflicts**: + - Check precedence with `apache2ctl -S` + - Remove conflicting Plesk configs if needed + +#### **SSL Certificate Issues:** +8. **Self-signed certificate after Let's Encrypt**: + - Plesk might not be using the correct certificate + - Import Let's Encrypt certs into Plesk or use direct Apache config + +### Debug Commands + +```bash +# Container debugging +docker ps | grep relay +docker logs stella-relay +curl -I http://127.0.0.1:7777 # Should return HTTP 426 + +# WebSocket testing +echo '["REQ","test",{}]' | websocat wss://domain.com/ +echo '["REQ","test",{}]' | websocat wss://domain.com/ws/ + +# Apache debugging (for reverse proxy issues) +apache2ctl -S | grep domain.com +apache2ctl -M | grep -E "(proxy|rewrite)" +grep ProxyPass /etc/apache2/plesk.conf.d/vhosts/domain.conf +``` + +### Logs + +```bash +# View relay logs +docker-compose logs -f stella-relay + +# View nginx logs (if using proxy) +docker-compose logs -f nginx + +# Apache logs (for reverse proxy debugging) +sudo tail -f /var/log/apache2/error.log +sudo tail -f /var/log/apache2/domain-error.log +``` + +### Working Reverse Proxy Config + +**For Apache (direct config file):** +```apache + + ServerName domain.com + SSLEngine on + SSLCertificateFile /etc/letsencrypt/live/domain.com/fullchain.pem + SSLCertificateKeyFile /etc/letsencrypt/live/domain.com/privkey.pem + + # Direct WebSocket proxy for Nostr relay + ProxyRequests Off + ProxyPreserveHost On + ProxyPass / ws://127.0.0.1:7777/ + ProxyPassReverse / ws://127.0.0.1:7777/ + + Header always set Access-Control-Allow-Origin "*" + +``` + +--- + +*Crafted for Stella's digital forest* ๐ŸŒฒ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..003d7f6 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,78 @@ +# Dockerfile for Stella's Nostr Relay (next.orly.dev) +# Owner: npub1v30tsz9vw6ylpz63g0a702nj3xa26t3m7p5us8f2y2sd8v6cnsvq465zjx + +FROM golang:alpine AS builder + +# Install build dependencies +RUN apk add --no-cache \ + git \ + build-base \ + autoconf \ + automake \ + libtool \ + pkgconfig + +# Install secp256k1 library from Alpine packages +RUN apk add --no-cache libsecp256k1-dev + +# Set working directory +WORKDIR /build + +# Copy go modules first (for better caching) +COPY go.mod go.sum ./ +RUN go mod download + +# Copy source code +COPY . . + +# Build the relay with optimizations from v0.4.8 +RUN CGO_ENABLED=1 GOOS=linux go build -ldflags "-w -s" -o relay . + +# Create non-root user for security +RUN adduser -D -u 1000 stella && \ + chown -R 1000:1000 /build + +# Final stage - minimal runtime image +FROM alpine:latest + +# Install only runtime dependencies +RUN apk add --no-cache \ + ca-certificates \ + curl \ + libsecp256k1 \ + libsecp256k1-dev + +WORKDIR /app + +# Copy binary from builder +COPY --from=builder /build/relay /app/relay + +# Create runtime user and directories +RUN adduser -D -u 1000 stella && \ + mkdir -p /data /profiles /app && \ + chown -R 1000:1000 /data /profiles /app + +# Expose the relay port +EXPOSE 7777 + +# Set environment variables for Stella's relay +ENV ORLY_DATA_DIR=/data +ENV ORLY_LISTEN=0.0.0.0 +ENV ORLY_PORT=7777 +ENV ORLY_LOG_LEVEL=info +ENV ORLY_MAX_CONNECTIONS=1000 +ENV ORLY_OWNERS=npub1v30tsz9vw6ylpz63g0a702nj3xa26t3m7p5us8f2y2sd8v6cnsvq465zjx +ENV ORLY_ADMINS=npub1v30tsz9vw6ylpz63g0a702nj3xa26t3m7p5us8f2y2sd8v6cnsvq465zjx,npub1l5sga6xg72phsz5422ykujprejwud075ggrr3z2hwyrfgr7eylqstegx9z + +# Health check to ensure relay is responding +HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ + CMD sh -c "code=\$(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:7777 || echo 000); echo \$code | grep -E '^(101|200|400|404|426)$' >/dev/null || exit 1" + +# Create volume for persistent data +VOLUME ["/data"] + +# Drop privileges and run as stella user +USER 1000:1000 + +# Run Stella's Nostr relay +CMD ["/app/relay"] diff --git a/SERVICE-WORKER-FIX.md b/SERVICE-WORKER-FIX.md new file mode 100644 index 0000000..981a9ac --- /dev/null +++ b/SERVICE-WORKER-FIX.md @@ -0,0 +1,101 @@ +# Service Worker Certificate Caching Fix + +## ๐Ÿšจ **Problem** +When accessing Jumble from the ImWald landing page, the service worker serves a cached self-signed certificate instead of the new Let's Encrypt certificate. + +## โšก **Solutions** + +### **Option 1: Force Service Worker Update** +Add this to your Jumble app's service worker or main JavaScript: + +```javascript +// Force service worker update and certificate refresh +if ('serviceWorker' in navigator) { + navigator.serviceWorker.getRegistrations().then(function(registrations) { + for(let registration of registrations) { + registration.update(); // Force update + } + }); +} + +// Clear all caches on certificate update +if ('caches' in window) { + caches.keys().then(function(names) { + for (let name of names) { + caches.delete(name); + } + }); +} +``` + +### **Option 2: Update Service Worker Cache Strategy** +In your service worker file, add cache busting for SSL-sensitive requests: + +```javascript +// In your service worker +self.addEventListener('fetch', function(event) { + // Don't cache HTTPS requests that might have certificate issues + if (event.request.url.startsWith('https://') && + event.request.url.includes('imwald.eu')) { + event.respondWith( + fetch(event.request, { cache: 'no-store' }) + ); + return; + } + + // Your existing fetch handling... +}); +``` + +### **Option 3: Version Your Service Worker** +Update your service worker with a new version number: + +```javascript +// At the top of your service worker +const CACHE_VERSION = 'v2.0.1'; // Increment this when certificates change +const CACHE_NAME = `jumble-cache-${CACHE_VERSION}`; + +// Clear old caches +self.addEventListener('activate', function(event) { + event.waitUntil( + caches.keys().then(function(cacheNames) { + return Promise.all( + cacheNames.map(function(cacheName) { + if (cacheName !== CACHE_NAME) { + return caches.delete(cacheName); + } + }) + ); + }) + ); +}); +``` + +### **Option 4: Add Cache Headers** +In your Plesk Apache config for Jumble, add: + +```apache +# Prevent service worker from caching SSL-sensitive content +Header always set Cache-Control "no-cache, no-store, must-revalidate" +Header always set Pragma "no-cache" +Header always set Expires "0" + +# Only for service worker file + + Header always set Cache-Control "no-cache, no-store, must-revalidate" + +``` + +## ๐Ÿงน **Immediate User Fix** + +For users experiencing the certificate issue: + +1. **Clear browser data** for jumble.imwald.eu +2. **Unregister service worker**: + - F12 โ†’ Application โ†’ Service Workers โ†’ Unregister +3. **Hard refresh**: Ctrl+Shift+R +4. **Or use incognito mode** to test + +--- + +This will prevent the service worker from serving stale certificate data. diff --git a/WEBSOCKET-DEBUG.md b/WEBSOCKET-DEBUG.md new file mode 100644 index 0000000..97ebd14 --- /dev/null +++ b/WEBSOCKET-DEBUG.md @@ -0,0 +1,109 @@ +# WebSocket Connection Debug Guide + +## ๐Ÿšจ **Current Issue** +`wss://orly-relay.imwald.eu/` returns `NS_ERROR_WEBSOCKET_CONNECTION_REFUSED` + +## ๐Ÿ” **Debug Steps** + +### **Step 1: Verify Relay is Running** +```bash +# On your server +curl -I http://127.0.0.1:7777 +# Should return: HTTP/1.1 426 Upgrade Required + +docker ps | grep stella +# Should show running container +``` + +### **Step 2: Test Apache Modules** +```bash +# Check if WebSocket modules are enabled +apache2ctl -M | grep -E "(proxy|rewrite)" + +# If missing, enable them: +sudo a2enmod proxy +sudo a2enmod proxy_http +sudo a2enmod proxy_wstunnel +sudo a2enmod rewrite +sudo a2enmod headers +sudo systemctl restart apache2 +``` + +### **Step 3: Check Apache Configuration** +```bash +# Check what Plesk generated +sudo cat /etc/apache2/plesk.conf.d/vhosts/orly-relay.imwald.eu.conf + +# Look for proxy and rewrite rules +grep -E "(Proxy|Rewrite)" /etc/apache2/plesk.conf.d/vhosts/orly-relay.imwald.eu.conf +``` + +### **Step 4: Test Direct WebSocket Connection** +```bash +# Test if the issue is Apache or the relay itself +echo '["REQ","test",{}]' | websocat ws://127.0.0.1:7777/ + +# If that works, the issue is Apache proxy +# If that fails, the issue is the relay +``` + +### **Step 5: Check Apache Error Logs** +```bash +# Watch Apache errors in real-time +sudo tail -f /var/log/apache2/error.log + +# Then try connecting to wss://orly-relay.imwald.eu/ and see what errors appear +``` + +## ๐Ÿ”ง **Specific Plesk Fix** + +Based on your current status, try this **exact configuration** in Plesk: + +### **Go to Apache & nginx Settings for orly-relay.imwald.eu:** + +**Clear both HTTP and HTTPS sections, then add to HTTPS:** + +```apache +# Enable proxy +ProxyRequests Off +ProxyPreserveHost On + +# WebSocket handling - the key part +RewriteEngine On +RewriteCond %{HTTP:Upgrade} =websocket [NC] +RewriteCond %{HTTP:Connection} upgrade [NC] +RewriteRule /(.*) ws://127.0.0.1:7777/$1 [P,L] + +# Fallback for regular HTTP +RewriteCond %{HTTP:Upgrade} !=websocket [NC] +RewriteRule /(.*) http://127.0.0.1:7777/$1 [P,L] + +# Headers +ProxyAddHeaders On +``` + +### **Alternative Simpler Version:** +If the above doesn't work, try just: + +```apache +ProxyPass / http://127.0.0.1:7777/ +ProxyPassReverse / http://127.0.0.1:7777/ +ProxyPass /ws ws://127.0.0.1:7777/ +ProxyPassReverse /ws ws://127.0.0.1:7777/ +``` + +## ๐Ÿงช **Testing Commands** + +```bash +# Test the WebSocket after each change +echo '["REQ","test",{}]' | websocat wss://orly-relay.imwald.eu/ + +# Check what's actually being served +curl -v https://orly-relay.imwald.eu/ 2>&1 | grep -E "(HTTP|upgrade|connection)" +``` + +## ๐ŸŽฏ **Expected Fix** + +The issue is likely that Apache isn't properly handling the WebSocket upgrade request. The `proxy_wstunnel` module and correct rewrite rules should fix this. + +Try the **simpler ProxyPass version first** - it's often more reliable in Plesk environments. diff --git a/debug-websocket.sh b/debug-websocket.sh new file mode 100755 index 0000000..4445281 --- /dev/null +++ b/debug-websocket.sh @@ -0,0 +1,116 @@ +#!/bin/bash +# WebSocket Debug Script for Stella's Orly Relay + +echo "๐Ÿ” Debugging WebSocket Connection for orly-relay.imwald.eu" +echo "==================================================" + +echo "" +echo "๐Ÿ“‹ Step 1: Check if relay container is running" +echo "----------------------------------------------" +docker ps | grep -E "(stella|relay|orly)" || echo "โŒ No relay containers found" + +echo "" +echo "๐Ÿ“‹ Step 2: Test local relay connection" +echo "--------------------------------------" +if curl -s -I http://127.0.0.1:7777 | grep -q "426"; then + echo "โœ… Local relay responding correctly (HTTP 426)" +else + echo "โŒ Local relay not responding correctly" + curl -I http://127.0.0.1:7777 +fi + +echo "" +echo "๐Ÿ“‹ Step 3: Check Apache modules" +echo "------------------------------" +if apache2ctl -M 2>/dev/null | grep -q "proxy_wstunnel"; then + echo "โœ… proxy_wstunnel module enabled" +else + echo "โŒ proxy_wstunnel module NOT enabled" + echo "Run: sudo a2enmod proxy_wstunnel" +fi + +if apache2ctl -M 2>/dev/null | grep -q "rewrite"; then + echo "โœ… rewrite module enabled" +else + echo "โŒ rewrite module NOT enabled" + echo "Run: sudo a2enmod rewrite" +fi + +echo "" +echo "๐Ÿ“‹ Step 4: Check Plesk Apache configuration" +echo "------------------------------------------" +if [ -f "/etc/apache2/plesk.conf.d/vhosts/orly-relay.imwald.eu.conf" ]; then + echo "โœ… Plesk config file exists" + echo "Current proxy configuration:" + grep -E "(Proxy|Rewrite|proxy|rewrite)" /etc/apache2/plesk.conf.d/vhosts/orly-relay.imwald.eu.conf || echo "โŒ No proxy/rewrite rules found" +else + echo "โŒ Plesk config file not found" +fi + +echo "" +echo "๐Ÿ“‹ Step 5: Test WebSocket connections" +echo "------------------------------------" + +# Test with curl first (simpler) +echo "Testing HTTP upgrade request to local relay..." +if curl -s -I -H "Connection: Upgrade" -H "Upgrade: websocket" http://127.0.0.1:7777 | grep -q "426\|101"; then + echo "โœ… Local relay accepts upgrade requests" +else + echo "โŒ Local relay doesn't accept upgrade requests" +fi + +echo "Testing HTTP upgrade request to remote relay..." +if curl -s -I -H "Connection: Upgrade" -H "Upgrade: websocket" https://orly-relay.imwald.eu | grep -q "426\|101"; then + echo "โœ… Remote relay accepts upgrade requests" +else + echo "โŒ Remote relay doesn't accept upgrade requests" + echo "This indicates Apache proxy issue" +fi + +# Try to install websocat if not available +if ! command -v websocat >/dev/null 2>&1; then + echo "" + echo "๐Ÿ“ฅ Installing websocat for proper WebSocket testing..." + if wget -q https://github.com/vi/websocat/releases/download/v1.12.0/websocat.x86_64-unknown-linux-musl -O websocat 2>/dev/null; then + chmod +x websocat + echo "โœ… websocat installed" + else + echo "โŒ Could not install websocat (no internet or wget issue)" + echo "Manual install: wget https://github.com/vi/websocat/releases/download/v1.12.0/websocat.x86_64-unknown-linux-musl -O websocat && chmod +x websocat" + fi +fi + +# Test with websocat if available +if command -v ./websocat >/dev/null 2>&1; then + echo "" + echo "Testing actual WebSocket connection..." + echo "Local WebSocket test:" + timeout 3 bash -c 'echo "[\"REQ\",\"test\",{}]" | ./websocat ws://127.0.0.1:7777/' 2>/dev/null || echo "โŒ Local WebSocket failed" + + echo "Remote WebSocket test (ignoring SSL):" + timeout 3 bash -c 'echo "[\"REQ\",\"test\",{}]" | ./websocat --insecure wss://orly-relay.imwald.eu/' 2>/dev/null || echo "โŒ Remote WebSocket failed" +fi + +echo "" +echo "๐Ÿ“‹ Step 6: Check ports and connections" +echo "------------------------------------" +echo "Ports listening on 7777:" +netstat -tlnp 2>/dev/null | grep :7777 || ss -tlnp 2>/dev/null | grep :7777 || echo "โŒ No process listening on port 7777" + +echo "" +echo "๐Ÿ“‹ Step 7: Test SSL certificate" +echo "------------------------------" +echo "Certificate issuer:" +echo | openssl s_client -connect orly-relay.imwald.eu:443 -servername orly-relay.imwald.eu 2>/dev/null | openssl x509 -noout -issuer 2>/dev/null || echo "โŒ SSL test failed" + +echo "" +echo "๐ŸŽฏ RECOMMENDED NEXT STEPS:" +echo "=========================" +echo "1. If proxy_wstunnel is missing: sudo a2enmod proxy_wstunnel && sudo systemctl restart apache2" +echo "2. If no proxy rules found: Add configuration in Plesk Apache & nginx Settings" +echo "3. If local WebSocket fails: Check if relay container is actually running" +echo "4. If remote WebSocket fails but local works: Apache proxy configuration issue" +echo "" +echo "๐Ÿ”ง Try this simple Plesk configuration:" +echo "ProxyPass / http://127.0.0.1:7777/" +echo "ProxyPassReverse / http://127.0.0.1:7777/" diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..0ccfc0a --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,93 @@ +# Docker Compose for Stella's Nostr Relay +# Owner: npub1v30tsz9vw6ylpz63g0a702nj3xa26t3m7p5us8f2y2sd8v6cnsvq465zjx + +version: '3.8' + +services: + stella-relay: + image: silberengel/orly-relay:latest + container_name: stella-nostr-relay + restart: unless-stopped + ports: + - "127.0.0.1:7777:7777" + volumes: + - relay_data:/data + - ./profiles:/profiles:ro + environment: + # Relay Configuration + - ORLY_DATA_DIR=/data + - ORLY_LISTEN=0.0.0.0 + - ORLY_PORT=7777 + - ORLY_LOG_LEVEL=info + - ORLY_MAX_CONNECTIONS=1000 + - ORLY_OWNERS=npub1v30tsz9vw6ylpz63g0a702nj3xa26t3m7p5us8f2y2sd8v6cnsvq465zjx + - ORLY_ADMINS=npub1v30tsz9vw6ylpz63g0a702nj3xa26t3m7p5us8f2y2sd8v6cnsvq465zjx,npub1l5sga6xg72phsz5422ykujprejwud075ggrr3z2hwyrfgr7eylqstegx9z + + # Performance Settings (based on v0.4.8 optimizations) + - ORLY_CONCURRENT_WORKERS=0 # 0 = auto-detect CPU cores + - ORLY_BATCH_SIZE=1000 + - ORLY_CACHE_SIZE=10000 + + # Database Settings + - BADGER_LOG_LEVEL=ERROR + - BADGER_SYNC_WRITES=false # Better performance, slightly less durability + + # Security Settings + - ORLY_REQUIRE_AUTH=false + - ORLY_MAX_EVENT_SIZE=65536 + - ORLY_MAX_SUBSCRIPTIONS=20 + + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:7777"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 10s + + # Resource limits + deploy: + resources: + limits: + memory: 1G + cpus: '1.0' + reservations: + memory: 256M + cpus: '0.25' + + # Logging configuration + logging: + driver: "json-file" + options: + max-size: "10m" + max-file: "3" + + # Optional: Nginx reverse proxy for SSL/domain setup + nginx: + image: nginx:alpine + container_name: stella-nginx + restart: unless-stopped + ports: + - "80:80" + - "443:443" + volumes: + - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro + - ./nginx/ssl:/etc/nginx/ssl:ro + - nginx_logs:/var/log/nginx + depends_on: + - stella-relay + profiles: + - proxy # Only start with: docker-compose --profile proxy up + +volumes: + relay_data: + driver: local + driver_opts: + type: none + o: bind + device: ./data + nginx_logs: + driver: local + +networks: + default: + name: stella-relay-network diff --git a/manage-relay.sh b/manage-relay.sh new file mode 100755 index 0000000..cd82d02 --- /dev/null +++ b/manage-relay.sh @@ -0,0 +1,89 @@ +#!/bin/bash +# Stella's Orly Relay Management Script + +set -e + +RELAY_SERVICE="stella-relay" +RELAY_URL="ws://127.0.0.1:7777" + +case "${1:-}" in + "start") + echo "๐Ÿš€ Starting Stella's Orly Relay..." + sudo systemctl start $RELAY_SERVICE + echo "โœ… Relay started!" + ;; + "stop") + echo "โน๏ธ Stopping Stella's Orly Relay..." + sudo systemctl stop $RELAY_SERVICE + echo "โœ… Relay stopped!" + ;; + "restart") + echo "๐Ÿ”„ Restarting Stella's Orly Relay..." + sudo systemctl restart $RELAY_SERVICE + echo "โœ… Relay restarted!" + ;; + "status") + echo "๐Ÿ“Š Stella's Orly Relay Status:" + sudo systemctl status $RELAY_SERVICE --no-pager + ;; + "logs") + echo "๐Ÿ“œ Stella's Orly Relay Logs:" + sudo journalctl -u $RELAY_SERVICE -f --no-pager + ;; + "test") + echo "๐Ÿงช Testing relay connection..." + if curl -s -I http://127.0.0.1:7777 | grep -q "426 Upgrade Required"; then + echo "โœ… Relay is responding correctly!" + echo "๐Ÿ“ก WebSocket URL: $RELAY_URL" + else + echo "โŒ Relay is not responding correctly" + exit 1 + fi + ;; + "enable") + echo "๐Ÿ”ง Enabling relay to start at boot..." + sudo systemctl enable $RELAY_SERVICE + echo "โœ… Relay will start automatically at boot!" + ;; + "disable") + echo "๐Ÿ”ง Disabling relay auto-start..." + sudo systemctl disable $RELAY_SERVICE + echo "โœ… Relay will not start automatically at boot!" + ;; + "info") + echo "๐Ÿ“‹ Stella's Orly Relay Information:" + echo " Service: $RELAY_SERVICE" + echo " WebSocket URL: $RELAY_URL" + echo " HTTP URL: http://127.0.0.1:7777" + echo " Data Directory: /home/madmin/.local/share/orly-relay" + echo " Config Directory: $(pwd)" + echo "" + echo "๐Ÿ”‘ Admin NPubs:" + echo " Stella: npub1v30tsz9vw6ylpz63g0a702nj3xa26t3m7p5us8f2y2sd8v6cnsvq465zjx" + echo " Admin2: npub1l5sga6xg72phsz5422ykujprejwud075ggrr3z2hwyrfgr7eylqstegx9z" + ;; + *) + echo "๐ŸŒฒ Stella's Orly Relay Management Script" + echo "" + echo "Usage: $0 [COMMAND]" + echo "" + echo "Commands:" + echo " start Start the relay" + echo " stop Stop the relay" + echo " restart Restart the relay" + echo " status Show relay status" + echo " logs Show relay logs (follow mode)" + echo " test Test relay connection" + echo " enable Enable auto-start at boot" + echo " disable Disable auto-start at boot" + echo " info Show relay information" + echo "" + echo "Examples:" + echo " $0 start # Start the relay" + echo " $0 status # Check if it's running" + echo " $0 test # Test WebSocket connection" + echo " $0 logs # Watch real-time logs" + echo "" + echo "๐ŸŒฒ Crafted in the digital forest by Stella โœจ" + ;; +esac diff --git a/stella-relay.service b/stella-relay.service new file mode 100644 index 0000000..72a83a4 --- /dev/null +++ b/stella-relay.service @@ -0,0 +1,39 @@ +[Unit] +Description=Stella's Orly Nostr Relay +Documentation=https://github.com/Silberengel/next.orly.dev +After=network-online.target +Wants=network-online.target + +[Service] +Type=simple +User=madmin +Group=madmin +WorkingDirectory=/home/madmin/Projects/GitCitadel/next.orly.dev +ExecStart=docker compose up stella-relay +ExecStop=docker compose down +Restart=always +RestartSec=10 +TimeoutStartSec=60 +TimeoutStopSec=30 + +# Environment variables +Environment=ORLY_DATA_DIR=/home/madmin/.local/share/orly-relay +Environment=ORLY_LISTEN=127.0.0.1 +Environment=ORLY_PORT=7777 +Environment=ORLY_LOG_LEVEL=info +Environment=ORLY_OWNERS=npub1v30tsz9vw6ylpz63g0a702nj3xa26t3m7p5us8f2y2sd8v6cnsvq465zjx +Environment=ORLY_ADMINS=npub1v30tsz9vw6ylpz63g0a702nj3xa26t3m7p5us8f2y2sd8v6cnsvq465zjx,npub1l5sga6xg72phsz5422ykujprejwud075ggrr3z2hwyrfgr7eylqstegx9z + +# Security settings +NoNewPrivileges=true +ProtectSystem=strict +ProtectHome=read-only +ReadWritePaths=/home/madmin/.local/share/orly-relay +ReadWritePaths=/home/madmin/Projects/GitCitadel/next.orly.dev/data + +# Resource limits +LimitNOFILE=65536 +LimitNPROC=4096 + +[Install] +WantedBy=multi-user.target