#!/usr/bin/env bash set -e # Default update interval: 60 minutes UPDATE_INTERVAL=${UPDATE_INTERVAL:-60} CONFIG_FILE="/app/data/client.json" SINGBOX_PID="" # Ensure data directory exists mkdir -p /app/data # Function to generate config generate_config() { echo "$(date): Generating config..." if ./gen-client-from-url.sh "$VLESS_URL" "$CONFIG_FILE"; then echo "$(date): Config generated successfully." return 0 else echo "$(date): Error generating config." return 1 fi } start_singbox() { if [[ -f "$CONFIG_FILE" ]]; then echo "$(date): Starting sing-box..." sing-box run -c "$CONFIG_FILE" & SINGBOX_PID=$! echo "$(date): sing-box started with PID $SINGBOX_PID" else echo "$(date): Config file not found. Use web UI at :3456 to apply config." SINGBOX_PID="" fi } stop_singbox() { if [[ -n "$SINGBOX_PID" ]]; then echo "$(date): Stopping sing-box (PID $SINGBOX_PID)..." kill "$SINGBOX_PID" 2>/dev/null || true wait "$SINGBOX_PID" 2>/dev/null || true SINGBOX_PID="" fi } restart_singbox() { stop_singbox start_singbox } # Initial generation (if URL provided) if [[ -n "$VLESS_URL" ]]; then generate_config fi start_singbox # Start Web UI Server echo "$(date): Starting Web UI on port 3456..." python3 /app/web/server.py & WEBUI_PID=$! # HTTP Control Server (Simple Netcat loop) # Listens on 9090. # Endpoints: # /update -> Regenerate from ENV (VLESS_URL) & Restart # /reload -> Just Restart (used by web_server.py after config change) ( while true; do # Read the request using nc. REQ=$(echo -e "HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n" | nc -l -p 9090 -q 1) echo "$(date): Received request on 9090" if echo "$REQ" | grep -q "GET /update"; then echo "$(date): Action: UPDATE (Regen from ENV + Restart)" if generate_config; then restart_singbox fi elif echo "$REQ" | grep -q "GET /reload"; then echo "$(date): Action: RELOAD (Restart only)" restart_singbox else echo "$(date): Unknown request or ping." fi done ) & CONTROL_PID=$! # Periodic Update Loop (only if VLESS_URL is set) if [[ -n "$VLESS_URL" ]]; then ( while true; do sleep "$((UPDATE_INTERVAL * 60))" echo "$(date): Checking for periodic update..." if generate_config; then restart_singbox fi done ) & UPDATE_PID=$! fi # Keep container alive - wait for any background process echo "$(date): Entrypoint ready. Waiting for processes..." # Wait indefinitely - if WebUI dies, restart container wait $WEBUI_PID