Ctrl K
ComunidadGuías…

selfhost/start.sh

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
#!/usr/bin/env sh
set -eu

ROOT=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
RUNTIME_DIR="$ROOT/.runtime"
PID_PATH="$RUNTIME_DIR/lan-watcher.pid"
WEB_PORT_VALUE=${WEB_PORT:-8787}

if [ -f "$ROOT/.env" ]; then
  ENV_PORT=$(sed -n 's/^[[:space:]]*WEB_PORT[[:space:]]*=[[:space:]]*\([0-9][0-9]*\)[[:space:]]*$/\1/p' "$ROOT/.env" | tail -n 1)
  if [ -n "$ENV_PORT" ]; then WEB_PORT_VALUE=$ENV_PORT; fi
fi

case "$WEB_PORT_VALUE" in
  ''|*[!0-9]*) echo "WEB_PORT must be an integer." >&2; exit 1 ;;
esac
if [ "$WEB_PORT_VALUE" -lt 1 ] || [ "$WEB_PORT_VALUE" -gt 65535 ]; then
  echo "WEB_PORT must be between 1 and 65535." >&2
  exit 1
fi

mkdir -p "$RUNTIME_DIR"

detect_lan_ip() {
  case "$(uname -s)" in
    Darwin)
      interface=$(route -n get default 2>/dev/null | awk '/interface:/{print $2; exit}')
      [ -n "$interface" ] || return 1
      ipconfig getifaddr "$interface"
      ;;
    Linux)
      ip -4 route get 1.1.1.1 2>/dev/null |
        awk '{ for (i = 1; i <= NF; i++) if ($i == "src") { print $(i + 1); exit } }'
      ;;
    *) return 1 ;;
  esac
}

write_lan_address() {
  ipv4=$(detect_lan_ip)
  [ -n "$ipv4" ] || return 1
  updated_at=$(date -u '+%Y-%m-%dT%H:%M:%SZ')
  printf '{"ipv4":"%s","baseUrl":"http://%s:%s","updatedAt":"%s","source":"host-default-route"}' \
    "$ipv4" "$ipv4" "$WEB_PORT_VALUE" "$updated_at" > "$RUNTIME_DIR/lan-address.json"
  printf '%s' "$ipv4"
}

run_lan_watcher() {
  cleanup_lan_watcher() {
    recorded_pid=$(cat "$PID_PATH" 2>/dev/null || true)
    if [ "$recorded_pid" = "$$" ]; then
      rm -f "$PID_PATH"
    fi
  }
  trap cleanup_lan_watcher EXIT
  trap 'exit 0' INT TERM
  stopped_checks=0
  while :; do
    if ! write_lan_address >/dev/null 2>&1; then
      rm -f "$RUNTIME_DIR/lan-address.json"
    fi
    if [ "$(docker inspect --format '{{.State.Running}}' ekko-selfhost-web-1 2>/dev/null || true)" = "true" ]; then
      stopped_checks=0
    else
      stopped_checks=$((stopped_checks + 1))
      [ "$stopped_checks" -lt 6 ] || break
    fi
    sleep 5
  done
}

if [ "${1:-}" = "--watch-lan" ]; then
  run_lan_watcher
  exit 0
fi

DETECTED_IP=""
if ! DETECTED_IP=$(write_lan_address); then
  rm -f "$RUNTIME_DIR/lan-address.json"
  printf '%s\n' 'LAN IP detection is not available yet; Compose will still start.' >&2
fi

cd "$ROOT"
docker compose up --build -d

watcher_is_running() {
  [ -f "$PID_PATH" ] || return 1
  watcher_pid=$(awk 'NR == 1 { print $1 }' "$PID_PATH" 2>/dev/null)
  case "$watcher_pid" in
    ''|*[!0-9]*) return 1 ;;
  esac
  kill -0 "$watcher_pid" 2>/dev/null || return 1
  case "$(uname -s)" in
    Linux)
      watcher_command=$(tr '\000' ' ' < "/proc/$watcher_pid/cmdline" 2>/dev/null || true)
      ;;
    Darwin)
      watcher_command=$(ps -p "$watcher_pid" -o command= 2>/dev/null || true)
      ;;
    *) return 1 ;;
  esac
  case "$watcher_command" in
    *start.sh*--watch-lan*|*watch-lan-ip.ps1*) return 0 ;;
    *) return 1 ;;
  esac
}

if watcher_is_running; then
  :
else
  sh "$ROOT/start.sh" --watch-lan >/dev/null 2>&1 &
  printf '%s\n' "$!" > "$PID_PATH"
fi

printf '\nEkko Rules is ready:\n'
printf '  Computer: http://localhost:%s\n' "$WEB_PORT_VALUE"
if [ -n "$DETECTED_IP" ]; then
  printf '  Trusted LAN: http://%s:%s\n\n' "$DETECTED_IP" "$WEB_PORT_VALUE"
else
  printf '  Trusted LAN: waiting for an active network\n\n'
fi
printf 'The LAN address watcher will refresh automatically when the network changes.\n'