Spaces:
Sleeping
Sleeping
| FROM node:22-slim | |
| # Install system dependencies including Chromium for browser support | |
| RUN apt-get update && apt-get install -y \ | |
| git \ | |
| bash \ | |
| curl \ | |
| jq \ | |
| python3 \ | |
| python3-pip \ | |
| python3-venv \ | |
| chromium \ | |
| chromium-driver \ | |
| fonts-liberation \ | |
| libasound2 \ | |
| libatk-bridge2.0-0 \ | |
| libatk1.0-0 \ | |
| libatspi2.0-0 \ | |
| libcups2 \ | |
| libdbus-1-3 \ | |
| libdrm2 \ | |
| libgbm1 \ | |
| libgtk-3-0 \ | |
| libnspr4 \ | |
| libnss3 \ | |
| libwayland-client0 \ | |
| libxcomposite1 \ | |
| libxdamage1 \ | |
| libxfixes3 \ | |
| libxkbcommon0 \ | |
| libxrandr2 \ | |
| xdg-utils \ | |
| && rm -rf /var/lib/apt/lists/* | |
| RUN npm install -g openclaw@latest | |
| # Create Python virtual environment and install PostgreSQL driver | |
| RUN python3 -m venv /opt/venv | |
| ENV PATH="/opt/venv/bin:$PATH" | |
| RUN pip install --no-cache-dir psycopg2-binary | |
| RUN mkdir -p /root/.openclaw | |
| EXPOSE 18789 | |
| # Python script for DB operations with Neon support | |
| RUN cat > /usr/local/bin/db-manager.py << 'PYSCRIPT' | |
| #!/usr/bin/env python3 | |
| import psycopg2 | |
| import json | |
| import sys | |
| import os | |
| def get_connection(): | |
| # Use DATABASE_URL if provided (Neon), otherwise use individual params | |
| database_url = os.environ.get('DATABASE_URL') | |
| if database_url: | |
| return psycopg2.connect(database_url) | |
| else: | |
| return psycopg2.connect( | |
| host=os.environ.get('POSTGRES_HOST', 'localhost'), | |
| port=os.environ.get('POSTGRES_PORT', '5432'), | |
| database=os.environ.get('POSTGRES_DB', 'openclaw_db'), | |
| user=os.environ.get('POSTGRES_USER', 'openclaw'), | |
| password=os.environ.get('POSTGRES_PASSWORD') | |
| ) | |
| def load_config(): | |
| """Load OpenClaw config from PostgreSQL""" | |
| try: | |
| conn = get_connection() | |
| cur = conn.cursor() | |
| cur.execute("SELECT config_value FROM openclaw_config WHERE config_key = 'openclaw_main'") | |
| row = cur.fetchone() | |
| cur.close() | |
| conn.close() | |
| if row: | |
| return row[0] | |
| return None | |
| except Exception as e: | |
| print(f"Error loading config from DB: {e}", file=sys.stderr) | |
| return None | |
| def save_config(config_json): | |
| """Save OpenClaw config to PostgreSQL""" | |
| try: | |
| conn = get_connection() | |
| cur = conn.cursor() | |
| cur.execute(""" | |
| INSERT INTO openclaw_config (config_key, config_value, updated_at) | |
| VALUES ('openclaw_main', %s::jsonb, CURRENT_TIMESTAMP) | |
| ON CONFLICT (config_key) | |
| DO UPDATE SET config_value = EXCLUDED.config_value, updated_at = CURRENT_TIMESTAMP | |
| """, (config_json,)) | |
| conn.commit() | |
| cur.close() | |
| conn.close() | |
| return True | |
| except Exception as e: | |
| print(f"Error saving config to DB: {e}", file=sys.stderr) | |
| return False | |
| def init_db(): | |
| """Initialize database with default config if not exists""" | |
| try: | |
| conn = get_connection() | |
| cur = conn.cursor() | |
| cur.execute("SELECT COUNT(*) FROM openclaw_config WHERE config_key = 'openclaw_main'") | |
| count = cur.fetchone()[0] | |
| cur.close() | |
| conn.close() | |
| return count > 0 | |
| except Exception as e: | |
| print(f"Error checking DB: {e}", file=sys.stderr) | |
| return False | |
| if __name__ == '__main__': | |
| action = sys.argv[1] if len(sys.argv) > 1 else 'load' | |
| if action == 'load': | |
| config = load_config() | |
| if config: | |
| print(json.dumps(config)) | |
| else: | |
| sys.exit(1) | |
| elif action == 'save': | |
| config_json = sys.stdin.read() | |
| if save_config(config_json): | |
| sys.exit(0) | |
| else: | |
| sys.exit(1) | |
| elif action == 'init': | |
| if init_db(): | |
| print("DB already initialized") | |
| else: | |
| print("DB not initialized") | |
| sys.exit(1) | |
| PYSCRIPT | |
| RUN chmod +x /usr/local/bin/db-manager.py | |
| # Config sync daemon | |
| RUN cat > /usr/local/bin/sync-config.sh << 'SYNCSCRIPT' | |
| #!/bin/bash | |
| CONFIG_FILE="/root/.openclaw/openclaw.json" | |
| LAST_HASH="" | |
| echo "[sync-daemon] Config sync daemon started" | |
| sleep 10 | |
| while true; do | |
| if [ -f "$CONFIG_FILE" ]; then | |
| CURRENT_HASH=$(md5sum "$CONFIG_FILE" | awk '{print $1}') | |
| if [ "$CURRENT_HASH" != "$LAST_HASH" ] && [ -n "$LAST_HASH" ]; then | |
| echo "[sync-daemon] Config changed detected, syncing to DB..." | |
| if cat "$CONFIG_FILE" | /opt/venv/bin/python3 /usr/local/bin/db-manager.py save; then | |
| echo "[sync-daemon] ��� Config synced at $(date -Iseconds)" | |
| else | |
| echo "[sync-daemon] ��� Failed to sync config" | |
| fi | |
| fi | |
| LAST_HASH="$CURRENT_HASH" | |
| fi | |
| sleep 30 | |
| done | |
| SYNCSCRIPT | |
| RUN cat > /usr/local/bin/start-openclaw.sh << 'SCRIPT' | |
| #!/bin/bash | |
| set -e | |
| echo "=== OpenClaw Startup with Browser Support ===" | |
| if [ -z "$OPENCLAW_GATEWAY_PASSWORD" ]; then | |
| echo "ERROR: OPENCLAW_GATEWAY_PASSWORD not set!" | |
| exit 1 | |
| fi | |
| if [ -z "$KIRO_API_KEY" ]; then | |
| echo "ERROR: KIRO_API_KEY not set!" | |
| exit 1 | |
| fi | |
| if [ -z "$DATABASE_URL" ]; then | |
| echo "ERROR: DATABASE_URL not set!" | |
| exit 1 | |
| fi | |
| if [ -n "$TELEGRAM_STEVE_TOKEN" ]; then | |
| echo "Telegram Steve bot token found" | |
| fi | |
| if [ -n "$TELEGRAM_DEN_TOKEN" ]; then | |
| echo "Telegram Den bot token found" | |
| fi | |
| if [ -n "$TELEGRAM_OLYA_TOKEN" ]; then | |
| echo "Telegram Olya bot token found" | |
| fi | |
| if [ -n "$SPACE_HOST" ]; then | |
| ALLOWED_ORIGIN="https://${SPACE_HOST}" | |
| else | |
| ALLOWED_ORIGIN="*" | |
| fi | |
| echo "Loading config from Neon PostgreSQL..." | |
| if ! /opt/venv/bin/python3 /usr/local/bin/db-manager.py load > /root/.openclaw/openclaw.json; then | |
| echo "ERROR: Failed to load config from Neon DB!" | |
| echo "Please ensure config exists in openclaw_config table with key 'openclaw_main'" | |
| exit 1 | |
| fi | |
| echo "��� Config loaded successfully from Neon" | |
| chmod 700 /root/.openclaw | |
| chmod 600 /root/.openclaw/openclaw.json | |
| echo "Starting config sync daemon..." | |
| /usr/local/bin/sync-config.sh & | |
| echo "��� Sync daemon started (PID: $!)" | |
| echo "Starting OpenClaw Gateway with browser support..." | |
| exec openclaw gateway run --port 18789 | |
| SCRIPT | |
| RUN chmod +x /usr/local/bin/start-openclaw.sh | |
| RUN chmod +x /usr/local/bin/sync-config.sh | |
| CMD ["/usr/local/bin/start-openclaw.sh"] | |