Browse Source

update docker and apache stuff to new next-orly and make it all more proxy-friendly

main
Silberengel 3 months ago
parent
commit
9fdef77e02
  1. 4
      .dockerignore
  2. 132
      APACHE-PROXY-GUIDE.md
  3. 12
      app/config/config.go
  4. 2
      app/handle-req.go
  5. 15
      app/handle-websocket.go
  6. 27
      app/helpers.go
  7. 41
      app/server.go
  8. 161
      app/web/dist/index-kk1m7jg4.js
  9. 161
      app/web/dist/index-mrm09k9p.js
  10. 2
      app/web/dist/index.html
  11. 28
      docker-compose.yml
  12. 115
      manage-relay.sh
  13. 20
      pkg/protocol/auth/nip42.go
  14. 6
      readme.adoc
  15. 35
      stella-relay.service

4
.dockerignore

@ -13,6 +13,8 @@ cmd/benchmark/reports/ @@ -13,6 +13,8 @@ cmd/benchmark/reports/
# Go build cache and binaries
**/bin/
**/dist/
**/build/
**/*.out
# Allow web dist directory (needed for embedding)
!app/web/dist/

132
APACHE-PROXY-GUIDE.md

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
# 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**
**Updated with real-world troubleshooting solutions and latest Orly relay improvements**
## 🎯 **What This Solves**
- WebSocket connection failures (`NS_ERROR_WEBSOCKET_CONNECTION_REFUSED`)
@ -9,24 +9,32 @@ @@ -9,24 +9,32 @@
- Docker container proxy configuration
- SSL certificate integration
- Plesk configuration conflicts and virtual host precedence issues
- **NEW**: WebSocket scheme validation errors (`expected 'ws' got 'wss'`)
- **NEW**: Proxy-friendly relay configuration with enhanced CORS headers
- **NEW**: Improved error handling for malformed client data
## 🐳 **Step 1: Deploy Your Docker Application**
### **For Stella's Orly Relay:**
### **For Stella's Orly Relay (Latest Version with Proxy Improvements):**
```bash
# Pull and run the relay
# Pull and run the relay with enhanced proxy support
docker run -d \
--name stella-relay \
--name orly-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
-e ORLY_RELAY_URL=wss://your-domain.com \
-e ORLY_ACL_MODE=follows \
-e ORLY_SPIDER_MODE=follows \
-e ORLY_SPIDER_FREQUENCY=1h \
-e ORLY_SUBSCRIPTION_ENABLED=false \
silberengel/next-orly:latest
# Test the relay
curl -I http://127.0.0.1:7777
# Should return: HTTP/1.1 426 Upgrade Required
# Should return: HTTP/1.1 200 OK with enhanced CORS headers
```
### **For Web Apps (like Jumble):**
@ -253,9 +261,40 @@ sudo a2enmod proxy @@ -253,9 +261,40 @@ sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod proxy_wstunnel
sudo a2enmod rewrite
sudo a2enmod headers
sudo systemctl restart apache2
```
## 🆕 **Step 4: Latest Orly Relay Improvements**
### **Enhanced Proxy Support**
The latest Orly relay includes several proxy improvements:
1. **Flexible WebSocket Scheme Handling**: Accepts both `ws://` and `wss://` schemes for authentication
2. **Enhanced CORS Headers**: Better compatibility with web applications
3. **Improved Error Handling**: More robust handling of malformed client data
4. **Proxy-Aware Logging**: Better debugging information for proxy setups
### **Key Environment Variables**
```bash
# Essential for proxy setups
ORLY_RELAY_URL=wss://your-domain.com # Must match your public URL
ORLY_ACL_MODE=follows # Enable follows-based access control
ORLY_SPIDER_MODE=follows # Enable content syncing from other relays
ORLY_SUBSCRIPTION_ENABLED=false # Disable payment requirements
```
### **Testing the Enhanced Relay**
```bash
# Test local connectivity
curl -I http://127.0.0.1:7777
# Expected response includes enhanced CORS headers:
# Access-Control-Allow-Credentials: true
# Access-Control-Max-Age: 86400
# Vary: Origin, Access-Control-Request-Method, Access-Control-Request-Headers
```
## ⚡ **Step 4: Alternative - Nginx in Plesk**
If Apache keeps giving issues, switch to Nginx in Plesk:
@ -327,13 +366,67 @@ After making changes: @@ -327,13 +366,67 @@ After making changes:
```bash
# Essential debugging
docker ps | grep relay # Container running?
curl -I http://127.0.0.1:7777 # Local relay (should return 426)
curl -I http://127.0.0.1:7777 # Local relay (should return 200 with CORS headers)
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
# Check relay logs for proxy information
docker logs relay-name | grep -i "proxy info"
docker logs relay-name | grep -i "websocket connection"
```
## 🚨 **Latest Troubleshooting Solutions**
### **WebSocket Scheme Validation Errors**
**Problem**: `"HTTP Scheme incorrect: expected 'ws' got 'wss'"`
**Solution**: Use the latest Orly relay image with enhanced proxy support:
```bash
# Pull the latest image with proxy improvements
docker pull silberengel/next-orly:latest
# Restart with the latest image
docker stop orly-relay && docker rm orly-relay
# Then run with the configuration above
```
### **Malformed Client Data Errors**
**Problem**: `"invalid hex array size, got 2 expect 64"`
**Solution**: These are client-side issues, not server problems. The latest relay handles them gracefully:
- The relay now sends helpful error messages to clients
- Malformed requests are logged but don't crash the relay
- Normal operations continue despite client errors
### **Follows ACL Not Working**
**Problem**: Only owners can write, admins can't write
**Solution**: Ensure proper configuration:
```bash
# Check ACL configuration
docker exec orly-relay env | grep ACL
# Should show: ORLY_ACL_MODE=follows
# If not, restart with explicit configuration
```
### **Spider Not Syncing Content**
**Problem**: Spider enabled but not pulling events
**Solution**: Check for relay lists and follow events:
```bash
# Check spider status
docker logs orly-relay | grep -i spider
# Look for relay discovery
docker logs orly-relay | grep -i "relay URLs"
# Check for follow events
docker logs orly-relay | grep -i "kind.*3"
```
### **Working Solution (Proven):**
@ -362,3 +455,28 @@ echo '["REQ","test",{}]' | websocat wss://domain.com/ws/ # /ws/ path @@ -362,3 +455,28 @@ echo '["REQ","test",{}]' | websocat wss://domain.com/ws/ # /ws/ path
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`
5. **NEW**: Use the latest Orly relay image for better proxy compatibility
6. **NEW**: Enhanced CORS headers improve web app compatibility
7. **NEW**: Flexible WebSocket scheme handling eliminates authentication errors
8. **NEW**: Improved error handling makes the relay more robust
## 🎉 **Summary of Latest Improvements**
### **Enhanced Proxy Support**
- ✅ Flexible WebSocket scheme validation (accepts both `ws://` and `wss://`)
- ✅ Enhanced CORS headers for better web app compatibility
- ✅ Improved error handling for malformed client data
- ✅ Proxy-aware logging for better debugging
### **Spider and ACL Features**
- ✅ Follows-based access control (`ORLY_ACL_MODE=follows`)
- ✅ Content syncing from other relays (`ORLY_SPIDER_MODE=follows`)
- ✅ No payment requirements (`ORLY_SUBSCRIPTION_ENABLED=false`)
### **Production Ready**
- ✅ Robust error handling
- ✅ Enhanced logging and debugging
- ✅ Better client compatibility
- ✅ Improved proxy support
**The latest Orly relay is now fully optimized for proxy environments and provides a much better user experience!**

12
app/config/config.go

@ -40,7 +40,7 @@ type C struct { @@ -40,7 +40,7 @@ type C struct {
Admins []string `env:"ORLY_ADMINS" usage:"comma-separated list of admin npubs"`
Owners []string `env:"ORLY_OWNERS" usage:"comma-separated list of owner npubs, who have full control of the relay for wipe and restart and other functions"`
ACLMode string `env:"ORLY_ACL_MODE" usage:"ACL mode: follows,none" default:"none"`
SpiderMode string `env:"ORLY_SPIDER_MODE" usage:"spider mode: none,follow" default:"none"`
SpiderMode string `env:"ORLY_SPIDER_MODE" usage:"spider mode: none,follows" default:"none"`
SpiderFrequency time.Duration `env:"ORLY_SPIDER_FREQUENCY" usage:"spider frequency in seconds" default:"1h"`
NWCUri string `env:"ORLY_NWC_URI" usage:"NWC (Nostr Wallet Connect) connection string for Lightning payments"`
SubscriptionEnabled bool `env:"ORLY_SUBSCRIPTION_ENABLED" default:"false" usage:"enable subscription-based access control requiring payment for non-directory events"`
@ -225,15 +225,14 @@ func EnvKV(cfg any) (m KVSlice) { @@ -225,15 +225,14 @@ func EnvKV(cfg any) (m KVSlice) {
k := t.Field(i).Tag.Get("env")
v := reflect.ValueOf(cfg).Field(i).Interface()
var val string
switch v.(type) {
switch v := v.(type) {
case string:
val = v.(string)
val = v
case int, bool, time.Duration:
val = fmt.Sprint(v)
case []string:
arr := v.([]string)
if len(arr) > 0 {
val = strings.Join(arr, ",")
if len(v) > 0 {
val = strings.Join(v, ",")
}
}
// this can happen with embedded structs
@ -305,5 +304,4 @@ func PrintHelp(cfg *C, printer io.Writer) { @@ -305,5 +304,4 @@ func PrintHelp(cfg *C, printer io.Writer) {
fmt.Fprintf(printer, "\ncurrent configuration:\n\n")
PrintEnv(cfg, printer)
fmt.Fprintln(printer)
return
}

2
app/handle-req.go

@ -64,7 +64,7 @@ func (l *Listener) HandleReq(msg []byte) (err error) { @@ -64,7 +64,7 @@ func (l *Listener) HandleReq(msg []byte) (err error) {
l.ctx, 30*time.Second,
)
defer queryCancel()
// Collect all events from all filters
var allEvents event.S
for _, f := range *env.Filters {

15
app/handle-websocket.go

@ -38,7 +38,9 @@ const ( @@ -38,7 +38,9 @@ const (
func (s *Server) HandleWebsocket(w http.ResponseWriter, r *http.Request) {
remote := GetRemoteFromReq(r)
log.T.F("handling websocket connection from %s", remote)
// Log comprehensive proxy information for debugging
LogProxyInfo(r, "WebSocket connection from "+remote)
if len(s.Config.IPWhitelist) > 0 {
for _, ip := range s.Config.IPWhitelist {
log.T.F("checking IP whitelist: %s", ip)
@ -55,9 +57,14 @@ whitelist: @@ -55,9 +57,14 @@ whitelist:
defer cancel()
var err error
var conn *websocket.Conn
if conn, err = websocket.Accept(
w, r, &websocket.AcceptOptions{OriginPatterns: []string{"*"}},
); chk.E(err) {
// Configure WebSocket accept options for proxy compatibility
acceptOptions := &websocket.AcceptOptions{
OriginPatterns: []string{"*"}, // Allow all origins for proxy compatibility
// Don't check origin when behind a proxy - let the proxy handle it
InsecureSkipVerify: true,
}
if conn, err = websocket.Accept(w, r, acceptOptions); chk.E(err) {
log.E.F("websocket accept failed from %s: %v", remote, err)
return
}

27
app/helpers.go

@ -3,6 +3,8 @@ package app @@ -3,6 +3,8 @@ package app
import (
"net/http"
"strings"
"lol.mleku.dev/log"
)
// GetRemoteFromReq retrieves the originating IP address of the client from
@ -67,3 +69,28 @@ func GetRemoteFromReq(r *http.Request) (rr string) { @@ -67,3 +69,28 @@ func GetRemoteFromReq(r *http.Request) (rr string) {
}
return
}
// LogProxyInfo logs comprehensive proxy information for debugging
func LogProxyInfo(r *http.Request, prefix string) {
proxyHeaders := map[string]string{
"X-Forwarded-For": r.Header.Get("X-Forwarded-For"),
"X-Real-IP": r.Header.Get("X-Real-IP"),
"X-Forwarded-Proto": r.Header.Get("X-Forwarded-Proto"),
"X-Forwarded-Host": r.Header.Get("X-Forwarded-Host"),
"X-Forwarded-Port": r.Header.Get("X-Forwarded-Port"),
"Forwarded": r.Header.Get("Forwarded"),
"Host": r.Header.Get("Host"),
"User-Agent": r.Header.Get("User-Agent"),
}
var info []string
for header, value := range proxyHeaders {
if value != "" {
info = append(info, header+":"+value)
}
}
if len(info) > 0 {
log.T.F("%s proxy info: %s", prefix, strings.Join(info, " "))
}
}

41
app/server.go

@ -40,17 +40,24 @@ type Server struct { @@ -40,17 +40,24 @@ type Server struct {
// Challenge storage for HTTP UI authentication
challengeMutex sync.RWMutex
challenges map[string][]byte
paymentProcessor *PaymentProcessor
}
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// Set CORS headers for all responses
// Set comprehensive CORS headers for proxy compatibility
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
w.Header().Set(
"Access-Control-Allow-Headers", "Content-Type, Authorization",
)
w.Header().Set("Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept, Authorization, "+
"X-Forwarded-For, X-Forwarded-Proto, X-Forwarded-Host, X-Real-IP, "+
"Upgrade, Connection, Sec-WebSocket-Key, Sec-WebSocket-Version, "+
"Sec-WebSocket-Protocol, Sec-WebSocket-Extensions")
w.Header().Set("Access-Control-Allow-Credentials", "true")
w.Header().Set("Access-Control-Max-Age", "86400")
// Add proxy-friendly headers
w.Header().Set("Vary", "Origin, Access-Control-Request-Method, Access-Control-Request-Headers")
// Handle preflight OPTIONS requests
if r.Method == "OPTIONS" {
@ -58,6 +65,11 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { @@ -58,6 +65,11 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
return
}
// Log proxy information for debugging (only for WebSocket requests to avoid spam)
if r.Header.Get("Upgrade") == "websocket" {
LogProxyInfo(r, "HTTP request")
}
// If this is a websocket request, only intercept the relay root path.
// This allows other websocket paths (e.g., Vite HMR) to be handled by the dev proxy when enabled.
if r.Header.Get("Upgrade") == "websocket" {
@ -83,13 +95,30 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { @@ -83,13 +95,30 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}
func (s *Server) ServiceURL(req *http.Request) (st string) {
// Get host from various proxy headers
host := req.Header.Get("X-Forwarded-Host")
if host == "" {
host = req.Header.Get("Host")
}
if host == "" {
host = req.Host
}
// Get protocol from various proxy headers
proto := req.Header.Get("X-Forwarded-Proto")
if proto == "" {
if host == "localhost" {
proto = req.Header.Get("X-Forwarded-Scheme")
}
if proto == "" {
// Check if we're behind a proxy by looking for common proxy headers
hasProxyHeaders := req.Header.Get("X-Forwarded-For") != "" ||
req.Header.Get("X-Real-IP") != "" ||
req.Header.Get("Forwarded") != ""
if hasProxyHeaders {
// If we have proxy headers, assume HTTPS/WSS
proto = "wss"
} else if host == "localhost" {
proto = "ws"
} else if strings.Contains(host, ":") {
// has a port number

161
app/web/dist/index-kk1m7jg4.js vendored

File diff suppressed because one or more lines are too long

161
app/web/dist/index-mrm09k9p.js vendored

File diff suppressed because one or more lines are too long

2
app/web/dist/index.html vendored

@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Nostr Relay</title>
<link rel="stylesheet" crossorigin href="./index-q4cwd1fy.css"><script type="module" crossorigin src="./index-kk1m7jg4.js"></script></head>
<link rel="stylesheet" crossorigin href="./index-q4cwd1fy.css"><script type="module" crossorigin src="./index-mrm09k9p.js"></script></head>
<body>
<script>
// Apply system theme preference immediately to avoid flash of wrong theme

28
docker-compose.yml

@ -1,11 +1,12 @@ @@ -1,11 +1,12 @@
# Docker Compose for Stella's Nostr Relay
# Owner: npub1v30tsz9vw6ylpz63g0a702nj3xa26t3m7p5us8f2y2sd8v6cnsvq465zjx
version: '3.8'
services:
stella-relay:
image: silberengel/orly-relay:latest
build:
context: .
dockerfile: Dockerfile
image: silberengel/next-orly:latest
container_name: stella-nostr-relay
restart: unless-stopped
ports:
@ -19,21 +20,20 @@ services: @@ -19,21 +20,20 @@ services:
- ORLY_LISTEN=0.0.0.0
- ORLY_PORT=7777
- ORLY_LOG_LEVEL=info
- ORLY_MAX_CONNECTIONS=1000
- ORLY_DB_LOG_LEVEL=error
- ORLY_OWNERS=npub1v30tsz9vw6ylpz63g0a702nj3xa26t3m7p5us8f2y2sd8v6cnsvq465zjx
- ORLY_ADMINS=npub1v30tsz9vw6ylpz63g0a702nj3xa26t3m7p5us8f2y2sd8v6cnsvq465zjx,npub1l5sga6xg72phsz5422ykujprejwud075ggrr3z2hwyrfgr7eylqstegx9z
- ORLY_ADMINS=npub1v30tsz9vw6ylpz63g0a702nj3xa26t3m7p5us8f2y2sd8v6cnsvq465zjx
# 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
# ACL and Spider Configuration
- ORLY_ACL_MODE=follows
- ORLY_SPIDER_MODE=follows
# Database Settings
- BADGER_LOG_LEVEL=ERROR
- BADGER_SYNC_WRITES=false # Better performance, slightly less durability
# Subscription Settings (optional)
- ORLY_SUBSCRIPTION_ENABLED=false
- ORLY_MONTHLY_PRICE_SATS=0
# Security Settings
- ORLY_REQUIRE_AUTH=false
# Performance Settings
- ORLY_MAX_CONNECTIONS=1000
- ORLY_MAX_EVENT_SIZE=65536
- ORLY_MAX_SUBSCRIPTIONS=20

115
manage-relay.sh

@ -1,42 +1,57 @@ @@ -1,42 +1,57 @@
#!/bin/bash
# Stella's Orly Relay Management Script
# Uses docker-compose.yml directly for configuration
set -e
# Get script directory and project root
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$SCRIPT_DIR"
# Configuration from docker-compose.yml
RELAY_SERVICE="stella-relay"
CONTAINER_NAME="stella-nostr-relay"
RELAY_URL="ws://127.0.0.1:7777"
HTTP_URL="http://127.0.0.1:7777"
RELAY_DATA_DIR="/home/madmin/.local/share/orly-relay"
# Change to project directory for docker-compose commands
cd "$PROJECT_DIR"
case "${1:-}" in
"start")
echo "🚀 Starting Stella's Orly Relay..."
sudo systemctl start $RELAY_SERVICE
docker compose up -d stella-relay
echo "✅ Relay started!"
;;
"stop")
echo "⏹ Stopping Stella's Orly Relay..."
sudo systemctl stop $RELAY_SERVICE
docker compose down
echo "✅ Relay stopped!"
;;
"restart")
echo "🔄 Restarting Stella's Orly Relay..."
sudo systemctl restart $RELAY_SERVICE
docker compose restart stella-relay
echo "✅ Relay restarted!"
;;
"status")
echo "📊 Stella's Orly Relay Status:"
sudo systemctl status $RELAY_SERVICE --no-pager
docker compose ps stella-relay
;;
"logs")
echo "📜 Stella's Orly Relay Logs:"
sudo journalctl -u $RELAY_SERVICE -f --no-pager
docker compose logs -f stella-relay
;;
"test")
echo "🧪 Testing relay connection..."
if curl -s -I http://127.0.0.1:7777 | grep -q "426 Upgrade Required"; then
if curl -s -I "$HTTP_URL" | grep -q "426 Upgrade Required"; then
echo "✅ Relay is responding correctly!"
echo "📡 WebSocket URL: $RELAY_URL"
echo "🌐 HTTP URL: $HTTP_URL"
else
echo "❌ Relay is not responding correctly"
echo " Expected: 426 Upgrade Required"
echo " URL: $HTTP_URL"
exit 1
fi
;;
@ -53,14 +68,53 @@ case "${1:-}" in @@ -53,14 +68,53 @@ case "${1:-}" in
"info")
echo "📋 Stella's Orly Relay Information:"
echo " Service: $RELAY_SERVICE"
echo " Container: $CONTAINER_NAME"
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 " HTTP URL: $HTTP_URL"
echo " Data Directory: $RELAY_DATA_DIR"
echo " Config Directory: $PROJECT_DIR"
echo ""
echo "🐳 Docker Information:"
echo " Compose File: $PROJECT_DIR/docker-compose.yml"
echo " Container Status:"
docker compose ps stella-relay 2>/dev/null || echo " Not running"
echo ""
echo "🔑 Admin NPubs:"
echo " Stella: npub1v30tsz9vw6ylpz63g0a702nj3xa26t3m7p5us8f2y2sd8v6cnsvq465zjx"
echo " Admin2: npub1l5sga6xg72phsz5422ykujprejwud075ggrr3z2hwyrfgr7eylqstegx9z"
echo "💡 Configuration:"
echo " All settings are defined in docker-compose.yml"
echo " Use 'docker compose config' to see parsed configuration"
;;
"docker-logs")
echo "🐳 Docker Container Logs:"
docker compose logs -f stella-relay 2>/dev/null || echo "❌ Container not found or not running"
;;
"docker-status")
echo "🐳 Docker Container Status:"
docker compose ps stella-relay
;;
"docker-restart")
echo "🔄 Restarting Docker Container..."
docker compose restart stella-relay
echo "✅ Container restarted!"
;;
"docker-update")
echo "🔄 Updating and restarting Docker Container..."
docker compose pull stella-relay
docker compose up -d stella-relay
echo "✅ Container updated and restarted!"
;;
"docker-build")
echo "🔨 Building Docker Container..."
docker compose build stella-relay
echo "✅ Container built!"
;;
"docker-down")
echo "⏹ Stopping Docker Container..."
docker compose down
echo "✅ Container stopped!"
;;
"docker-config")
echo "📋 Docker Compose Configuration:"
docker compose config
;;
*)
echo "🌲 Stella's Orly Relay Management Script"
@ -68,21 +122,32 @@ case "${1:-}" in @@ -68,21 +122,32 @@ case "${1:-}" in
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 " 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 "Docker Commands:"
echo " docker-logs Show Docker container logs"
echo " docker-status Show Docker container status"
echo " docker-restart Restart Docker container only"
echo " docker-update Update and restart container"
echo " docker-build Build Docker container"
echo " docker-down Stop Docker container"
echo " docker-config Show Docker Compose configuration"
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 " $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 " $0 docker-logs # Watch Docker container logs"
echo " $0 docker-update # Update and restart container"
echo ""
echo "🌲 Crafted in the digital forest by Stella ✨"
;;

20
pkg/protocol/auth/nip42.go

@ -91,12 +91,22 @@ func Validate(evt *event.E, challenge []byte, relayURL string) ( @@ -91,12 +91,22 @@ func Validate(evt *event.E, challenge []byte, relayURL string) (
err = errorf.E("error parsing relay url: %s", err)
return
}
// Allow both ws:// and wss:// schemes when behind a reverse proxy
// This handles cases where the relay expects ws:// but receives wss:// from clients
// connecting through HTTPS proxies
if expected.Scheme != found.Scheme {
err = errorf.E(
"HTTP Scheme incorrect: expected '%s' got '%s",
expected.Scheme, found.Scheme,
)
return
// Check if this is a ws/wss scheme mismatch (acceptable behind proxy)
if (expected.Scheme == "ws" && found.Scheme == "wss") ||
(expected.Scheme == "wss" && found.Scheme == "ws") {
// This is acceptable when behind a reverse proxy
// The client will always send wss:// when connecting through HTTPS
} else {
err = errorf.E(
"HTTP Scheme incorrect: expected '%s' got '%s",
expected.Scheme, found.Scheme,
)
return
}
}
if expected.Host != found.Host {
err = errorf.E(

6
readme.adoc

@ -303,11 +303,11 @@ The spider operates in two phases: @@ -303,11 +303,11 @@ The spider operates in two phases:
=== configuration
Enable the spider by setting the spider mode to "follow":
Enable the spider by setting the spider mode to "follows":
[source,bash]
----
export ORLY_SPIDER_MODE=follow
export ORLY_SPIDER_MODE=follows
export ORLY_SPIDER_FREQUENCY=1h
----
@ -322,7 +322,7 @@ Configuration options: @@ -322,7 +322,7 @@ Configuration options:
----
# Enable both follows ACL and spider sync
export ORLY_ACL_MODE=follows
export ORLY_SPIDER_MODE=follow
export ORLY_SPIDER_MODE=follows
export ORLY_SPIDER_FREQUENCY=30m
export ORLY_ADMINS=npub1fjqqy4a93z5zsjwsfxqhc2764kvykfdyttvldkkkdera8dr78vhsmmleku

35
stella-relay.service

@ -1,28 +1,25 @@ @@ -1,28 +1,25 @@
[Unit]
Description=Stella's Orly Nostr Relay
Description=Stella's Orly Nostr Relay (Docker Compose)
Documentation=https://github.com/Silberengel/next.orly.dev
After=network-online.target
After=network-online.target docker.service
Wants=network-online.target
Requires=docker.service
[Service]
Type=simple
Type=oneshot
RemainAfterExit=yes
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
# Start the relay using docker compose
ExecStart=/usr/bin/docker compose up -d stella-relay
# Stop the relay
ExecStop=/usr/bin/docker compose down
# Reload configuration (restart containers)
ExecReload=/usr/bin/docker compose restart stella-relay
# Security settings
NoNewPrivileges=true
@ -35,5 +32,11 @@ ReadWritePaths=/home/madmin/Projects/GitCitadel/next.orly.dev/data @@ -35,5 +32,11 @@ ReadWritePaths=/home/madmin/Projects/GitCitadel/next.orly.dev/data
LimitNOFILE=65536
LimitNPROC=4096
# Restart policy
Restart=on-failure
RestartSec=10
TimeoutStartSec=60
TimeoutStopSec=30
[Install]
WantedBy=multi-user.target

Loading…
Cancel
Save