a9e2d295b1
- Remove static runtime/*.service files - generate_systemd_units() writes paths based on PROJECT_DIR - frps.service: ExecStart uses actual frps binary path - frps-manager.service: WorkingDir + gunicorn path from PROJECT_DIR - frpc@.service template also generated at deploy time
239 lines
6.6 KiB
Bash
239 lines
6.6 KiB
Bash
#!/usr/bin/env bash
|
|
# frps-manager one-shot deploy script.
|
|
# Dynamically generates systemd units with correct paths.
|
|
# Run as root (or with sudo).
|
|
#
|
|
# Usage: sudo bash scripts/deploy.sh [--dry-run] [--no-systemd] [--dev]
|
|
|
|
set -euo pipefail
|
|
|
|
DRY_RUN=0
|
|
NO_SYSTEMD=0
|
|
DEV=0
|
|
for arg in "$@"; do
|
|
case "$arg" in
|
|
--dry-run) DRY_RUN=1 ;;
|
|
--no-systemd) NO_SYSTEMD=1 ;;
|
|
--dev) DEV=1 ;;
|
|
-h|--help)
|
|
grep '^#' "$0" | sed 's/^# \?//'
|
|
exit 0 ;;
|
|
esac
|
|
done
|
|
|
|
PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
cd "$PROJECT_DIR"
|
|
|
|
log() { echo "[deploy] $*"; }
|
|
die() { echo "[deploy][FATAL] $*" >&2; exit 1; }
|
|
|
|
FRPS_BIN="$PROJECT_DIR/runtime/bin/frps"
|
|
FRPS_INI="$PROJECT_DIR/runtime/conf/frps.ini"
|
|
GUNICORN="$PROJECT_DIR/venv/bin/gunicorn"
|
|
PORT=5390
|
|
|
|
# --- distro detection -------------------------------------------------------
|
|
if [ -f /etc/os-release ]; then
|
|
. /etc/os-release
|
|
OS_ID="$ID"
|
|
OS_VER="$VERSION_ID"
|
|
else
|
|
die "Cannot detect /etc/os-release"
|
|
fi
|
|
case "$OS_ID" in
|
|
ubuntu|debian|raspbian) PKG=apt; SUDO=sudo ;;
|
|
centos|rhel|rocky|almalinux|opencloudos|openanolis) PKG=yum; SUDO=sudo ;;
|
|
fedora) PKG=dnf; SUDO=sudo ;;
|
|
*)
|
|
log "Unknown distro $OS_ID — assuming apt-compatible"
|
|
PKG=apt; SUDO=sudo ;;
|
|
esac
|
|
[ "$(id -u)" -eq 0 ] && SUDO=""
|
|
|
|
log "Detected: $OS_ID $OS_VER (pkg manager: $PKG)"
|
|
|
|
# --- frps download ----------------------------------------------------------
|
|
if [ ! -x "$FRPS_BIN" ]; then
|
|
log "frps binary missing — fetching v0.70.1 from GitHub"
|
|
if [ "$DRY_RUN" = 1 ]; then
|
|
log "DRY: would download frp_0.70.1_linux_amd64.tar.gz"
|
|
else
|
|
TMPDIR=$(mktemp -d)
|
|
trap "rm -rf $TMPDIR" EXIT
|
|
ARCH="$(uname -m)"
|
|
case "$ARCH" in
|
|
x86_64) FRPS_ARCH=amd64 ;;
|
|
aarch64|arm64) FRPS_ARCH=arm64 ;;
|
|
armv7l|armv7) FRPS_ARCH=arm ;;
|
|
*) die "Unsupported arch: $ARCH (please build/download frps manually)" ;;
|
|
esac
|
|
URL="https://github.com/fatedier/frp/releases/download/v0.70.1/frp_0.70.1_linux_${FRPS_ARCH}.tar.gz"
|
|
log "Downloading $URL"
|
|
curl -fSL --max-time 120 -o "$TMPDIR/frp.tgz" "$URL" \
|
|
|| die "Failed to download frps"
|
|
tar xzf "$TMPDIR/frp.tgz" -C "$TMPDIR"
|
|
mkdir -p runtime/bin
|
|
cp "$TMPDIR"/frp_0.70.1_linux_${FRPS_ARCH}/frps "$FRPS_BIN"
|
|
chmod +x "$FRPS_BIN"
|
|
log "Installed $FRPS_BIN"
|
|
fi
|
|
fi
|
|
|
|
# --- system deps ------------------------------------------------------------
|
|
log "Installing system dependencies"
|
|
if [ "$DRY_RUN" = 0 ]; then
|
|
case "$PKG" in
|
|
apt)
|
|
$SUDO apt-get update -y >/dev/null
|
|
$SUDO apt-get install -y python3 python3-venv python3-pip curl ca-certificates >/dev/null
|
|
;;
|
|
yum|dnf)
|
|
$SUDO $PKG install -y python3 python3-pip python3-venv curl ca-certificates >/dev/null
|
|
;;
|
|
esac
|
|
fi
|
|
|
|
# --- venv -------------------------------------------------------------------
|
|
if [ ! -d venv ]; then
|
|
log "Creating Python venv"
|
|
if [ "$DRY_RUN" = 0 ]; then
|
|
python3 -m venv venv
|
|
venv/bin/pip install --upgrade pip >/dev/null
|
|
venv/bin/pip install -r requirements.txt
|
|
fi
|
|
fi
|
|
|
|
# --- db init ----------------------------------------------------------------
|
|
log "Initializing database"
|
|
if [ "$DRY_RUN" = 0 ]; then
|
|
venv/bin/python init_db.py
|
|
fi
|
|
|
|
# --- generate systemd units -------------------------------------------------
|
|
generate_systemd_units() {
|
|
# frps.service — generated with actual binary + config paths
|
|
cat > /etc/systemd/system/frps.service <<EOF
|
|
[Unit]
|
|
Description=frps — fatedier/frp server
|
|
After=network-online.target
|
|
Wants=network-online.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
ExecStart=$FRPS_BIN -c $FRPS_INI
|
|
Restart=on-failure
|
|
RestartSec=5
|
|
LimitNOFILE=65536
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
EOF
|
|
|
|
# frps-manager.service — generated with actual project paths
|
|
cat > /etc/systemd/system/frps-manager.service <<EOF
|
|
[Unit]
|
|
Description=frps-manager — frps Web Management UI
|
|
After=network-online.target frps.service
|
|
Wants=frps.service
|
|
|
|
[Service]
|
|
Type=simple
|
|
WorkingDirectory=$PROJECT_DIR
|
|
Environment=FLASK_SECRET=
|
|
Environment=FRPS_DASHBOARD_URL=http://127.0.0.1:7500
|
|
Environment=FRPS_DASHBOARD_USER=admin
|
|
Environment=FRPS_DASHBOARD_PASS=admin123
|
|
Environment=FRPS_BIND_PORT=7000
|
|
Environment=FRPS_VHOST_HTTP_PORT=80
|
|
Environment=FRPS_VHOST_HTTPS_PORT=443
|
|
ExecStart=$GUNICORN wsgi:app --bind 0.0.0.0:$PORT --workers 2 --timeout 30
|
|
Restart=on-failure
|
|
RestartSec=5
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
EOF
|
|
|
|
# frpc@.service template — for client hosts
|
|
cat > /etc/systemd/system/frpc@.service <<EOF
|
|
[Unit]
|
|
Description=frpc — fatedier/frp client (%i)
|
|
After=network-online.target
|
|
Wants=network-online.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
ExecStart=/usr/local/bin/frpc -c /etc/frpc/%i.ini
|
|
Restart=on-failure
|
|
RestartSec=5
|
|
LimitNOFILE=65536
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
EOF
|
|
}
|
|
|
|
if [ "$NO_SYSTEMD" = 0 ]; then
|
|
log "Generating systemd units (project_dir=$PROJECT_DIR)"
|
|
if [ "$DRY_RUN" = 0 ]; then
|
|
generate_systemd_units
|
|
$SUDO systemctl daemon-reload
|
|
log "systemd units written to /etc/systemd/system/"
|
|
fi
|
|
|
|
# --- start frps ---
|
|
log "Starting frps.service"
|
|
if [ "$DRY_RUN" = 0 ]; then
|
|
$SUDO systemctl enable frps.service 2>/dev/null || true
|
|
$SUDO systemctl restart frps.service || true
|
|
sleep 2
|
|
if ! systemctl is-active --quiet frps.service; then
|
|
log "WARNING: frps.service not active — check 'journalctl -u frps'"
|
|
else
|
|
log "frps.service is active"
|
|
fi
|
|
fi
|
|
|
|
# --- start frps-manager ---
|
|
log "Starting frps-manager.service (port $PORT)"
|
|
if [ "$DRY_RUN" = 0 ]; then
|
|
$SUDO systemctl enable frps-manager.service 2>/dev/null || true
|
|
$SUDO systemctl restart frps-manager.service || true
|
|
sleep 2
|
|
if ! systemctl is-active --quiet frps-manager.service; then
|
|
log "WARNING: frps-manager.service not active — check 'journalctl -u frps-manager'"
|
|
else
|
|
log "frps-manager.service is active on http://0.0.0.0:$PORT"
|
|
fi
|
|
fi
|
|
else
|
|
log "Skipped systemd (--no-systemd)"
|
|
fi
|
|
|
|
cat <<EOF
|
|
|
|
================================================================
|
|
frps-manager deployed!
|
|
|
|
Web UI: http://<this-host>:$PORT
|
|
Default: admin / admin (CHANGE IMMEDIATELY under "改密")
|
|
|
|
frps bind: 0.0.0.0:7000
|
|
frps dashboard: 127.0.0.1:7500 (admin / admin123)
|
|
frps vhost_http: 0.0.0.0:80 (set FRPS_VHOST_HTTP_PORT in service to override)
|
|
frps vhost_https: 0.0.0.0:443
|
|
|
|
Systemd units (auto-generated with correct paths):
|
|
/etc/systemd/system/frps.service
|
|
/etc/systemd/system/frps-manager.service
|
|
/etc/systemd/system/frpc@.service
|
|
|
|
To upgrade:
|
|
cd $PROJECT_DIR
|
|
sudo systemctl stop frps-manager frps
|
|
git pull
|
|
venv/bin/pip install -r requirements.txt
|
|
sudo bash scripts/deploy.sh # regenerates units + restarts
|
|
================================================================
|
|
EOF
|