deploy.sh 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. #!/usr/bin/env sh
  2. # Linux bootstrap: uv + Python + locked dependencies + local model + update/start.
  3. set -eu
  4. REPO_ROOT=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
  5. cd "$REPO_ROOT"
  6. ACTION=${1:-templates}
  7. case "$ACTION" in
  8. -h|--help|help)
  9. echo 'Usage: sh deploy.sh [setup|model|templates|dms|start|restart] [--host HOST] [--port PORT]'
  10. echo 'setup: install environment and model only; model: ensure model is ready'
  11. echo 'templates/dms: prepare environment and model, update, then start; start: prepare and start'
  12. echo 'Services start in the background; logs: .runtime/service.log'
  13. echo 'Environment: AUTO_INSTALL_UV=0 disables uv installation; DEPLOY_PYTHON overrides .python-version (default: 3.14.5)'
  14. exit 0 ;;
  15. setup|model|templates|dms|start|restart) ;;
  16. *) echo "Unknown action: $ACTION" >&2; exit 2 ;;
  17. esac
  18. if [ "$#" -gt 0 ]; then shift; fi
  19. if [ "$ACTION" = setup ] || [ "$ACTION" = model ]; then
  20. if [ "$#" -gt 0 ]; then echo 'setup/model do not accept service arguments' >&2; exit 2; fi
  21. fi
  22. if ! command -v uv >/dev/null 2>&1; then
  23. if [ -x "$HOME/.local/bin/uv" ]; then
  24. PATH="$HOME/.local/bin:$PATH"; export PATH
  25. elif [ -x "$REPO_ROOT/.runtime/bin/uv" ]; then
  26. PATH="$REPO_ROOT/.runtime/bin:$PATH"; export PATH
  27. else
  28. if [ "${AUTO_INSTALL_UV:-1}" != 1 ]; then
  29. echo 'uv is missing; install uv or set AUTO_INSTALL_UV=1.' >&2; exit 127
  30. fi
  31. installer=$(mktemp)
  32. trap 'rm -f "$installer"' EXIT HUP INT TERM
  33. if command -v curl >/dev/null 2>&1; then
  34. curl -fLsS https://astral.sh/uv/install.sh -o "$installer"
  35. elif command -v wget >/dev/null 2>&1; then
  36. wget -q https://astral.sh/uv/install.sh -O "$installer"
  37. else
  38. echo 'Installing uv requires curl or wget.' >&2; exit 127
  39. fi
  40. UV_UNMANAGED_INSTALL="$REPO_ROOT/.runtime/bin" sh "$installer"
  41. rm -f "$installer"
  42. trap - EXIT HUP INT TERM
  43. PATH="$REPO_ROOT/.runtime/bin:$PATH"; export PATH
  44. fi
  45. fi
  46. # Never source .env as shell code; Python reads it via python-dotenv.
  47. if [ ! -f .env ]; then
  48. cp .env.example .env
  49. echo 'Created .env from .env.example; fill in real service credentials and paths.'
  50. if [ "$ACTION" != setup ] && [ "$ACTION" != model ]; then
  51. echo 'After editing .env, rerun this command. No business update was attempted.' >&2
  52. exit 2
  53. fi
  54. fi
  55. export UV_CACHE_DIR="${UV_CACHE_DIR:-$REPO_ROOT/.uv-cache}"
  56. echo '[1/3] Prepare Python and locked project environment'
  57. PYTHON_VERSION=${DEPLOY_PYTHON:-$(cat "$REPO_ROOT/.python-version")}
  58. echo "Using Python $PYTHON_VERSION"
  59. uv python install "$PYTHON_VERSION"
  60. uv sync --frozen --python "$PYTHON_VERSION"
  61. case "$ACTION" in
  62. templates|dms|start|restart) uv run --frozen --no-sync --python "$PYTHON_VERSION" python scripts/start_service.py --check-config "$@" ;;
  63. esac
  64. echo '[2/3] Prepare local embedding model'
  65. uv run --frozen --no-sync --python "$PYTHON_VERSION" python scripts/download_model.py
  66. case "$ACTION" in
  67. setup|model) echo 'Environment and model ready. Configure .env, then run sh deploy.sh templates.' ;;
  68. *)
  69. echo '[3/3] Update/start service'
  70. if [ "$ACTION" = templates ] || [ "$ACTION" = dms ]; then
  71. uv run --frozen --no-sync --python "$PYTHON_VERSION" python scripts/update_data.py --mode "$ACTION"
  72. fi
  73. if [ "$ACTION" = restart ]; then set -- --restart "$@"; fi
  74. mkdir -p "$REPO_ROOT/.runtime"
  75. SERVICE_LOG="$REPO_ROOT/.runtime/service.log"
  76. nohup uv run --frozen --no-sync --python "$PYTHON_VERSION" python -u scripts/start_service.py "$@" >> "$SERVICE_LOG" 2>&1 < /dev/null &
  77. service_pid=$!
  78. sleep 2
  79. if ! kill -0 "$service_pid" 2>/dev/null; then
  80. service_status=0
  81. wait "$service_pid" || service_status=$?
  82. echo "Service exited during startup (status: $service_status). Check: $SERVICE_LOG" >&2
  83. tail -n 30 "$SERVICE_LOG" >&2
  84. exit 1
  85. fi
  86. echo "Service launched in background (launcher PID: $service_pid). Startup may still be in progress."
  87. echo "Logs: $SERVICE_LOG"
  88. echo "View startup status: tail -f \"$SERVICE_LOG\""
  89. ;;
  90. esac