#!/usr/bin/env bash # 学校订餐菜单生成器 - 一键部署脚本 (Ubuntu/Debian) # 用法: bash deploy.sh <域名> set -e DOMAIN="${1:-_}" APP_DIR=/opt/school-meal SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" echo "==> [1/8] 安装系统依赖" export DEBIAN_FRONTEND=noninteractive apt-get update -y apt-get install -y python3 python3-venv python3-pip nginx curl echo "==> [2/8] 安装 Node.js 20" if ! command -v node >/dev/null 2>&1; then curl -fsSL https://deb.nodesource.com/setup_20.x | bash - apt-get install -y nodejs fi echo "==> [3/8] 放置代码到 $APP_DIR" mkdir -p "$APP_DIR" cp -r "$SCRIPT_DIR/backend" "$SCRIPT_DIR/frontend" "$APP_DIR/" echo "==> [4/8] 后端环境、迁移与初始化" cd "$APP_DIR/backend" python3 -m venv .venv .venv/bin/pip install -r requirements.txt -q .venv/bin/python manage.py migrate .venv/bin/python manage.py seed_dishes .venv/bin/python manage.py collectstatic --noinput .venv/bin/python manage.py shell -c " from django.contrib.auth import get_user_model U = get_user_model() if not U.objects.filter(username='admin').exists(): U.objects.create_superuser('admin', 'admin@example.com', 'admin123') print('已创建管理员 admin / admin123') else: print('管理员 admin 已存在') " echo "==> [5/8] 后端 systemd 服务 (gunicorn)" cat > /etc/systemd/system/school-meal.service </dev/null || true systemctl daemon-reload systemctl enable --now school-meal.service systemctl restart school-meal.service echo "==> [6/8] 前端构建" cd "$APP_DIR/frontend" npm install --silent npm run build echo "==> [7/8] 配置 Nginx (域名: $DOMAIN)" cat > /etc/nginx/sites-available/school-meal < [8/8] 验证" sleep 2 curl -s -o /dev/null -w "后端 API: HTTP %{http_code}\n" http://127.0.0.1:8000/api/dishes/ curl -s -o /dev/null -w "前端页面: HTTP %{http_code}\n" http://127.0.0.1/$DOMAIN echo "" echo "部署完成!" echo " 前台页面: http://$DOMAIN/" echo " 后台管理: http://$DOMAIN/admin/ (admin / admin123,请尽快修改密码)" echo " 域名解析: 请确保 $DOMAIN 的 A 记录指向本服务器 IP"