| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- #!/usr/bin/env bash
- set -euo pipefail
- SERVICE_NAME="vmess-domain-rotator"
- APP_DIR="/opt/vmess-domain-rotator"
- RUN_USER="vmessrotator"
- RUN_GROUP="vmessrotator"
- APP_DIR_SET="0"
- RUN_USER_SET="0"
- RUN_GROUP_SET="0"
- INTERVAL="1h"
- INSTALL_DEPS="1"
- OVERWRITE_CONFIG="0"
- usage() {
- cat <<'EOF'
- Usage: sudo bash scripts/install_debian.sh [options]
- Default behavior:
- - If current source dir is a git repo and --app-dir is not set, install in-place
- (service runs directly from this repo so auto-commit works on your real git repo).
- - If --app-dir is set, files are copied into that directory.
- Options:
- --app-dir <path> Install directory (default: /opt/vmess-domain-rotator)
- --user <name> Service user (default: vmessrotator)
- --group <name> Service group (default: vmessrotator)
- --interval <value> Timer interval, e.g. 1h/10min (default: 1h)
- --no-install-deps Skip apt dependency install
- --overwrite-config Overwrite existing config.json in app dir
- -h, --help Show help
- Examples:
- sudo bash scripts/install_debian.sh
- sudo bash scripts/install_debian.sh --app-dir /opt/vmess-domain-rotator
- sudo bash scripts/install_debian.sh --user root --group root --interval 10min
- EOF
- }
- while [[ $# -gt 0 ]]; do
- case "$1" in
- --app-dir)
- APP_DIR="$2"
- APP_DIR_SET="1"
- shift 2
- ;;
- --user)
- RUN_USER="$2"
- RUN_USER_SET="1"
- shift 2
- ;;
- --group)
- RUN_GROUP="$2"
- RUN_GROUP_SET="1"
- shift 2
- ;;
- --interval)
- INTERVAL="$2"
- shift 2
- ;;
- --no-install-deps)
- INSTALL_DEPS="0"
- shift
- ;;
- --overwrite-config)
- OVERWRITE_CONFIG="1"
- shift
- ;;
- -h|--help)
- usage
- exit 0
- ;;
- *)
- echo "Unknown option: $1" >&2
- usage
- exit 1
- ;;
- esac
- done
- if [[ "$(id -u)" -ne 0 ]]; then
- echo "Please run as root (use sudo)." >&2
- exit 1
- fi
- SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
- DEPLOY_MODE="copy"
- if [[ "$APP_DIR_SET" != "1" ]] && git -C "$SOURCE_DIR" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
- APP_DIR="$SOURCE_DIR"
- DEPLOY_MODE="in-place"
- if [[ -n "${SUDO_USER:-}" ]] && [[ "$RUN_USER_SET" != "1" ]]; then
- RUN_USER="$SUDO_USER"
- fi
- if [[ -n "${SUDO_USER:-}" ]] && [[ "$RUN_GROUP_SET" != "1" ]]; then
- RUN_GROUP="$(id -gn "$SUDO_USER")"
- fi
- fi
- if [[ "$INSTALL_DEPS" == "1" ]]; then
- export DEBIAN_FRONTEND=noninteractive
- apt-get update -y
- apt-get install -y python3 ca-certificates git
- fi
- if [[ "$RUN_USER" != "root" ]]; then
- if ! getent group "$RUN_GROUP" >/dev/null 2>&1; then
- groupadd --system "$RUN_GROUP"
- fi
- if ! id -u "$RUN_USER" >/dev/null 2>&1; then
- useradd --system --home-dir "$APP_DIR" --create-home --shell /usr/sbin/nologin --gid "$RUN_GROUP" "$RUN_USER"
- fi
- fi
- mkdir -p "$APP_DIR"
- if [[ "$DEPLOY_MODE" == "copy" ]]; then
- CONFIG_BACKUP=""
- if [[ "$OVERWRITE_CONFIG" != "1" && -f "$APP_DIR/config.json" ]]; then
- CONFIG_BACKUP="$(mktemp)"
- cp "$APP_DIR/config.json" "$CONFIG_BACKUP"
- fi
- tar -C "$SOURCE_DIR" \
- --exclude='.git' \
- --exclude='.DS_Store' \
- --exclude='__pycache__' \
- -cf - . | tar -C "$APP_DIR" -xf -
- if [[ -n "$CONFIG_BACKUP" ]]; then
- cp "$CONFIG_BACKUP" "$APP_DIR/config.json"
- rm -f "$CONFIG_BACKUP"
- fi
- fi
- mkdir -p "$APP_DIR/runtime"
- chmod +x "$APP_DIR/scripts/run_update_and_commit.sh" "$APP_DIR/scripts/install_debian.sh" "$APP_DIR/scripts/uninstall_debian.sh" || true
- if [[ "$RUN_USER" != "root" ]]; then
- if [[ "$DEPLOY_MODE" == "in-place" ]]; then
- chown -R "$RUN_USER:$RUN_GROUP" "$APP_DIR/runtime"
- else
- chown -R "$RUN_USER:$RUN_GROUP" "$APP_DIR"
- fi
- fi
- if [[ "$DEPLOY_MODE" == "copy" ]] && ! git -C "$APP_DIR" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
- git -C "$APP_DIR" init
- fi
- cat >"/etc/systemd/system/${SERVICE_NAME}.service" <<EOF
- [Unit]
- Description=VMess Domain Rotator updater
- After=network-online.target
- Wants=network-online.target
- [Service]
- Type=oneshot
- User=${RUN_USER}
- Group=${RUN_GROUP}
- WorkingDirectory=${APP_DIR}
- ExecStart=/bin/bash ${APP_DIR}/scripts/run_update_and_commit.sh ${APP_DIR}/config.json
- EOF
- cat >"/etc/systemd/system/${SERVICE_NAME}.timer" <<EOF
- [Unit]
- Description=Run VMess Domain Rotator every ${INTERVAL}
- [Timer]
- OnBootSec=2min
- OnUnitActiveSec=${INTERVAL}
- AccuracySec=30s
- Unit=${SERVICE_NAME}.service
- Persistent=true
- [Install]
- WantedBy=timers.target
- EOF
- systemctl daemon-reload
- systemctl enable --now "${SERVICE_NAME}.timer"
- systemctl start "${SERVICE_NAME}.service"
- echo "Installed successfully."
- echo "Deploy mode: ${DEPLOY_MODE}"
- echo "App dir: ${APP_DIR}"
- echo "Service: ${SERVICE_NAME}.service"
- echo "Timer: ${SERVICE_NAME}.timer"
- echo "Check status: systemctl status ${SERVICE_NAME}.timer"
- echo "View logs: journalctl -u ${SERVICE_NAME}.service -n 50 --no-pager"
|