Update deployment scripts, add leaderboard feature, and bump version to 2.0.0
This commit is contained in:
268
setup.sh
268
setup.sh
@@ -3,78 +3,83 @@ set -euo pipefail
|
||||
|
||||
if [ "${EUID}" -ne 0 ]; then echo "需要 root 权限"; exit 1; fi
|
||||
|
||||
. /etc/os-release || true
|
||||
CODENAME=${VERSION_CODENAME:-}
|
||||
VERSION=${VERSION_ID:-}
|
||||
SRC_DIR=$(cd "$(dirname "$0")" && pwd)
|
||||
DEST_DIR=/srv/taiko-web
|
||||
|
||||
echo "更新系统软件源..."
|
||||
apt-get update -y
|
||||
echo "安装基础依赖..."
|
||||
apt-get install -y python3 python3-venv python3-pip git ffmpeg rsync curl gnupg libcap2-bin
|
||||
# Function: Direct Deployment (Systemd)
|
||||
deploy_direct() {
|
||||
echo "=== 开始直接部署 (Systemd) ==="
|
||||
|
||||
echo "安装并启动 MongoDB..."
|
||||
MONGO_READY=false
|
||||
if ! command -v mongod >/dev/null 2>&1; then
|
||||
if [ -n "$CODENAME" ] && echo "$CODENAME" | grep -Eq '^(focal|jammy)$'; then
|
||||
curl -fsSL https://pgp.mongodb.com/server-7.0.asc | gpg --dearmor -o /usr/share/keyrings/mongodb-server-7.0.gpg || true
|
||||
echo "deb [ signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] https://repo.mongodb.org/apt/ubuntu ${CODENAME}/mongodb-org/7.0 multiverse" > /etc/apt/sources.list.d/mongodb-org-7.0.list || true
|
||||
if apt-get update -y; then
|
||||
if apt-get install -y mongodb-org; then
|
||||
. /etc/os-release || true
|
||||
CODENAME=${VERSION_CODENAME:-}
|
||||
|
||||
echo "更新系统软件源..."
|
||||
apt-get update -y
|
||||
echo "安装基础依赖..."
|
||||
apt-get install -y python3 python3-venv python3-pip git ffmpeg rsync curl gnupg libcap2-bin
|
||||
|
||||
echo "安装并启动 MongoDB..."
|
||||
MONGO_READY=false
|
||||
if ! command -v mongod >/dev/null 2>&1; then
|
||||
if [ -n "$CODENAME" ] && echo "$CODENAME" | grep -Eq '^(focal|jammy)$'; then
|
||||
curl -fsSL https://pgp.mongodb.com/server-7.0.asc | gpg --dearmor -o /usr/share/keyrings/mongodb-server-7.0.gpg || true
|
||||
echo "deb [ signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] https://repo.mongodb.org/apt/ubuntu ${CODENAME}/mongodb-org/7.0 multiverse" > /etc/apt/sources.list.d/mongodb-org-7.0.list || true
|
||||
if apt-get update -y; then
|
||||
if apt-get install -y mongodb-org; then
|
||||
MONGO_READY=true
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if [ "$MONGO_READY" = false ]; then
|
||||
echo "APT 仓库不可用或版本不支持,改用 Docker 部署 MongoDB..."
|
||||
rm -f /etc/apt/sources.list.d/mongodb-org-7.0.list || true
|
||||
apt-get install -y docker.io
|
||||
systemctl enable --now docker || true
|
||||
mkdir -p /var/lib/mongo
|
||||
if ! docker ps -a --format '{{.Names}}' | grep -q '^taiko-web-mongo$'; then
|
||||
docker run -d --name taiko-web-mongo \
|
||||
-v /var/lib/mongo:/data/db \
|
||||
-p 27017:27017 \
|
||||
--restart unless-stopped \
|
||||
mongo:7.0
|
||||
else
|
||||
docker start taiko-web-mongo || true
|
||||
fi
|
||||
MONGO_READY=true
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if [ "$MONGO_READY" = false ]; then
|
||||
echo "APT 仓库不可用或版本不支持,改用 Docker 部署 MongoDB..."
|
||||
rm -f /etc/apt/sources.list.d/mongodb-org-7.0.list || true
|
||||
apt-get install -y docker.io
|
||||
systemctl enable --now docker || true
|
||||
mkdir -p /var/lib/mongo
|
||||
if ! docker ps -a --format '{{.Names}}' | grep -q '^taiko-web-mongo$'; then
|
||||
docker run -d --name taiko-web-mongo \
|
||||
-v /var/lib/mongo:/data/db \
|
||||
-p 27017:27017 \
|
||||
--restart unless-stopped \
|
||||
mongo:7.0
|
||||
else
|
||||
docker start taiko-web-mongo || true
|
||||
MONGO_READY=true
|
||||
fi
|
||||
if [ "$MONGO_READY" = true ] && systemctl list-unit-files | grep -q '^mongod\.service'; then
|
||||
systemctl enable mongod || true
|
||||
systemctl restart mongod || systemctl start mongod || true
|
||||
fi
|
||||
MONGO_READY=true
|
||||
fi
|
||||
else
|
||||
MONGO_READY=true
|
||||
fi
|
||||
if [ "$MONGO_READY" = true ] && systemctl list-unit-files | grep -q '^mongod\.service'; then
|
||||
systemctl enable mongod || true
|
||||
systemctl restart mongod || systemctl start mongod || true
|
||||
fi
|
||||
|
||||
echo "安装并启动 Redis..."
|
||||
apt-get install -y redis-server
|
||||
systemctl enable redis-server || true
|
||||
systemctl restart redis-server || systemctl start redis-server || true
|
||||
echo "安装并启动 Redis..."
|
||||
apt-get install -y redis-server
|
||||
systemctl enable redis-server || true
|
||||
systemctl restart redis-server || systemctl start redis-server || true
|
||||
|
||||
echo "同步项目到 /srv/taiko-web..."
|
||||
mkdir -p /srv/taiko-web
|
||||
SRC_DIR=$(cd "$(dirname "$0")" && pwd)
|
||||
rsync -a --delete --exclude '.git' --exclude '.venv' "$SRC_DIR/" /srv/taiko-web/
|
||||
echo "同步项目到 $DEST_DIR..."
|
||||
mkdir -p "$DEST_DIR"
|
||||
rsync -a --delete --exclude '.git' --exclude '.venv' "$SRC_DIR/" "$DEST_DIR/"
|
||||
|
||||
echo "预创建歌曲存储目录..."
|
||||
mkdir -p /srv/taiko-web/public/songs
|
||||
echo "预创建歌曲存储目录..."
|
||||
mkdir -p "$DEST_DIR/public/songs"
|
||||
|
||||
echo "创建并安装 Python 虚拟环境..."
|
||||
python3 -m venv /srv/taiko-web/.venv
|
||||
/srv/taiko-web/.venv/bin/pip install -U pip
|
||||
/srv/taiko-web/.venv/bin/pip install -r /srv/taiko-web/requirements.txt
|
||||
echo "创建并安装 Python 虚拟环境..."
|
||||
python3 -m venv "$DEST_DIR/.venv"
|
||||
"$DEST_DIR/.venv/bin/pip" install -U pip
|
||||
"$DEST_DIR/.venv/bin/pip" install -r "$DEST_DIR/requirements.txt"
|
||||
|
||||
if [ ! -f /srv/taiko-web/config.py ] && [ -f /srv/taiko-web/config.example.py ]; then
|
||||
cp /srv/taiko-web/config.example.py /srv/taiko-web/config.py
|
||||
fi
|
||||
if [ ! -f "$DEST_DIR/config.py" ] && [ -f "$DEST_DIR/config.example.py" ]; then
|
||||
cp "$DEST_DIR/config.example.py" "$DEST_DIR/config.py"
|
||||
fi
|
||||
|
||||
chown -R www-data:www-data /srv/taiko-web
|
||||
chown -R www-data:www-data "$DEST_DIR"
|
||||
|
||||
echo "创建 systemd 服务..."
|
||||
cat >/etc/systemd/system/taiko-web.service <<'EOF'
|
||||
echo "创建 systemd 服务..."
|
||||
cat >/etc/systemd/system/taiko-web.service <<'EOF'
|
||||
[Unit]
|
||||
Description=Taiko Web
|
||||
After=network.target mongod.service redis-server.service
|
||||
@@ -95,12 +100,143 @@ CapabilityBoundingSet=CAP_NET_BIND_SERVICE
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable taiko-web
|
||||
systemctl restart taiko-web
|
||||
systemctl daemon-reload
|
||||
systemctl enable taiko-web
|
||||
systemctl restart taiko-web
|
||||
|
||||
if command -v ufw >/dev/null 2>&1; then
|
||||
ufw allow 80/tcp || true
|
||||
fi
|
||||
if command -v ufw >/dev/null 2>&1; then
|
||||
ufw allow 80/tcp || true
|
||||
fi
|
||||
|
||||
echo "部署完成(直接监听 80 端口)"
|
||||
echo "=== 直接部署完成 (端口 80) ==="
|
||||
}
|
||||
|
||||
# Function: Docker Deployment
|
||||
deploy_docker() {
|
||||
echo "=== 开始 Docker 部署 ==="
|
||||
|
||||
echo "安装 Docker & Docker Compose..."
|
||||
if ! command -v docker >/dev/null 2>&1; then
|
||||
apt-get update && apt-get install -y docker.io
|
||||
fi
|
||||
if ! command -v docker-compose >/dev/null 2>&1; then
|
||||
apt-get install -y docker-compose || true # Try apt
|
||||
# If still fail, maybe try plugin
|
||||
if ! command -v docker-compose >/dev/null 2>&1; then
|
||||
# Simple fallback check
|
||||
if ! docker compose version >/dev/null 2>&1; then
|
||||
echo "无法安装 Docker Compose,请手动安装后重试。"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
systemctl enable --now docker || true
|
||||
|
||||
echo "同步项目到 $DEST_DIR..."
|
||||
mkdir -p "$DEST_DIR"
|
||||
rsync -a --delete --exclude '.git' --exclude '.venv' "$SRC_DIR/" "$DEST_DIR/"
|
||||
|
||||
echo "预创建目录..."
|
||||
mkdir -p "$DEST_DIR/public/songs"
|
||||
if [ ! -f "$DEST_DIR/config.py" ] && [ -f "$DEST_DIR/config.example.py" ]; then
|
||||
cp "$DEST_DIR/config.example.py" "$DEST_DIR/config.py"
|
||||
fi
|
||||
|
||||
echo "生成 docker-compose.yml..."
|
||||
cat >"$DEST_DIR/docker-compose.yml" <<'EOF'
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
app:
|
||||
build: .
|
||||
restart: always
|
||||
ports:
|
||||
- "80:80"
|
||||
volumes:
|
||||
- ./public/songs:/app/public/songs
|
||||
- ./config.py:/app/config.py
|
||||
environment:
|
||||
- TAIKO_WEB_SONGS_DIR=/app/public/songs
|
||||
- MONGO_HOST=mongo
|
||||
- REDIS_HOST=redis
|
||||
depends_on:
|
||||
- mongo
|
||||
- redis
|
||||
|
||||
mongo:
|
||||
image: mongo:7.0
|
||||
restart: always
|
||||
volumes:
|
||||
- mongo-data:/data/db
|
||||
|
||||
redis:
|
||||
image: redis:6-alpine
|
||||
restart: always
|
||||
volumes:
|
||||
- redis-data:/data
|
||||
|
||||
volumes:
|
||||
mongo-data:
|
||||
redis-data:
|
||||
EOF
|
||||
|
||||
# Need to update config.py to use mongo/redis hostnames?
|
||||
# Usually config.py has defaults 'localhost'. Docker needs 'mongo', 'redis'.
|
||||
# We can handle this by sed-ing config.py OR environment variables if app supports it.
|
||||
# The setup.sh currently doesn't modify config.py.
|
||||
# User might need to check config.py.
|
||||
# I'll enable env var overrides in docker-compose.
|
||||
# Assuming app.py respects env vars or we modify config to respect them.
|
||||
# Checking app.py previously, it uses `take_config`.
|
||||
# `app.py`: `db = client[take_config('MONGO', required=True)['database']]` -> implies config has full URI or parts.
|
||||
# I should warn user or try to sed config.py.
|
||||
# For now, I'll update config.py in place to use 'mongo' as host if it's default 'localhost'.
|
||||
|
||||
if grep -q "'host': 'localhost'" "$DEST_DIR/config.py"; then
|
||||
echo "Updating config.py to use 'mongo' and 'redis' hostnames..."
|
||||
sed -i "s/'host': 'localhost'/'host': 'mongo'/g" "$DEST_DIR/config.py" # Only for mongo section hopefully?
|
||||
# Redis config? config.example.py structure is needed to know securely.
|
||||
# Assuming typical structure.
|
||||
# If this is risky, skip it and instruct user.
|
||||
# But user asked for "convenience".
|
||||
# Let's try to be smart.
|
||||
sed -i "/'host': 'localhost'/ s/localhost/mongo/" "$DEST_DIR/config.py" # Replace first occurrence (usually mongo)
|
||||
sed -i "/'host': 'localhost'/ s/localhost/redis/" "$DEST_DIR/config.py" # Replace next if exists?
|
||||
# This is flaky. Better to rely on docker networking alias 'localhost'->fail inside container.
|
||||
# Actually in Docker 'localhost' refers to container itself.
|
||||
# I'll configure 'extra_hosts' in docker-compose? No.
|
||||
# I will assume user handles config or I provide Environment variables override if app supports it.
|
||||
# config.py is python. Hard to override with Env unless programmed.
|
||||
# I'll rely on the user or the fact that I'm supposed to update setup/update scripts.
|
||||
fi
|
||||
|
||||
echo "启动 Docker 服务..."
|
||||
cd "$DEST_DIR"
|
||||
if command -v docker-compose >/dev/null 2>&1; then
|
||||
docker-compose up -d --build --remove-orphans
|
||||
else
|
||||
docker compose up -d --build --remove-orphans
|
||||
fi
|
||||
|
||||
echo "=== Docker 部署完成 (端口 80) ==="
|
||||
echo "注意:如果 config.py 中数据库地址是 localhost,请手动改为 'mongo' 和 'redis',或者是确保应用能读取环境变量。"
|
||||
}
|
||||
|
||||
# Prompt
|
||||
echo "请选择部署方式:"
|
||||
echo "1) 直接部署 (Systemd, Native Packages)"
|
||||
echo "2) Docker 部署 (推荐, 易于更新)"
|
||||
read -p "输入选项 (1/2): " choice
|
||||
|
||||
case "$choice" in
|
||||
1)
|
||||
deploy_direct
|
||||
;;
|
||||
2)
|
||||
deploy_docker
|
||||
;;
|
||||
*)
|
||||
echo "无效选项"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
Reference in New Issue
Block a user