Release
This commit is contained in:
192
install.sh
Normal file
192
install.sh
Normal file
@@ -0,0 +1,192 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
C_RESET="\033[0m"; C_DIM="\033[2m"; C_BOLD="\033[1m"
|
||||
C_RED="\033[31m"; C_GRN="\033[32m"; C_BLU="\033[34m"; C_YEL="\033[33m"
|
||||
info(){ echo -e "${C_BLU}➜${C_RESET} $*"; }
|
||||
ok(){ echo -e "${C_GRN}✓${C_RESET} $*"; }
|
||||
warn(){ echo -e "${C_YEL}!${C_RESET} $*"; }
|
||||
fail(){ echo -e "${C_RED}✗${C_RESET} $*"; }
|
||||
if [[ $EUID -ne 0 ]]; then fail "Run as root (sudo)."; exit 1; fi
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
PANEL_ROOT="/var/www/snowpanel"
|
||||
PANEL_PUBLIC="$PANEL_ROOT/public"
|
||||
STATE_DIR="/var/lib/snowpanel"
|
||||
LOG_DIR="/var/log/snowpanel"
|
||||
ETC_APP="/etc/snowpanel"
|
||||
|
||||
NGX_SITE_AVAIL="/etc/nginx/sites-available/snowpanel"
|
||||
NGX_SITE_ENABL="/etc/nginx/sites-enabled/snowpanel"
|
||||
SUDOERS_FILE="/etc/sudoers.d/snowpanel"
|
||||
|
||||
COLLECTOR_SRC="$SCRIPT_DIR/bin/snowpanel-collect.py"
|
||||
COLLECTOR_BIN="/usr/local/bin/snowpanel-collect.py"
|
||||
LOGDUMP_SRC="$SCRIPT_DIR/bin/snowpanel-logdump"
|
||||
LOGDUMP_BIN="/usr/local/bin/snowpanel-logdump"
|
||||
|
||||
SHAPER_SRC="$SCRIPT_DIR/bin/snowpanel-shaper"
|
||||
SHAPER_BIN="/usr/local/bin/snowpanel-shaper"
|
||||
SHAPER_SVC="/etc/systemd/system/snowpanel-shaper.service"
|
||||
SHAPER_PATH="/etc/systemd/system/snowpanel-shaper.path"
|
||||
|
||||
SVC="/etc/systemd/system/snowpanel-collector.service"
|
||||
TIMER="/etc/systemd/system/snowpanel-collector.timer"
|
||||
SF_DROPIN_DIR="/etc/systemd/system/snowflake-proxy.service.d"
|
||||
SF_ACCOUNTING="$SF_DROPIN_DIR/10-accounting.conf"
|
||||
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
echo -e "${C_BOLD}Installing SnowPanel...${C_RESET}"
|
||||
|
||||
info "Updating apt and installing packages"
|
||||
apt-get update -y >/dev/null
|
||||
apt-get install -y --no-install-recommends snowflake-proxy nginx rsync php-fpm php-cli php-json php-curl php-zip php-common php-opcache python3 iproute2 iptables >/dev/null
|
||||
ok "Packages installed"
|
||||
|
||||
PHPV=$(php -r 'echo PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;' 2>/dev/null || echo "8.2")
|
||||
PHP_FPM_SVC="php${PHPV}-fpm"
|
||||
PHP_SOCK="/run/php/php${PHPV}-fpm.sock"
|
||||
ln -sf "$PHP_SOCK" /run/php/php-fpm.sock || true
|
||||
|
||||
info "Preparing directories"
|
||||
install -d "$PANEL_PUBLIC" "$STATE_DIR" "$LOG_DIR" "$ETC_APP"
|
||||
install -d -m 0755 /usr/local/bin
|
||||
chown -R www-data:www-data "$PANEL_ROOT" || true
|
||||
chown -R www-data:www-data "$STATE_DIR" "$LOG_DIR" || true
|
||||
chmod 750 "$PANEL_ROOT" "$STATE_DIR" "$LOG_DIR"
|
||||
ok "Directories ready"
|
||||
|
||||
info "Deploying web"
|
||||
rsync -a --delete "$SCRIPT_DIR/web/" "$PANEL_PUBLIC/"
|
||||
chown -R www-data:www-data "$PANEL_PUBLIC"
|
||||
ok "Web deployed"
|
||||
|
||||
info "Seeding state"
|
||||
echo -n '{"data":[]}' > "$STATE_DIR/stats.json"
|
||||
chown www-data:www-data "$STATE_DIR/stats.json"
|
||||
chmod 640 "$STATE_DIR/stats.json"
|
||||
ok "State seeded"
|
||||
|
||||
info "Writing Nginx site"
|
||||
cat > "$NGX_SITE_AVAIL" <<'NGINX'
|
||||
server {
|
||||
listen 80 default_server;
|
||||
server_name _;
|
||||
root /var/www/snowpanel/public;
|
||||
index index.php index.html;
|
||||
location / {
|
||||
try_files $uri $uri/ /index.php?$args;
|
||||
}
|
||||
location ~ \.php$ {
|
||||
include snippets/fastcgi-php.conf;
|
||||
fastcgi_pass unix:/run/php/php-fpm.sock;
|
||||
}
|
||||
location ~ /\. {
|
||||
deny all;
|
||||
}
|
||||
}
|
||||
NGINX
|
||||
rm -f /etc/nginx/sites-enabled/default || true
|
||||
ln -sf "$NGX_SITE_AVAIL" "$NGX_SITE_ENABL"
|
||||
ok "Nginx site enabled"
|
||||
|
||||
info "Installing helpers"
|
||||
install -m 0755 "$COLLECTOR_SRC" "$COLLECTOR_BIN"
|
||||
install -m 0755 "$LOGDUMP_SRC" "$LOGDUMP_BIN"
|
||||
install -m 0755 "$SHAPER_SRC" "$SHAPER_BIN"
|
||||
install -d -m 0750 -o www-data -g www-data "$STATE_DIR"
|
||||
ok "Helpers installed"
|
||||
|
||||
info "Granting sudoers"
|
||||
cat > "$SUDOERS_FILE" <<SUD
|
||||
www-data ALL=NOPASSWD:/usr/local/bin/snowpanel-logdump
|
||||
www-data ALL=NOPASSWD:/bin/systemctl start snowflake-proxy, /bin/systemctl stop snowflake-proxy, /bin/systemctl restart snowflake-proxy
|
||||
www-data ALL=NOPASSWD:/bin/systemctl restart snowpanel-shaper
|
||||
SUD
|
||||
chmod 440 "$SUDOERS_FILE"
|
||||
ok "Sudoers set"
|
||||
|
||||
info "Enabling systemd IP accounting"
|
||||
mkdir -p "$SF_DROPIN_DIR"
|
||||
cat > "$SF_ACCOUNTING" <<EOF
|
||||
[Service]
|
||||
IPAccounting=yes
|
||||
EOF
|
||||
ok "Accounting drop-in written"
|
||||
|
||||
info "Creating collector units"
|
||||
cat > "$SVC" <<'UNIT'
|
||||
[Unit]
|
||||
Description=SnowPanel minute collector
|
||||
After=snowflake-proxy.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
User=www-data
|
||||
Group=www-data
|
||||
ExecStart=/usr/bin/env python3 /usr/local/bin/snowpanel-collect.py
|
||||
UNIT
|
||||
cat > "$TIMER" <<'TIMER'
|
||||
[Unit]
|
||||
Description=Run SnowPanel collector every minute
|
||||
|
||||
[Timer]
|
||||
OnCalendar=*-*-* *:*:00
|
||||
Persistent=true
|
||||
Unit=snowpanel-collector.service
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
TIMER
|
||||
ok "Collector units created"
|
||||
|
||||
info "Creating shaper units"
|
||||
cat > "$SHAPER_SVC" <<'UNIT'
|
||||
[Unit]
|
||||
Description=SnowPanel traffic shaper for snowflake-proxy
|
||||
After=network-online.target snowflake-proxy.service
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/local/bin/snowpanel-shaper apply
|
||||
ExecStop=/usr/local/bin/snowpanel-shaper clear
|
||||
RemainAfterExit=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
UNIT
|
||||
|
||||
cat > "$SHAPER_PATH" <<'PATHUNIT'
|
||||
[Unit]
|
||||
Description=Watch SnowPanel limits and reapply shaper
|
||||
|
||||
[Path]
|
||||
PathChanged=/var/lib/snowpanel/app.json
|
||||
PathChanged=/etc/snowpanel/app.json
|
||||
PathChanged=/etc/snowpanel/limits.json
|
||||
PathChanged=/var/lib/snowpanel/limits.json
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
PATHUNIT
|
||||
ok "Shaper units created"
|
||||
|
||||
info "Restarting services"
|
||||
systemctl daemon-reload
|
||||
systemctl enable "$PHP_FPM_SVC" nginx >/dev/null 2>&1 || true
|
||||
systemctl restart "$PHP_FPM_SVC" || true
|
||||
systemctl restart nginx
|
||||
systemctl enable --now snowflake-proxy >/dev/null 2>&1 || true
|
||||
systemctl restart snowflake-proxy || true
|
||||
systemctl enable --now snowpanel-collector.timer
|
||||
systemctl start snowpanel-collector.service || true
|
||||
systemctl enable --now snowpanel-shaper.service snowpanel-shaper.path
|
||||
systemctl restart snowpanel-shaper.service || true
|
||||
ok "Services running"
|
||||
|
||||
IP=$(hostname -I 2>/dev/null | awk '{print $1}')
|
||||
echo
|
||||
echo -e "${C_BOLD}All set!${C_RESET}"
|
||||
echo -e "URL: ${C_GRN}http://$IP/${C_RESET}"
|
||||
echo -e " First run: you'll see a setup page to create the admin user."
|
||||
Reference in New Issue
Block a user