#!/usr/bin/env bash # 部署脚本:在远程服务器上跑一次 # 用法: bash /root/deploy_news.sh set -euo pipefail # === 配置 === GITEA_URL="http://124.223.26.33:3000/xiaji/diary-news.git" APP_DIR="/srv/news" DOMAIN="" # 留空走 IP log() { echo "[$(date +'%H:%M:%S')] $*"; } fail() { echo "[FAIL] $*" >&2; exit 1; } # === 1. 系统初始化 === log "1/8 系统更新 + 基础包" export DEBIAN_FRONTEND=noninteractive apt-get update -y apt-get install -y --no-install-recommends curl git ufw fail2ban openssl ca-certificates # === 2. 创建非 root 用户(后续切过去) === if ! id news &>/dev/null; then log "2/8 创建 news 用户" adduser --disabled-password --gecos "" news echo "news ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/news fi # === 3. Docker === if ! command -v docker &>/dev/null; then log "3/8 安装 Docker" curl -fsSL https://get.docker.com -o /tmp/get-docker.sh sh /tmp/get-docker.sh usermod -aG docker news fi docker --version # === 4. 防火墙 === log "4/8 防火墙" SSHD_PORT="${SSHD_PORT:-22}" # 自定义 SSH 端口(默认 22) ufw --force reset ufw default deny incoming ufw default allow outgoing ufw allow "${SSHD_PORT}/tcp" comment 'ssh' ufw allow 80/tcp comment 'http' ufw allow 443/tcp comment 'https' ufw --force enable ufw status verbose # === 5. 拉代码 === log "5/8 拉代码到 $APP_DIR" mkdir -p "$APP_DIR" if [ ! -d "$APP_DIR/.git" ]; then sudo -u news git clone "$GITEA_URL" "$APP_DIR" else cd "$APP_DIR" && sudo -u news git pull --rebase fi chown -R news:news "$APP_DIR" # === 6. 写 .env(自动生成密码) === log "6/8 生成 .env" if [ ! -f "$APP_DIR/.env" ]; then cat > "$APP_DIR/.env" </dev/null; then break fi sleep 2 done for i in {1..30}; do if dc exec -T redis redis-cli -a "$(grep ^REDIS_PASSWORD $APP_DIR/.env | cut -d= -f2)" ping 2>/dev/null | grep -q PONG; then break fi sleep 2 done # === 8. 初始化 === log "8/8 数据库迁移 + 用户 + 源" dc exec -T api alembic upgrade head # 创建 owner(从 env 或自动生成,避免后台跑卡在 read) if [ -n "${OWNER_PASS:-}" ]; then log " 使用环境变量 OWNER_PASS" else OWNER_PASS="$(openssl rand -hex 12)" log " 自动生成 owner 密码(写入 /root/.owner_pass): $OWNER_PASS" fi dc exec -T api python -m app.scripts.create_user --username owner --password "$OWNER_PASS" || true echo "$OWNER_PASS" > /root/.owner_pass chmod 600 /root/.owner_pass # 种子 dc exec -T api python -m app.scripts.seed_sources # 健康检查 log " 健康检查" sleep 3 curl -s http://localhost/api/v1/healthz && echo echo echo "================================================" echo " 部署完成!" echo " 访问: http://$(curl -s ifconfig.me)/" echo " 账号: owner" echo " 密码: 写入到 /root/.owner_pass (chmod 600)" echo " 后续: docker compose -f $APP_DIR/docker-compose.yml logs -f" echo "================================================"