FROM ubuntu:22.04 # Prevent interactive prompts ENV DEBIAN_FRONTEND=noninteractive # Install dependencies RUN apt-get update && apt-get install -y \ wget \ unzip \ xvfb \ python3 \ python3-pip \ curl \ libgtk-3-0 \ libnotify4 \ libnss3 \ libxss1 \ libxtst6 \ xdg-utils \ libatspi2.0-0 \ libdrm2 \ libgbm1 \ libasound2 \ && rm -rf /var/lib/apt/lists/* # Install Python packages for keep-alive RUN pip3 install flask requests APScheduler # Set working directory WORKDIR /app # Download and extract FeelingSurf (use x64 version for Hugging Face) RUN wget -q https://github.com/feelingsurf/viewer/releases/download/2.5.0/FeelingSurfViewer-linux-x64-2.5.0.zip && \ unzip -q FeelingSurfViewer-linux-x64-2.5.0.zip && \ rm FeelingSurfViewer-linux-x64-2.5.0.zip && \ chmod +x FeelingSurfViewer # Create enhanced status page with auto-refresh and external ping trigger RUN echo '\n\ \n\ \n\ FeelingSurf Viewer - Always Active\n\ \n\ \n\ \n\ \n\ \n\
\n\
✅ FeelingSurf Viewer Active
\n\
\n\

Status: 🟢 Always Running

\n\

User: alllogin

\n\

Space URL: huijio/testsurf

\n\

Mode: Headless Browser

\n\

Version: 2.5.0

\n\

Last Activity:

\n\

Internal Pings: 0

