From ba153e7bf46613467cc62e164c85d4226311d7fa Mon Sep 17 00:00:00 2001 From: Sudo-Ivan Date: Fri, 2 Jan 2026 16:49:04 -0600 Subject: [PATCH] chore(docker): remove demo configuration files for Docker and NGINX to streamline project structure --- Dockerfile.demo | 32 ----- docker-compose.demo.yml | 27 ----- nginx.demo.conf | 257 ---------------------------------------- 3 files changed, 316 deletions(-) delete mode 100644 Dockerfile.demo delete mode 100644 docker-compose.demo.yml delete mode 100644 nginx.demo.conf diff --git a/Dockerfile.demo b/Dockerfile.demo deleted file mode 100644 index afa8ca9..0000000 --- a/Dockerfile.demo +++ /dev/null @@ -1,32 +0,0 @@ -# Build arguments -ARG NODE_VERSION=20 -ARG NODE_ALPINE_SHA256=sha256:6a91081a440be0b57336fbc4ee87f3dab1a2fd6f80cdb355dcf960e13bda3b59 - -# Build the frontend -FROM node:${NODE_VERSION}-alpine@${NODE_ALPINE_SHA256} AS build-frontend - -WORKDIR /src - -COPY package.json vite.config.js pnpm-lock.yaml tailwind.config.js postcss.config.js ./ -# Copy only the frontend source and version info to speed up builds and reduce image size -COPY meshchatx/src/frontend ./meshchatx/src/frontend -COPY meshchatx/src/version.py ./meshchatx/src/version.py - -RUN corepack enable && corepack prepare pnpm@latest --activate - -RUN pnpm install - -RUN pnpm run build-frontend - -RUN find /src/meshchatx/public -type d -exec chmod 755 {} + && \ - find /src/meshchatx/public -type f -exec chmod 644 {} + - -# Runtime stage -FROM nginxinc/nginx-unprivileged:alpine - -COPY --from=build-frontend --chown=101:101 /src/meshchatx/public /usr/share/nginx/html -COPY nginx.demo.conf /etc/nginx/conf.d/default.conf - -EXPOSE 8080 - -CMD ["nginx", "-g", "daemon off;"] diff --git a/docker-compose.demo.yml b/docker-compose.demo.yml deleted file mode 100644 index 00291ba..0000000 --- a/docker-compose.demo.yml +++ /dev/null @@ -1,27 +0,0 @@ -services: - meshchatx-demo: - build: - context: . - dockerfile: Dockerfile.demo - image: ${MESHCHAT_DEMO_IMAGE:-reticulum-meshchatx-demo:local} - container_name: reticulum-meshchatx-demo - restart: unless-stopped - - # Security Hardening - security_opt: - - no-new-privileges:true - read_only: true - tmpfs: - - /tmp:mode=1777 - - /var/cache/nginx:mode=1777 - - /var/run:mode=1777 - cap_drop: - - ALL - - # Resource Limits - deploy: - resources: - limits: - memory: 128M - reservations: - memory: 64M diff --git a/nginx.demo.conf b/nginx.demo.conf deleted file mode 100644 index ca18d92..0000000 --- a/nginx.demo.conf +++ /dev/null @@ -1,257 +0,0 @@ -server { - listen 8080; - server_name localhost; - - absolute_redirect off; - port_in_redirect off; - - include /etc/nginx/mime.types; - default_type application/octet-stream; - - root /usr/share/nginx/html; - index index.html; - - # Support for SPA routing - location / { - try_files $uri $uri/ /index.html; - add_header Cache-Control "no-cache"; - } - - # Don't serve index.html for missing assets - location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot|wasm|json|proto)$ { - add_header Cache-Control "public, max-age=31536000, immutable"; - access_log off; - try_files $uri =404; - } - - # Mocking missing critical files for demo stability - location = /manifest.json { - add_header Cache-Control "no-cache"; - add_header Content-Type application/json; - try_files $uri @mock_manifest; - } - location @mock_manifest { - return 200 '{"name": "MeshChat Demo", "short_name": "MeshChat", "start_url": "/", "display": "standalone", "icons": [{"src": "/favicons/favicon-512x512.png", "sizes": "512x512", "type": "image/png"}]}'; - } - - location = /service-worker.js { - add_header Cache-Control "no-cache"; - add_header Content-Type application/javascript; - try_files $uri @mock_sw; - } - location @mock_sw { - return 200 '// Mock Service Worker\nself.addEventListener("fetch", (event) => {});'; - } - - # Mock Codec2 scripts to prevent load failures in demo mode - location ^~ /assets/js/codec2-emscripten/ { - add_header Content-Type application/javascript; - try_files $uri =200; - } - - # Gzip compression - gzip on; - gzip_vary on; - gzip_proxied any; - gzip_comp_level 6; - gzip_types text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml; - - # Mock responses for demo mode with the power of NGINX! - location /api/v1/auth/status { - return 200 '{"auth_enabled": false, "authenticated": true}'; - add_header Content-Type application/json; - } - - location /api/v1/config { - return 200 '{"config": {"theme": "dark", "language": "en", "display_name": "Demo User", "identity_hash": "effe95b0482d7b6c04844977d17e0c36", "lxmf_address_hash": "c0ffee00000000000000000000000000", "auto_announce_interval_seconds": 0, "lxmf_user_icon_name": "account", "lxmf_user_icon_foreground_colour": "#ffffff", "lxmf_user_icon_background_colour": "#000000"}}'; - add_header Content-Type application/json; - } - - location /api/v1/app/info { - return 200 '{"app_info": {"version": "demo", "rns_version": "0.0.0", "lxmf_version": "0.0.0", "python_version": "3.11", "is_connected_to_shared_instance": false, "is_transport_enabled": false, "reticulum_config_path": "/demo/rns.conf", "database_path": "/demo/meshchat.db", "database_file_size": 1048576, "is_demo": true, "memory_usage": {"rss": 52428800, "vms": 104857600}, "network_stats": {"bytes_sent": 102400, "bytes_recv": 204800, "packets_sent": 150, "packets_recv": 300}, "reticulum_stats": {"total_paths": 42, "announces_per_second": 0.1, "announces_per_minute": 6, "announces_per_hour": 360}}}'; - add_header Content-Type application/json; - } - - location /api/v1/database/health { - return 200 '{"database": {"quick_check": "ok", "journal_mode": "wal", "wal_autocheckpoint": 1000, "page_size": 4096, "page_count": 256, "freelist_pages": 10, "estimated_free_bytes": 40960}}'; - add_header Content-Type application/json; - } - - location /api/v1/reticulum/interfaces { - return 200 '{"interfaces": { - "RNode-LoRa-V3": {"type": "RNodeInterface", "enabled": "true", "port": "/dev/ttyUSB0", "frequency": 868000000, "bandwidth": 125000, "spreadingfactor": 7, "codingrate": 5, "txpower": 7}, - "Internet": {"type": "TCPClientInterface", "enabled": "true", "target_host": "hub.reticulum.network", "target_port": 4242}, - "I2C-Bus-0": {"type": "I2CInterface", "enabled": "false"}, - "LAN Mesh": {"type": "UDPInterface", "enabled": "true", "listen_ip": "0.0.0.0", "listen_port": 4242, "forward_ip": "255.255.255.255", "forward_port": 4242} - }}'; - add_header Content-Type application/json; - } - - location /api/v1/interface-stats { - return 200 '{"interface_stats": {"interfaces": [ - {"short_name": "RNode-LoRa-V3", "name": "AutoInterface[RNode]", "status": true, "bitrate": 1200, "txb": 1024, "rxb": 5120}, - {"short_name": "Internet", "name": "AutoInterface[TCP]", "status": true, "bitrate": 10000000, "txb": 45678, "rxb": 987654}, - {"short_name": "I2C-Bus-0", "name": "AutoInterface[I2C]", "status": false, "bitrate": 400000, "txb": 0, "rxb": 0}, - {"short_name": "LAN Mesh", "name": "AutoInterface[UDP]", "status": true, "bitrate": 100000000, "txb": 12345, "rxb": 67890} - ]}}'; - add_header Content-Type application/json; - } - - location /api/v1/lxmf/conversations { - return 200 '{"conversations": [ - {"destination_hash": "8b5cf6", "display_name": "Alice", "updated_at": "2026-01-01T12:00:00Z", "latest_message_preview": "Hello from the mesh!", "unread_count": 1, "lxmf_user_icon": {"icon_name": "account", "foreground_colour": "#ffffff", "background_colour": "#3b82f6"}}, - {"destination_hash": "3b82f6", "display_name": "Bob", "updated_at": "2026-01-01T11:30:00Z", "latest_message_preview": "Did you see the new RNode update?", "unread_count": 0, "lxmf_user_icon": {"icon_name": "robot", "foreground_colour": "#ffffff", "background_colour": "#ef4444"}}, - {"destination_hash": "10b981", "display_name": "Regional Hub", "updated_at": "2026-01-01T10:00:00Z", "latest_message_preview": "Status: All interfaces operational", "unread_count": 0, "lxmf_user_icon": {"icon_name": "server", "foreground_colour": "#ffffff", "background_colour": "#10b981"}} - ]}'; - add_header Content-Type application/json; - } - - location ~ ^/api/v1/lxmf-messages/conversation/(.*)$ { - return 200 '{"lxmf_messages": [ - {"hash": "msg1", "source_hash": "8b5cf6", "destination_hash": "c0ffee00000000000000000000000000", "content": "Hey there!", "timestamp": 1735732500, "created_at": "2026-01-01T11:55:00Z", "state": "delivered", "method": "propagated"}, - {"hash": "msg2", "source_hash": "8b5cf6", "destination_hash": "c0ffee00000000000000000000000000", "content": "Hello from the mesh!", "timestamp": 1735732800, "created_at": "2026-01-01T12:00:00Z", "state": "delivered", "method": "propagated"} - ]}'; - add_header Content-Type application/json; - } - - location ~ ^/api/v1/lxmf/conversations/(.*)/mark-as-read$ { - return 200 '{"success": true}'; - add_header Content-Type application/json; - } - - location /api/v1/blocked-destinations { - return 200 '{"blocked_destinations": []}'; - add_header Content-Type application/json; - } - - location /api/v1/telephone/status { - set $mock_call $arg_mock_call; - if ($mock_call = "true") { - return 200 '{"enabled": true, "is_busy": false, "call_status": "ringing", "active_call": {"hash": "call123", "status": "ringing", "is_incoming": true, "is_outgoing": false, "remote_identity_hash": "8b5cf6", "remote_identity_name": "Alice", "audio_profile_id": 0, "tx_packets": 0, "rx_packets": 0, "tx_bytes": 0, "rx_bytes": 0, "is_mic_muted": false, "is_speaker_muted": false, "is_voicemail": false}, "is_mic_muted": false, "is_speaker_muted": false, "voicemail": {"is_recording": false, "unread_count": 0}}'; - add_header Content-Type application/json; - } - return 200 '{"enabled": true, "is_busy": false, "call_status": "idle", "active_call": null, "is_mic_muted": false, "is_speaker_muted": false, "voicemail": {"is_recording": false, "unread_count": 0}}'; - add_header Content-Type application/json; - } - - location /api/v1/telephone/mock-incoming-call { - return 200 '{"message": "Mock incoming call triggered. Poll /api/v1/telephone/status?mock_call=true to see the call"}'; - add_header Content-Type application/json; - } - - location /api/v1/telephone/history { - return 200 '{"call_history": [ - {"id": 1, "remote_identity_hash": "8b5cf6", "remote_identity_name": "Alice", "is_incoming": 1, "status": "completed", "duration_seconds": 125, "timestamp": 1735732800.0, "created_at": "2026-01-01T12:00:00Z"}, - {"id": 2, "remote_identity_hash": "3b82f6", "remote_identity_name": "Bob", "is_incoming": 0, "status": "completed", "duration_seconds": 45, "timestamp": 1735731000.0, "created_at": "2026-01-01T11:30:00Z"}, - {"id": 3, "remote_identity_hash": "10b981", "remote_identity_name": "Regional Hub", "is_incoming": 1, "status": "missed", "duration_seconds": 0, "timestamp": 1735729200.0, "created_at": "2026-01-01T11:00:00Z"}, - {"id": 4, "remote_identity_hash": "ef4444", "remote_identity_name": "Echo Bot", "is_incoming": 0, "status": "failed", "duration_seconds": 0, "timestamp": 1735727400.0, "created_at": "2026-01-01T10:30:00Z"}, - {"id": 5, "remote_identity_hash": "a1b2c3", "remote_identity_name": "Charlie", "is_incoming": 1, "status": "completed", "duration_seconds": 320, "timestamp": 1735725600.0, "created_at": "2026-01-01T10:00:00Z"} - ]}'; - add_header Content-Type application/json; - } - - location /api/v1/favourites { - set $aspect_filter $arg_aspect; - if ($aspect_filter = "lxmf.delivery") { - return 200 '{"favourites": [ - {"id": 1, "destination_hash": "8b5cf6", "display_name": "Alice", "aspect": "lxmf.delivery", "created_at": "2026-01-01T08:00:00Z", "updated_at": "2026-01-01T08:00:00Z"}, - {"id": 2, "destination_hash": "3b82f6", "display_name": "Bob", "aspect": "lxmf.delivery", "created_at": "2026-01-01T08:00:00Z", "updated_at": "2026-01-01T08:00:00Z"} - ]}'; - add_header Content-Type application/json; - } - if ($aspect_filter = "nomadnetwork.node") { - return 200 '{"favourites": [ - {"id": 3, "destination_hash": "10b981", "display_name": "Regional Hub", "aspect": "nomadnetwork.node", "created_at": "2026-01-01T08:00:00Z", "updated_at": "2026-01-01T08:00:00Z"}, - {"id": 4, "destination_hash": "f68b5c", "display_name": "Nomad Portal", "aspect": "nomadnetwork.node", "created_at": "2026-01-01T08:00:00Z", "updated_at": "2026-01-01T08:00:00Z"} - ]}'; - add_header Content-Type application/json; - } - return 200 '{"favourites": [ - {"id": 1, "destination_hash": "8b5cf6", "display_name": "Alice", "aspect": "lxmf.delivery", "created_at": "2026-01-01T08:00:00Z", "updated_at": "2026-01-01T08:00:00Z"}, - {"id": 2, "destination_hash": "3b82f6", "display_name": "Bob", "aspect": "lxmf.delivery", "created_at": "2026-01-01T08:00:00Z", "updated_at": "2026-01-01T08:00:00Z"}, - {"id": 3, "destination_hash": "10b981", "display_name": "Regional Hub", "aspect": "nomadnetwork.node", "created_at": "2026-01-01T08:00:00Z", "updated_at": "2026-01-01T08:00:00Z"}, - {"id": 4, "destination_hash": "f68b5c", "display_name": "Nomad Portal", "aspect": "nomadnetwork.node", "created_at": "2026-01-01T08:00:00Z", "updated_at": "2026-01-01T08:00:00Z"} - ]}'; - add_header Content-Type application/json; - } - - location /api/v1/lxmf/propagation-node/status { - return 200 '{"propagation_node_status": {"state": "idle", "connected": true, "address": "8b5cf6", "messages_received": 123, "messages_sent": 45}}'; - add_header Content-Type application/json; - } - - location /api/v1/announces { - return 200 '{"announces": [ - {"destination_hash": "8b5cf6", "display_name": "Alice", "aspect": "lxmf.delivery", "updated_at": "2026-01-01T12:00:00Z", "hops": 1, "snr": 12.5}, - {"destination_hash": "3b82f6", "display_name": "Bob", "aspect": "lxmf.delivery", "updated_at": "2026-01-01T11:30:00Z", "hops": 2, "snr": 8.2}, - {"destination_hash": "10b981", "display_name": "Regional Hub", "aspect": "nomadnetwork.node", "updated_at": "2026-01-01T10:00:00Z", "hops": 1, "snr": 15.0}, - {"destination_hash": "ef4444", "display_name": "Echo Bot", "aspect": "lxmf.delivery", "updated_at": "2026-01-01T09:00:00Z", "hops": 3}, - {"destination_hash": "f68b5c", "display_name": "Nomad Portal", "aspect": "nomadnetwork.node", "updated_at": "2026-01-01T12:05:00Z", "hops": 1}, - {"destination_hash": "a1b2c3", "display_name": "Charlie", "aspect": "lxmf.delivery", "updated_at": "2026-01-01T08:00:00Z", "hops": 4}, - {"destination_hash": "d4e5f6", "display_name": "Mesh Gateway", "aspect": "nomadnetwork.node", "updated_at": "2026-01-01T12:10:00Z", "hops": 1} - ], "total_count": 7}'; - add_header Content-Type application/json; - } - - location /api/v1/path-table { - return 200 '{"path_table": [ - {"hash": "8b5cf6", "hops": 1, "interface": "AutoInterface[RNode]"}, - {"hash": "3b82f6", "hops": 2, "interface": "AutoInterface[TCP]"}, - {"hash": "10b981", "hops": 1, "interface": "AutoInterface[RNode]"}, - {"hash": "ef4444", "hops": 3, "interface": "AutoInterface[TCP]"}, - {"hash": "f68b5c", "hops": 1, "interface": "AutoInterface[TCP]"}, - {"hash": "a1b2c3", "hops": 4, "interface": "AutoInterface[UDP]"}, - {"hash": "d4e5f6", "hops": 1, "interface": "AutoInterface[UDP]"} - ], "total_count": 7}'; - add_header Content-Type application/json; - } - - location /api/v1/notifications { - return 200 '{"notifications": [ - {"id": 1, "type": "new_message", "title": "New Message", "content": "Alice: Hello from the mesh!", "created_at": "2026-01-01T12:00:00Z"} - ]}'; - add_header Content-Type application/json; - } - - location /api/v1/announce { - return 200 '{"message": "Announce sent (Demo Mode)"}'; - add_header Content-Type application/json; - } - - location /api/v1/lxmf/propagation-node/sync { - return 200 '{"message": "Sync started (Demo Mode)"}'; - add_header Content-Type application/json; - } - - location /api/v1/identity/backup/base32 { - return 200 '{"identity_base32": "demo_base32_identity_key_do_not_use"}'; - add_header Content-Type application/json; - } - - # Catch-all for other API calls - location /api { - return 404 '{"error": "Endpoint not available in demo mode"}'; - add_header Content-Type application/json; - } - - # WebSocket handler for demo mode - location /ws { - # For non-WebSocket requests, return a simple message - if ($http_upgrade != "websocket") { - add_header Content-Type text/plain; - return 200 "WebSocket endpoint (Demo Mode - WebSocket not available)"; - } - - # For WebSocket upgrade requests, return 426 Upgrade Required - # This is more appropriate than 503 and prevents constant reconnection attempts - add_header Upgrade websocket; - add_header Connection Upgrade; - return 426; - } - - # Error pages - error_page 500 502 503 504 /50x.html; - location = /50x.html { - root /usr/share/nginx/html; - } -}