Files
FunConnect/install.sh
xiaobai 0f183b61a4 feat: Enhance installation script and download functionality
- Add support for a force installation mode in the install script, allowing users to overwrite existing configurations and databases.
- Improve database setup logic to ensure existing users and databases are only dropped during a force installation.
- Introduce a new API endpoint to list available download files, enhancing the user experience on the download page by only displaying existing files.
- Update HTML templates to reflect the availability of download files dynamically.
2026-02-26 21:22:39 +08:00

389 lines
13 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
#
# FunMC 一键部署脚本
# 用法: bash install.sh [ -force ]
# - 无参数: 更新安装保留数据库与现有配置server.env / relay.env / credentials.txt
# - -force: 强制覆盖安装,清空数据库并重写所有配置
#
set -e
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m'
# 配置
FUNMC_VERSION="0.1.0"
INSTALL_DIR="/opt/funmc"
CONFIG_DIR="/etc/funmc"
DATA_DIR="/var/lib/funmc"
LOG_DIR="/var/log/funmc"
echo -e "${CYAN}"
echo "╔═══════════════════════════════════════════════════════════╗"
echo "║ ║"
echo "║ FunMC 服务端一键部署脚本 v${FUNMC_VERSION}"
echo "║ ║"
echo "║ 魔幻方开发 ║"
echo "║ ║"
echo "╚═══════════════════════════════════════════════════════════╝"
echo -e "${NC}"
if [ "$FORCE_INSTALL" -eq 1 ]; then
echo -e "${YELLOW}运行模式: 强制覆盖安装(将清空数据库并重写配置)${NC}"
else
echo -e "${GREEN}运行模式: 更新安装(保留数据库与现有配置)${NC}"
fi
echo ""
# 检查 root 权限
if [ "$EUID" -ne 0 ]; then
echo -e "${RED}请使用 root 权限运行此脚本${NC}"
echo "sudo bash install.sh"
exit 1
fi
# 解析参数:-force 或 --force 为强制覆盖安装,否则为更新(不覆盖数据)
FORCE_INSTALL=0
for arg in "$@"; do
if [ "$arg" = "-force" ] || [ "$arg" = "--force" ]; then
FORCE_INSTALL=1
break
fi
done
# 检测系统
detect_os() {
if [ -f /etc/os-release ]; then
. /etc/os-release
OS=$ID
OS_VERSION=$VERSION_ID
else
echo -e "${RED}无法检测操作系统${NC}"
exit 1
fi
echo -e "${GREEN}检测到系统: $OS $OS_VERSION${NC}"
}
# 安装依赖
install_deps() {
echo -e "${YELLOW}[1/7] 安装系统依赖...${NC}"
case $OS in
ubuntu|debian)
apt-get update -qq
apt-get install -y -qq curl wget git build-essential pkg-config libssl-dev postgresql postgresql-contrib nginx certbot python3-certbot-nginx
;;
centos|rhel|fedora)
dnf install -y curl wget git gcc openssl-devel postgresql-server postgresql-contrib nginx certbot python3-certbot-nginx
postgresql-setup --initdb
;;
*)
echo -e "${RED}不支持的操作系统: $OS${NC}"
exit 1
;;
esac
echo -e "${GREEN}✓ 系统依赖安装完成${NC}"
}
# 安装 Rust
install_rust() {
echo -e "${YELLOW}[2/7] 安装 Rust...${NC}"
if command -v cargo &> /dev/null; then
echo -e "${GREEN}✓ Rust 已安装${NC}"
else
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
source $HOME/.cargo/env
echo -e "${GREEN}✓ Rust 安装完成${NC}"
fi
}
# 安装 Node.js
install_nodejs() {
echo -e "${YELLOW}[3/7] 安装 Node.js...${NC}"
if command -v node &> /dev/null; then
echo -e "${GREEN}✓ Node.js 已安装${NC}"
else
curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
apt-get install -y nodejs
echo -e "${GREEN}✓ Node.js 安装完成${NC}"
fi
}
# 配置数据库(-force 时强制删除并重建,否则仅确保库存在且不覆盖数据)
setup_database() {
echo -e "${YELLOW}[4/7] 配置数据库...${NC}"
systemctl enable postgresql
systemctl start postgresql
if [ "$FORCE_INSTALL" -eq 1 ]; then
# 强制断开对 funmc 库的所有连接,再删除库和用户
sudo -u postgres psql -d postgres -c "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = 'funmc' AND pid <> pg_backend_pid();" 2>/dev/null || true
sudo -u postgres psql -d postgres -c "DROP DATABASE IF EXISTS funmc;" 2>/dev/null || true
sudo -u postgres psql -d postgres -c "DROP USER IF EXISTS funmc;" 2>/dev/null || true
sudo -u postgres psql -d postgres -c "CREATE USER funmc WITH PASSWORD '12345678';"
sudo -u postgres psql -d postgres -c "CREATE DATABASE funmc OWNER funmc;"
sudo -u postgres psql -d postgres -c "GRANT ALL PRIVILEGES ON DATABASE funmc TO funmc;"
echo -e "${GREEN}✓ 数据库已强制重建(密码 12345678${NC}"
else
# 更新模式:不删除,仅确保用户和库存在(若已存在则跳过)
sudo -u postgres psql -d postgres -c "CREATE USER funmc WITH PASSWORD '12345678';" 2>/dev/null || true
sudo -u postgres psql -d postgres -c "CREATE DATABASE funmc OWNER funmc;" 2>/dev/null || true
sudo -u postgres psql -d postgres -c "GRANT ALL PRIVILEGES ON DATABASE funmc TO funmc;" 2>/dev/null || true
echo -e "${GREEN}✓ 数据库检查完成(未覆盖现有数据)${NC}"
fi
# 配置 pg_hba.conf仅追加缺失项
PG_HBA=$(sudo -u postgres psql -t -c "SHOW hba_file;" | xargs)
if ! grep -q "funmc" "$PG_HBA"; then
echo "local funmc funmc md5" >> "$PG_HBA"
echo "host funmc funmc 127.0.0.1/32 md5" >> "$PG_HBA"
systemctl reload postgresql
fi
}
# 下载并编译 FunMC
build_funmc() {
echo -e "${YELLOW}[5/7] 编译 FunMC...${NC}"
# 创建目录(含客户端下载目录)
mkdir -p $INSTALL_DIR $INSTALL_DIR/downloads $CONFIG_DIR $DATA_DIR $LOG_DIR
# 克隆或更新代码
if [ -d "$INSTALL_DIR/src" ]; then
cd $INSTALL_DIR/src
git pull
else
git clone https://gt.funmc.cn/xiaobai/FunConnect.git $INSTALL_DIR/src
cd $INSTALL_DIR/src
fi
# 编译服务端
source $HOME/.cargo/env
cargo build --release -p funmc-server -p funmc-relay-server
# 复制二进制文件包名与二进制名不同server / relay-server
cp target/release/server $INSTALL_DIR/funmc-server
cp target/release/relay-server $INSTALL_DIR/funmc-relay-server
# 编译管理面板前端(使用官方 registry 避免镜像返回 HTML 导致 FETCH_ERROR
cd $INSTALL_DIR/src/admin-panel
npm install --registry https://registry.npmjs.org/
npm run build
cp -r dist $INSTALL_DIR/admin-panel
echo -e "${GREEN}✓ FunMC 编译完成${NC}"
}
# 配置服务(-force 时重写配置;否则若已有配置则保留仅做迁移与重启)
configure_services() {
echo -e "${YELLOW}[6/7] 配置服务...${NC}"
WROTE_CONFIG=0
if [ "$FORCE_INSTALL" -eq 1 ] || [ ! -f "$CONFIG_DIR/server.env" ]; then
# 强制安装或首次安装:生成新配置
WROTE_CONFIG=1
DB_PASSWORD="12345678"
JWT_SECRET=$(openssl rand -base64 48 | tr -dc 'a-zA-Z0-9' | head -c 48)
ADMIN_PASSWORD=$(openssl rand -base64 16 | tr -dc 'a-zA-Z0-9' | head -c 12)
SERVER_IP=$(curl -s ifconfig.me || curl -s ipinfo.io/ip || hostname -I | awk '{print $1}')
cat > $CONFIG_DIR/server.env << EOF
# FunMC 服务端配置
DATABASE_URL=postgres://funmc:${DB_PASSWORD}@localhost/funmc
JWT_SECRET=${JWT_SECRET}
BIND_ADDR=0.0.0.0:3000
QUIC_PORT=3001
RUST_LOG=info
# 服务器信息
SERVER_NAME=FunMC Server
SERVER_IP=${SERVER_IP}
SERVER_DOMAIN=
# 管理面板
ADMIN_ENABLED=true
ADMIN_USERNAME=admin
ADMIN_PASSWORD=${ADMIN_PASSWORD}
# 客户端下载
CLIENT_DOWNLOAD_ENABLED=true
CLIENT_VERSION=${FUNMC_VERSION}
DOWNLOADS_DIR=$INSTALL_DIR/downloads
EOF
cat > $CONFIG_DIR/relay.env << EOF
RELAY_PORT=7900
JWT_SECRET=${JWT_SECRET}
RUST_LOG=info
EOF
else
# 更新模式:保留现有配置,仅确保 DB_PASSWORD 等变量存在供后续迁移使用
DB_PASSWORD=$(grep DATABASE_URL "$CONFIG_DIR/server.env" 2>/dev/null | sed -n 's/.*:\/\/funmc:\([^@]*\)@.*/\1/p')
if [ -z "$DB_PASSWORD" ]; then
DB_PASSWORD="12345678"
fi
echo -e "${GREEN}✓ 保留现有配置(未覆盖 server.env / relay.env${NC}"
fi
# 创建 systemd 服务文件(始终更新以便安装路径等变更生效)
cat > /etc/systemd/system/funmc-server.service << EOF
[Unit]
Description=FunMC API Server
After=network.target postgresql.service
[Service]
Type=simple
User=root
WorkingDirectory=$INSTALL_DIR
EnvironmentFile=$CONFIG_DIR/server.env
ExecStart=$INSTALL_DIR/funmc-server
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
cat > /etc/systemd/system/funmc-relay.service << EOF
[Unit]
Description=FunMC Relay Server
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=$INSTALL_DIR
EnvironmentFile=$CONFIG_DIR/relay.env
ExecStart=$INSTALL_DIR/funmc-relay-server
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
# 安装 sqlx-cli若未安装并运行数据库迁移
export PATH="$HOME/.cargo/bin:$PATH"
if ! command -v sqlx &> /dev/null; then
cargo install sqlx-cli --no-default-features --features postgres
fi
cd $INSTALL_DIR/src/server
export DATABASE_URL="postgres://funmc:${DB_PASSWORD}@localhost/funmc"
sqlx migrate run
# 启动服务
systemctl daemon-reload
systemctl enable funmc-server funmc-relay
systemctl start funmc-server funmc-relay
echo -e "${GREEN}✓ 服务配置完成${NC}"
# 仅强制/首次安装时写入凭据文件,更新模式不覆盖
if [ "$WROTE_CONFIG" -eq 1 ]; then
cat > $CONFIG_DIR/credentials.txt << EOF
======================================
FunMC 服务端安装信息
======================================
服务器 IP: ${SERVER_IP}
API 地址: http://${SERVER_IP}:3000
管理面板: http://${SERVER_IP}:3000/admin
管理员账号: admin
管理员密码: ${ADMIN_PASSWORD}
数据库密码: ${DB_PASSWORD}
JWT 密钥: ${JWT_SECRET}
======================================
请妥善保管此文件!
======================================
EOF
chmod 600 $CONFIG_DIR/credentials.txt
fi
}
# 配置防火墙
configure_firewall() {
echo -e "${YELLOW}[7/7] 配置防火墙...${NC}"
if command -v ufw &> /dev/null; then
ufw allow 80/tcp
ufw allow 443/tcp
ufw allow 3000/tcp
ufw allow 7900/udp
ufw allow 7901/udp
echo -e "${GREEN}✓ UFW 防火墙配置完成${NC}"
elif command -v firewall-cmd &> /dev/null; then
firewall-cmd --permanent --add-port=80/tcp
firewall-cmd --permanent --add-port=443/tcp
firewall-cmd --permanent --add-port=3000/tcp
firewall-cmd --permanent --add-port=7900/udp
firewall-cmd --permanent --add-port=7901/udp
firewall-cmd --reload
echo -e "${GREEN}✓ firewalld 防火墙配置完成${NC}"
else
echo -e "${YELLOW}! 未检测到防火墙,请手动开放端口 80, 443, 3000, 7900, 7901${NC}"
fi
}
# 显示完成信息
show_completion() {
SERVER_IP=$(cat $CONFIG_DIR/server.env | grep SERVER_IP | cut -d= -f2)
ADMIN_PASSWORD=$(cat $CONFIG_DIR/server.env | grep ADMIN_PASSWORD | cut -d= -f2)
echo ""
echo -e "${CYAN}╔═══════════════════════════════════════════════════════════╗${NC}"
echo -e "${CYAN}║ ║${NC}"
echo -e "${CYAN}${GREEN}FunMC 安装完成!${CYAN}${NC}"
echo -e "${CYAN}║ ║${NC}"
echo -e "${CYAN}╚═══════════════════════════════════════════════════════════╝${NC}"
echo ""
echo -e "${GREEN}服务器信息:${NC}"
echo -e " API 地址: http://${SERVER_IP}:3000"
echo -e " 管理面板: http://${SERVER_IP}:3000/admin"
echo ""
echo -e "${GREEN}管理员登录:${NC}"
echo -e " 用户名: admin"
echo -e " 密码: ${ADMIN_PASSWORD}"
echo ""
echo -e "${GREEN}客户端下载:${NC}"
echo -e " http://${SERVER_IP}:3000/download"
echo ""
echo -e "${YELLOW}重要文件:${NC}"
echo -e " 配置文件: $CONFIG_DIR/server.env"
echo -e " 凭据信息: $CONFIG_DIR/credentials.txt"
echo -e " 日志文件: $LOG_DIR/"
echo ""
echo -e "${CYAN}服务管理命令:${NC}"
echo -e " 查看状态: systemctl status funmc-server"
echo -e " 重启服务: systemctl restart funmc-server"
echo -e " 查看日志: journalctl -u funmc-server -f"
echo ""
echo -e "${GREEN}魔幻方开发 - 让 Minecraft 联机变得简单${NC}"
}
# 主流程
main() {
detect_os
install_deps
install_rust
install_nodejs
setup_database
build_funmc
configure_services
configure_firewall
show_completion
}
# 运行
main "$@"