#!/bin/bash # =========================== # MY Network v2.0 - Regular Node Deployment # Connects to existing network via bootstrap nodes # Optional: Telegram bots, public domain, SSL # =========================== set -e echo "=========================================================" echo "🌐 MY NETWORK v2.0 - REGULAR NODE DEPLOYMENT" echo "Connects to: my-public-node-3.projscale.dev" echo "Components: MY Network + Optional (bots, web, converter)" echo "=========================================================" # =========================== # CONFIGURATION INPUT # =========================== echo "" echo "=== NODE CONFIGURATION ===" # Get node configuration read -p "Enter node name (default: my-node-$(date +%s)): " NODE_NAME NODE_NAME=${NODE_NAME:-"my-node-$(date +%s)"} read -p "Enter public domain (optional, leave empty for private node): " PUBLIC_DOMAIN read -p "Enter Telegram Bot Token (optional): " TELEGRAM_BOT_TOKEN read -p "Enter Uploader Bot Token (optional): " UPLOADER_BOT_TOKEN # Determine node type based on configuration if [ -n "$PUBLIC_DOMAIN" ]; then NODE_TYPE="public_regular" PUBLIC_NODE="true" echo "🌐 Configuring as PUBLIC regular node with domain: $PUBLIC_DOMAIN" else NODE_TYPE="private_regular" PUBLIC_NODE="false" echo "🔒 Configuring as PRIVATE regular node" fi # Bot configuration if [ -n "$TELEGRAM_BOT_TOKEN" ] || [ -n "$UPLOADER_BOT_TOKEN" ]; then ENABLE_BOTS="true" echo "🤖 Telegram bots will be enabled" else ENABLE_BOTS="false" echo "🤖 Telegram bots will be disabled" fi # Ports MY_NETWORK_PORT="15100" WEB_CLIENT_PORT="3000" CONVERTER_PORT="8080" INSTALL_DIR="/opt/my-network-$NODE_NAME" echo "" echo "=== FINAL CONFIGURATION ===" echo "Node Name: $NODE_NAME" echo "Node Type: $NODE_TYPE" echo "Public Domain: ${PUBLIC_DOMAIN:-"None (private node)"}" echo "Enable Bots: $ENABLE_BOTS" echo "Install Directory: $INSTALL_DIR" read -p "Continue with this configuration? (y/N): " CONFIRM if [[ ! "$CONFIRM" =~ ^[Yy]$ ]]; then echo "❌ Deployment cancelled" exit 1 fi # =========================== # SYSTEM PREPARATION # =========================== echo "" echo "=== 1. SYSTEM PREPARATION ===" echo "📦 Installing dependencies..." apt-get update -y apt-get install -y curl wget unzip git jq echo "🐳 Installing Docker and Docker Compose..." if ! command -v docker &> /dev/null; then curl -fsSL https://get.docker.com -o get-docker.sh sh get-docker.sh systemctl enable docker systemctl start docker rm -f get-docker.sh fi if ! command -v docker-compose &> /dev/null; then curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose fi echo "✅ System preparation completed" # =========================== # BOOTSTRAP DISCOVERY # =========================== echo "" echo "=== 2. BOOTSTRAP DISCOVERY ===" echo "🔍 Connecting to main bootstrap node..." BOOTSTRAP_URL="https://my-public-node-3.projscale.dev/api/bootstrap" if ! curl -f -s "$BOOTSTRAP_URL" > /dev/null; then echo "❌ Cannot connect to bootstrap node: $BOOTSTRAP_URL" echo "Please ensure the main bootstrap node is running" exit 1 fi echo "📡 Fetching network configuration..." BOOTSTRAP_CONFIG=$(curl -s "$BOOTSTRAP_URL" | jq -r '.') if [ "$BOOTSTRAP_CONFIG" = "null" ]; then echo "❌ Failed to fetch bootstrap configuration" exit 1 fi echo "✅ Bootstrap discovery completed" # =========================== # PROJECT DEPLOYMENT # =========================== echo "" echo "=== 3. PROJECT DEPLOYMENT ===" echo "📁 Creating project structure..." mkdir -p $INSTALL_DIR/{data,logs} # Copy current project if in project directory CURRENT_DIR=$(pwd) if [ -f "$CURRENT_DIR/start_my_network.py" ]; then echo "📤 Copying project files..." cp -r $CURRENT_DIR/* $INSTALL_DIR/ fi cd $INSTALL_DIR echo "⚙️ Creating regular node configuration..." # Regular Node .env cat > $INSTALL_DIR/.env << EOF # MY Network v2.0 - Regular Node Configuration MY_NETWORK_VERSION=v2.0 MY_NETWORK_PORT=$MY_NETWORK_PORT MY_NETWORK_HOST=0.0.0.0 # Node Configuration NODE_NAME=$NODE_NAME NODE_TYPE=$NODE_TYPE BOOTSTRAP_NODE=false PUBLIC_NODE=$PUBLIC_NODE # Production Database DATABASE_URL=sqlite+aiosqlite:///./data/my_network_${NODE_NAME}.db DB_TYPE=sqlite # Security SECRET_KEY=$(openssl rand -hex 32) JWT_SECRET=$(openssl rand -hex 32) # API Configuration API_VERSION=v1 DEBUG=false # Bootstrap Configuration BOOTSTRAP_CONFIG_PATH=bootstrap_regular.json MAIN_BOOTSTRAP_URL=https://my-public-node-3.projscale.dev # Monitoring ENABLE_MONITORING=true MONITORING_THEME=matrix # Network Settings - Regular Node MAX_PEERS=100 SYNC_INTERVAL=30 PEER_DISCOVERY_INTERVAL=60 BOOTSTRAP_TIMEOUT=30 # Environment ENVIRONMENT=production LOG_LEVEL=INFO # Public Domain Configuration $([ -n "$PUBLIC_DOMAIN" ] && cat << DOMAIN_EOF HOST_DOMAIN=$PUBLIC_DOMAIN EXTERNAL_URL=https://$PUBLIC_DOMAIN SSL_ENABLED=true SSL_CERT_PATH=/etc/letsencrypt/live/$PUBLIC_DOMAIN/fullchain.pem SSL_KEY_PATH=/etc/letsencrypt/live/$PUBLIC_DOMAIN/privkey.pem DOMAIN_EOF ) # Service Configuration WEB2_CLIENT_PORT=$WEB_CLIENT_PORT WEB2_CLIENT_HOST=0.0.0.0 CONVERTER_PORT=$CONVERTER_PORT CONVERTER_HOST=0.0.0.0 # Telegram Bots Configuration ENABLE_TELEGRAM_BOTS=$ENABLE_BOTS $([ -n "$TELEGRAM_BOT_TOKEN" ] && echo "TELEGRAM_BOT_TOKEN=$TELEGRAM_BOT_TOKEN") $([ -n "$UPLOADER_BOT_TOKEN" ] && echo "UPLOADER_BOT_TOKEN=$UPLOADER_BOT_TOKEN") EOF # Regular Node Bootstrap Config cat > $INSTALL_DIR/bootstrap_regular.json << EOF { "network": { "name": "MY Network v2.0 Regular Node - $NODE_NAME", "version": "2.0", "protocol_version": "1.0", "port": $MY_NETWORK_PORT, "host": "0.0.0.0", $([ -n "$PUBLIC_DOMAIN" ] && echo "\"external_url\": \"https://$PUBLIC_DOMAIN\",") "node_name": "$NODE_NAME", "node_type": "$NODE_TYPE", "is_bootstrap": false, "is_public": $PUBLIC_NODE }, "bootstrap_nodes": [ { "id": "main-bootstrap-node", "host": "my-public-node-3.projscale.dev", "port": 15100, "public_key": "main-bootstrap-key", "weight": 1000, "priority": 1, "region": "global", "node_type": "main_bootstrap" } ], "discovery": { "bootstrap_url": "https://my-public-node-3.projscale.dev/api/bootstrap", "peer_discovery_url": "https://my-public-node-3.projscale.dev/api/peers", "sync_url": "https://my-public-node-3.projscale.dev/api/sync" }, "security": { "encryption_enabled": true, "authentication_required": true, "ssl_enabled": $([ -n "$PUBLIC_DOMAIN" ] && echo "true" || echo "false"), "rate_limiting": { "requests_per_minute": 1000, "burst_size": 100 } }, "api": { "endpoints": { "health": "/health", "metrics": "/api/metrics", "monitor": "/api/my/monitor/", "websocket": "/api/my/monitor/ws", "sync": "/api/sync", "peers": "/api/peers" }, "cors": { "enabled": true, "origins": $([ -n "$PUBLIC_DOMAIN" ] && echo "[\"https://$PUBLIC_DOMAIN\", \"http://localhost:3000\"]" || echo "[\"http://localhost:3000\"]") } }, "monitoring": { "enabled": true, "theme": "matrix", "real_time_updates": true, "websocket_path": "/api/my/monitor/ws", "dashboard_path": "/api/my/monitor/", "metrics_enabled": true, "public_metrics": $PUBLIC_NODE }, "storage": { "type": "sqlite", "path": "./data/my_network_${NODE_NAME}.db", "backup_enabled": true, "backup_interval": 3600 }, "p2p": { "max_peers": 100, "sync_interval": 30, "discovery_interval": 60, "connection_timeout": 30, "keep_alive": true, "bootstrap_timeout": 30 }, "logging": { "level": "INFO", "file_path": "./logs/my_network_${NODE_NAME}.log", "max_size": "100MB", "backup_count": 5 }, "services": { "web2_client": { "enabled": $PUBLIC_NODE, "port": $WEB_CLIENT_PORT, "host": "0.0.0.0" }, "converter": { "enabled": true, "port": $CONVERTER_PORT, "host": "0.0.0.0" }, "telegram_bots": { "enabled": $ENABLE_BOTS, "client_bot": $([ -n "$TELEGRAM_BOT_TOKEN" ] && echo "true" || echo "false"), "uploader_bot": $([ -n "$UPLOADER_BOT_TOKEN" ] && echo "true" || echo "false") } } } EOF # Docker Compose for Regular Node cat > $INSTALL_DIR/docker-compose.yml << EOF version: '3.8' services: # MY Network v2.0 Core my-network: build: . container_name: my-network-$NODE_NAME restart: unless-stopped ports: - "$MY_NETWORK_PORT:$MY_NETWORK_PORT" volumes: - ./data:/app/data - ./logs:/app/logs - ./.env:/app/.env - ./bootstrap_regular.json:/app/bootstrap.json environment: - NODE_TYPE=$NODE_TYPE - BOOTSTRAP_NODE=false - NODE_NAME=$NODE_NAME networks: - mynetwork $([ "$PUBLIC_NODE" = "true" ] && cat << SERVICES_EOF depends_on: - web2-client - converter # Web2 Client (only for public nodes) web2-client: build: ./web2-client container_name: web2-client-$NODE_NAME restart: unless-stopped ports: - "$WEB_CLIENT_PORT:3000" environment: - NEXT_PUBLIC_API_URL=$([ -n "$PUBLIC_DOMAIN" ] && echo "https://$PUBLIC_DOMAIN" || echo "http://localhost:$MY_NETWORK_PORT") - NEXT_PUBLIC_WS_URL=$([ -n "$PUBLIC_DOMAIN" ] && echo "wss://$PUBLIC_DOMAIN" || echo "ws://localhost:$MY_NETWORK_PORT") networks: - mynetwork SERVICES_EOF ) # Converter Module converter: build: ./converter-module container_name: converter-$NODE_NAME restart: unless-stopped ports: - "$CONVERTER_PORT:8080" volumes: - ./data/converter:/app/data networks: - mynetwork networks: mynetwork: driver: bridge EOF echo "✅ Project deployment completed" # =========================== # PUBLIC NODE SETUP # =========================== if [ "$PUBLIC_NODE" = "true" ] && [ -n "$PUBLIC_DOMAIN" ]; then echo "" echo "=== 4. PUBLIC NODE SETUP ===" echo "🔥 Configuring firewall..." apt-get install -y ufw ufw --force reset ufw default deny incoming ufw default allow outgoing ufw allow 22/tcp ufw allow 80/tcp ufw allow 443/tcp ufw allow $MY_NETWORK_PORT/tcp ufw allow $WEB_CLIENT_PORT/tcp ufw allow $CONVERTER_PORT/tcp ufw --force enable echo "🌐 Installing and configuring Nginx..." apt-get install -y nginx certbot python3-certbot-nginx cat > /etc/nginx/sites-available/my-network-$NODE_NAME << EOF server { listen 80; server_name $PUBLIC_DOMAIN; return 301 https://\$server_name\$request_uri; } server { listen 443 ssl http2; server_name $PUBLIC_DOMAIN; ssl_certificate /etc/letsencrypt/live/$PUBLIC_DOMAIN/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/$PUBLIC_DOMAIN/privkey.pem; add_header X-Frame-Options DENY; add_header X-Content-Type-Options nosniff; add_header X-XSS-Protection "1; mode=block"; location / { proxy_pass http://localhost:$WEB_CLIENT_PORT; 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; } location /api/ { proxy_pass http://localhost:$MY_NETWORK_PORT/api/; 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; } location /health { proxy_pass http://localhost:$MY_NETWORK_PORT/health; proxy_set_header Host \$host; proxy_set_header X-Real-IP \$remote_addr; } location /monitor/ { proxy_pass http://localhost:$MY_NETWORK_PORT/api/my/monitor/; proxy_set_header Host \$host; proxy_set_header X-Real-IP \$remote_addr; } location /ws/monitor { proxy_pass http://localhost:$MY_NETWORK_PORT/api/my/monitor/ws; proxy_http_version 1.1; proxy_set_header Upgrade \$http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host \$host; } location /convert/ { proxy_pass http://localhost:$CONVERTER_PORT/; proxy_set_header Host \$host; proxy_set_header X-Real-IP \$remote_addr; } } EOF ln -sf /etc/nginx/sites-available/my-network-$NODE_NAME /etc/nginx/sites-enabled/ rm -f /etc/nginx/sites-enabled/default nginx -t echo "🔒 Obtaining SSL certificate..." certbot --nginx -d $PUBLIC_DOMAIN --non-interactive --agree-tos --email admin@$PUBLIC_DOMAIN --redirect crontab -l 2>/dev/null | { cat; echo '0 12 * * * /usr/bin/certbot renew --quiet'; } | crontab - echo "✅ Public node setup completed" else echo "" echo "=== 4. PRIVATE NODE SETUP ===" echo "🔒 Configuring as private node (no public access)" fi # =========================== # CONTAINER DEPLOYMENT # =========================== echo "" echo "=== 5. CONTAINER DEPLOYMENT ===" echo "🚀 Building and starting containers..." cd $INSTALL_DIR # Stop existing services if systemctl is-active --quiet my-network-$NODE_NAME; then systemctl stop my-network-$NODE_NAME fi # Build and start containers docker-compose down 2>/dev/null || true docker-compose up -d --build echo "✅ Containers deployed" # =========================== # SYSTEMD SERVICE # =========================== echo "" echo "=== 6. SYSTEMD SERVICE ===" echo "📊 Creating systemd service..." cat > /etc/systemd/system/my-network-$NODE_NAME.service << EOF [Unit] Description=MY Network v2.0 Regular Node - $NODE_NAME After=docker.service network.target Requires=docker.service [Service] Type=oneshot RemainAfterExit=yes WorkingDirectory=$INSTALL_DIR ExecStart=/usr/local/bin/docker-compose up -d ExecStop=/usr/local/bin/docker-compose down ExecReload=/usr/local/bin/docker-compose restart TimeoutStartSec=300 TimeoutStopSec=120 User=root Environment="COMPOSE_PROJECT_NAME=my-network-$NODE_NAME" [Install] WantedBy=multi-user.target EOF systemctl daemon-reload systemctl enable my-network-$NODE_NAME systemctl start my-network-$NODE_NAME echo "✅ SystemD service created" # =========================== # NETWORK SYNCHRONIZATION # =========================== echo "" echo "=== 7. NETWORK SYNCHRONIZATION ===" echo "⏳ Waiting for services to start..." sleep 30 echo "🔄 Initiating network synchronization..." if curl -f -s "http://localhost:$MY_NETWORK_PORT/health" > /dev/null; then echo "✅ Node is running locally" # Register with bootstrap node echo "📡 Registering with bootstrap node..." REGISTER_DATA="{\"node_name\":\"$NODE_NAME\",\"node_type\":\"$NODE_TYPE\",\"public_node\":$PUBLIC_NODE" if [ -n "$PUBLIC_DOMAIN" ]; then REGISTER_DATA+=",\"external_url\":\"https://$PUBLIC_DOMAIN\"" fi REGISTER_DATA+="}" curl -X POST "https://my-public-node-3.projscale.dev/api/register" \ -H "Content-Type: application/json" \ -d "$REGISTER_DATA" || echo "Registration will retry automatically" echo "✅ Network synchronization initiated" else echo "⚠️ Node starting up, synchronization will begin automatically" fi # =========================== # FINAL VERIFICATION # =========================== echo "" echo "=== 8. FINAL VERIFICATION ===" echo "🔍 Testing local endpoints..." if curl -f -s "http://localhost:$MY_NETWORK_PORT/health" > /dev/null; then echo "✅ Local health check - OK" else echo "❌ Local health check - FAILED" fi if [ "$PUBLIC_NODE" = "true" ] && [ -n "$PUBLIC_DOMAIN" ]; then systemctl restart nginx sleep 10 echo "🔍 Testing public endpoints..." if curl -f -s -k "https://$PUBLIC_DOMAIN/health" > /dev/null; then echo "✅ Public health check - OK" else echo "❌ Public health check - FAILED" fi fi # =========================== # DEPLOYMENT SUMMARY # =========================== echo "" echo "============================================================" echo "🎉 MY NETWORK v2.0 REGULAR NODE DEPLOYMENT COMPLETE!" echo "============================================================" echo "" echo "📋 Node Information:" echo " • Node Name: $NODE_NAME" echo " • Node Type: $NODE_TYPE" echo " • Public Node: $PUBLIC_NODE" echo " • Telegram Bots: $ENABLE_BOTS" echo "" if [ "$PUBLIC_NODE" = "true" ] && [ -n "$PUBLIC_DOMAIN" ]; then echo "🌐 Public Access Points:" echo " • Web Interface: https://$PUBLIC_DOMAIN/" echo " • Matrix Dashboard: https://$PUBLIC_DOMAIN/monitor/" echo " • Health Check: https://$PUBLIC_DOMAIN/health" echo " • API: https://$PUBLIC_DOMAIN/api/" echo "" fi echo "🔧 Local Access:" echo " • Health Check: http://localhost:$MY_NETWORK_PORT/health" echo " • API: http://localhost:$MY_NETWORK_PORT/api/" echo " • Dashboard: http://localhost:$MY_NETWORK_PORT/api/my/monitor/" echo "" echo "🛠️ Management Commands:" echo " • View logs: docker-compose -f $INSTALL_DIR/docker-compose.yml logs -f" echo " • Restart: systemctl restart my-network-$NODE_NAME" echo " • Status: systemctl status my-network-$NODE_NAME" echo " • Containers: docker-compose ps" echo "" echo "🌐 Network Connection:" echo " • Bootstrap Node: https://my-public-node-3.projscale.dev" echo " • Sync Status: Check dashboard for peer connections" echo "" echo "✅ Regular node is live and syncing with MY Network v2.0!"