install_debian.sh 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. #!/usr/bin/env bash
  2. set -euo pipefail
  3. SERVICE_NAME="vmess-domain-rotator"
  4. APP_DIR="/opt/vmess-domain-rotator"
  5. RUN_USER="vmessrotator"
  6. RUN_GROUP="vmessrotator"
  7. INTERVAL="12h"
  8. INSTALL_DEPS="1"
  9. OVERWRITE_CONFIG="0"
  10. usage() {
  11. cat <<'EOF'
  12. Usage: sudo bash scripts/install_debian.sh [options]
  13. Options:
  14. --app-dir <path> Install directory (default: /opt/vmess-domain-rotator)
  15. --user <name> Service user (default: vmessrotator)
  16. --group <name> Service group (default: vmessrotator)
  17. --interval <value> Timer interval, e.g. 12h/10min (default: 12h)
  18. --no-install-deps Skip apt dependency install
  19. --overwrite-config Overwrite existing config.json in app dir
  20. -h, --help Show help
  21. Examples:
  22. sudo bash scripts/install_debian.sh
  23. sudo bash scripts/install_debian.sh --user root --group root --interval 10min
  24. EOF
  25. }
  26. while [[ $# -gt 0 ]]; do
  27. case "$1" in
  28. --app-dir)
  29. APP_DIR="$2"
  30. shift 2
  31. ;;
  32. --user)
  33. RUN_USER="$2"
  34. shift 2
  35. ;;
  36. --group)
  37. RUN_GROUP="$2"
  38. shift 2
  39. ;;
  40. --interval)
  41. INTERVAL="$2"
  42. shift 2
  43. ;;
  44. --no-install-deps)
  45. INSTALL_DEPS="0"
  46. shift
  47. ;;
  48. --overwrite-config)
  49. OVERWRITE_CONFIG="1"
  50. shift
  51. ;;
  52. -h|--help)
  53. usage
  54. exit 0
  55. ;;
  56. *)
  57. echo "Unknown option: $1" >&2
  58. usage
  59. exit 1
  60. ;;
  61. esac
  62. done
  63. if [[ "$(id -u)" -ne 0 ]]; then
  64. echo "Please run as root (use sudo)." >&2
  65. exit 1
  66. fi
  67. SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
  68. if [[ "$INSTALL_DEPS" == "1" ]]; then
  69. export DEBIAN_FRONTEND=noninteractive
  70. apt-get update -y
  71. apt-get install -y python3 ca-certificates git
  72. fi
  73. if [[ "$RUN_USER" != "root" ]]; then
  74. if ! getent group "$RUN_GROUP" >/dev/null 2>&1; then
  75. groupadd --system "$RUN_GROUP"
  76. fi
  77. if ! id -u "$RUN_USER" >/dev/null 2>&1; then
  78. useradd --system --home-dir "$APP_DIR" --create-home --shell /usr/sbin/nologin --gid "$RUN_GROUP" "$RUN_USER"
  79. fi
  80. fi
  81. mkdir -p "$APP_DIR"
  82. CONFIG_BACKUP=""
  83. if [[ "$OVERWRITE_CONFIG" != "1" && -f "$APP_DIR/config.json" ]]; then
  84. CONFIG_BACKUP="$(mktemp)"
  85. cp "$APP_DIR/config.json" "$CONFIG_BACKUP"
  86. fi
  87. tar -C "$SOURCE_DIR" \
  88. --exclude='.git' \
  89. --exclude='.DS_Store' \
  90. --exclude='__pycache__' \
  91. -cf - . | tar -C "$APP_DIR" -xf -
  92. if [[ -n "$CONFIG_BACKUP" ]]; then
  93. cp "$CONFIG_BACKUP" "$APP_DIR/config.json"
  94. rm -f "$CONFIG_BACKUP"
  95. fi
  96. mkdir -p "$APP_DIR/runtime"
  97. chmod +x "$APP_DIR/scripts/run_update_and_commit.sh" "$APP_DIR/scripts/install_debian.sh" "$APP_DIR/scripts/uninstall_debian.sh" || true
  98. if [[ "$RUN_USER" != "root" ]]; then
  99. chown -R "$RUN_USER:$RUN_GROUP" "$APP_DIR"
  100. fi
  101. if ! git -C "$APP_DIR" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
  102. git -C "$APP_DIR" init
  103. fi
  104. cat >"/etc/systemd/system/${SERVICE_NAME}.service" <<EOF
  105. [Unit]
  106. Description=VMess Domain Rotator updater
  107. After=network-online.target
  108. Wants=network-online.target
  109. [Service]
  110. Type=oneshot
  111. User=${RUN_USER}
  112. Group=${RUN_GROUP}
  113. WorkingDirectory=${APP_DIR}
  114. ExecStart=/bin/bash ${APP_DIR}/scripts/run_update_and_commit.sh ${APP_DIR}/config.json
  115. EOF
  116. cat >"/etc/systemd/system/${SERVICE_NAME}.timer" <<EOF
  117. [Unit]
  118. Description=Run VMess Domain Rotator every ${INTERVAL}
  119. [Timer]
  120. OnBootSec=2min
  121. OnUnitActiveSec=${INTERVAL}
  122. AccuracySec=30s
  123. Unit=${SERVICE_NAME}.service
  124. Persistent=true
  125. [Install]
  126. WantedBy=timers.target
  127. EOF
  128. systemctl daemon-reload
  129. systemctl enable --now "${SERVICE_NAME}.timer"
  130. systemctl start "${SERVICE_NAME}.service"
  131. echo "Installed successfully."
  132. echo "App dir: ${APP_DIR}"
  133. echo "Service: ${SERVICE_NAME}.service"
  134. echo "Timer: ${SERVICE_NAME}.timer"
  135. echo "Check status: systemctl status ${SERVICE_NAME}.timer"
  136. echo "View logs: journalctl -u ${SERVICE_NAME}.service -n 50 --no-pager"