\n\
\n\ 🛡️ Anti-Sleep Features:
\n\ • Auto-refresh every 30 seconds
\n\ • Internal keep-alive pings (25s interval)
\n\ • External self-ping (2 min interval)
\n\ • UptimeRobot monitoring ready
\n\ • Continuous activity logging\n\
\n\
\n\ 🌐 External Monitoring Endpoint:
\n\ https://huijio-testsurf.hf.space/health
\n\ Configure UptimeRobot or similar service to ping this URL every 5 minutes\n\
\n\
\n\
\n\
\n\ \n\ ' > /app/status.html # Create Flask keep-alive server with aggressive anti-sleep RUN echo 'from flask import Flask, send_file, jsonify\n\ from apscheduler.schedulers.background import BackgroundScheduler\n\ import requests\n\ import os\n\ import logging\n\ from datetime import datetime\n\ import threading\n\ import time\n\ \n\ app = Flask(__name__)\n\ logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")\n\ \n\ # Store last activity time and ping statistics\n\ last_activity = datetime.now()\n\ ping_count = {"internal": 0, "external": 0, "self": 0}\n\ space_url = "https://huijio-testsurf.hf.space"\n\ \n\ @app.route("/")\n\ def index():\n\ global last_activity\n\ last_activity = datetime.now()\n\ ping_count["external"] += 1\n\ external_count = ping_count["external"]\n\ app.logger.info(f"[INDEX] Page accessed - External pings: {external_count}")\n\ return send_file("/app/status.html")\n\ \n\ @app.route("/ping")\n\ def ping():\n\ global last_activity\n\ last_activity = datetime.now()\n\ ping_count["internal"] += 1\n\ return jsonify({\n\ "status": "alive",\n\ "time": str(last_activity),\n\ "ping_count": ping_count\n\ })\n\ \n\ @app.route("/health")\n\ def health():\n\ global last_activity\n\ last_activity = datetime.now()\n\ uptime = datetime.now() - start_time\n\ return jsonify({\n\ "status": "healthy",\n\ "last_activity": str(last_activity),\n\ "uptime_seconds": int(uptime.total_seconds()),\n\ "ping_stats": ping_count,\n\ "space_url": space_url\n\ })\n\ \n\ @app.route("/wake")\n\ def wake():\n\ """Endpoint specifically for external services to wake the space"""\n\ global last_activity\n\ last_activity = datetime.now()\n\ app.logger.info("[WAKE] External wake call received")\n\ return jsonify({"status": "awake", "time": str(last_activity)})\n\ \n\ # Aggressive self-ping function\n\ def self_ping():\n\ try:\n\ # Ping multiple endpoints to ensure activity\n\ endpoints = ["/ping", "/health"]\n\ for endpoint in endpoints:\n\ try:\n\ response = requests.get(f"http://localhost:7860{endpoint}", timeout=5)\n\ ping_count["self"] += 1\n\ self_count = ping_count["self"]\n\ app.logger.info(f"[SELF-PING] {endpoint} successful - Total self-pings: {self_count}")\n\ except Exception as e:\n\ app.logger.error(f"[SELF-PING] {endpoint} failed: {e}")\n\ except Exception as e:\n\ app.logger.error(f"[SELF-PING] Critical error: {e}")\n\ \n\ # External self-ping (ping the actual Hugging Face URL)\n\ def external_self_ping():\n\ try:\n\ response = requests.get(f"{space_url}/wake", timeout=10)\n\ app.logger.info(f"[EXTERNAL-PING] Space wake successful: {response.status_code}")\n\ except Exception as e:\n\ app.logger.warning(f"[EXTERNAL-PING] Could not reach external URL: {e}")\n\ \n\ # Continuous activity generator\n\ def generate_activity():\n\ """Generate continuous low-level activity to prevent sleep"""\n\ while True:\n\ try:\n\ # Simple calculation to generate CPU activity\n\ _ = sum(range(1000))\n\ time.sleep(60) # Every minute\n\ except Exception as e:\n\ app.logger.error(f"[ACTIVITY] Error: {e}")\n\ \n\ # Store start time\n\ start_time = datetime.now()\n\ \n\ # Schedule multiple keep-alive mechanisms\n\ scheduler = BackgroundScheduler()\n\ \n\ # Internal self-ping every 1 minute\n\ scheduler.add_job(func=self_ping, trigger="interval", seconds=60, id="self_ping")\n\ \n\ # External self-ping every 3 minutes\n\ scheduler.add_job(func=external_self_ping, trigger="interval", seconds=180, id="external_ping")\n\ \n\ # Log status every 5 minutes\n\ def log_status():\n\ app.logger.info(f"[STATUS] Uptime: {datetime.now() - start_time}, Pings: {ping_count}")\n\ \n\ scheduler.add_job(func=log_status, trigger="interval", seconds=300, id="status_log")\n\ \n\ scheduler.start()\n\ \n\ # Start activity generator in background thread\n\ activity_thread = threading.Thread(target=generate_activity, daemon=True)\n\ activity_thread.start()\n\ \n\ app.logger.info("=" * 50)\n\ app.logger.info("🛡️ ANTI-SLEEP PROTECTION ACTIVATED")\n\ app.logger.info(f"🌐 Space URL: {space_url}")\n\ app.logger.info("✓ Internal self-ping: Every 60 seconds")\n\ app.logger.info("✓ External self-ping: Every 3 minutes")\n\ app.logger.info("✓ Activity generator: Running")\n\ app.logger.info("✓ Status logging: Every 5 minutes")\n\ app.logger.info("=" * 50)\n\ \n\ if __name__ == "__main__":\n\ app.run(host="0.0.0.0", port=7860)' > /app/keep_alive_server.py # Create startup script with enhanced monitoring RUN echo '#!/bin/bash\n\ echo "🚀 Starting FeelingSurf Viewer with Anti-Sleep Protection..."\n\ echo "================================================"\n\ \n\ # Get current Hugging Face IP address\n\ echo "=== Current Hugging Face Space Information ==="\n\ CURRENT_IP=$(curl -s -H "Accept: application/json" https://api.ipify.org?format=json | grep -oE "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}")\n\ if [ -n "$CURRENT_IP" ]; then\n\ echo "🌐 Current Public IP: $CURRENT_IP"\n\ echo "📍 Hugging Face Space IP: $CURRENT_IP"\n\ else\n\ echo "⚠️ Could not determine current IP address"\n\ fi\n\ echo "🌐 Space URL: https://huijio-testsurf.hf.space"\n\ echo "🔗 Health Check: https://huijio-testsurf.hf.space/health"\n\ echo "============================================="\n\ echo ""\n\ \n\ # Start Xvfb (virtual display)\n\ echo "🖥️ Starting virtual display..."\n\ Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &\n\ export DISPLAY=:99\n\ sleep 2\n\ \n\ # Start FeelingSurf in background\n\ echo "🌊 Starting FeelingSurf Viewer..."\n\ cd /app\n\ ./FeelingSurfViewer --access-token d6e659ba6b59c9866fba8ff01bc56e04 --no-sandbox 2>&1 | tee /tmp/viewer.log &\n\ sleep 5\n\ \n\ # Start activity monitor\n\ echo "📊 Starting activity monitor..."\n\ (\n\ while true; do\n\ echo "[$(date)] ✓ System active - Memory: $(free -h | grep Mem | awk '\''{print $3}'\'' ) CPU Load: $(uptime | awk -F'\''load average:'\'' '\''{ print $2 }'\'' | cut -d, -f1)"\n\ sleep 300 # Log every 5 minutes\n\ done\n\ ) &\n\ \n\ # Start Flask keep-alive server\n\ echo "🛡️ Starting Flask keep-alive server on port 7860..."\n\ echo ""\n\ echo "=== Anti-Sleep Protection Active ==="\n\ echo "✓ Page auto-refresh: 30 seconds"\n\ echo "✓ Internal self-ping: 60 seconds"\n\ echo "✓ External self-ping: 3 minutes"\n\ echo "✓ Activity generator: Running"\n\ echo "✓ Health monitoring active"\n\ echo "==================================="\n\ echo ""\n\ echo "=== Setup External Monitoring (Recommended) ==="\n\ echo "1. Visit: https://uptimerobot.com (Free tier available)"\n\ echo "2. Add HTTP(s) monitor:"\n\ echo " URL: https://huijio-testsurf.hf.space/health"\n\ echo " Interval: 5 minutes"\n\ echo "3. Alternative services: Uptime Kuma, Better Uptime, Pingdom"\n\ echo "==============================================="\n\ echo ""\n\ echo "=== FeelingSurf Viewer Logs ==="\n\ tail -f /tmp/viewer.log &\n\ \n\ # Start Flask server (this keeps the container running)\n\ python3 /app/keep_alive_server.py' > /app/start.sh && \ chmod +x /app/start.sh # Set environment ENV access_token="d6e659ba6b59c9866fba8ff01bc56e04" ENV DISPLAY=:99 ENV PYTHONUNBUFFERED=1 EXPOSE 7860 CMD ["/app/start.sh"]