校园失物招领平台项目自动化部署指南(Docker + Nginx)

一、项目概述

本项目是一个基于 Flask 的校园众筹平台,采用 Docker 容器化部署,Nginx 作为反向代理服务器。本文档提供一套完整的手动部署步骤及其自动化脚本,帮助你在 CentOS 7+ 服务器上快速搭建环境,并确保基本的安全性。

注意:当前网站仅用于技术演示,未投入实际生产,因此安全性措施以满足基本防护为主(如仅开放必要端口、最小权限原则)。若用于生产环境,请根据业务需求加强数据备份、访问控制等。


二、环境准备

2.1 服务器要求

  • 操作系统:CentOS 7 / RHEL 7+(或其他 systemd 发行版)

  • 已安装 Docker 和 Docker Compose 插件

  • 已安装 Nginx

  • 防火墙使用 firewalld(脚本自动配置)

  • 云服务器需在安全组开放 80 端口(TCP)

2.2 项目文件

确保服务器上存在以下文件(路径可自定义):

  • /opt/campus_project/campus_crowdfunding/

    • app.py --- Flask 应用主文件,确保监听 0.0.0.0:8000debug=False

    • requirements.txt --- Python 依赖列表

    • Dockerfile --- 用于构建 Flask 镜像

    • docker-compose.yml --- 定义服务(web 容器、数据库等)

  • /etc/nginx/nginx.conf --- Nginx 主配置文件(需提前准备好反向代理配置)

若尚未编写 docker-compose.ymlDockerfile,请先根据项目需求创建。


三、手动部署步骤(简述)

  1. 清理旧环境

    bash

    复制代码
    docker compose down
    docker stop $(docker ps -a | grep campus | awk '{print $1}') 2>/dev/null
    docker rm $(docker ps -a | grep campus | awk '{print $1}') 2>/dev/null
    docker rmi $(docker images | grep campus | awk '{print $3}') 2>/dev/null
  2. 更新代码与权限

    bash

    复制代码
    rm -rf /opt/campus_project/campus_crowdfunding/*   # 谨慎使用,确保已备份
    chmod -R 755 /opt/campus_project/campus_crowdfunding
    chown -R root:root /opt/campus_project/campus_crowdfunding
  3. 检查基础服务

    bash

    复制代码
    systemctl status docker
    systemctl status nginx
  4. 修改 Flask 配置

    确保 app.py 中包含:app.run(host='0.0.0.0', port=8000, debug=False)

  5. 构建并启动容器

    bash

    复制代码
    cd /opt/campus_project/campus_crowdfunding
    docker compose up -d --build
    docker compose ps
    docker compose logs campus_app
    curl http://127.0.0.1:8000   # 验证本地访问
  6. 配置 Nginx

    bash

    复制代码
    vi /etc/nginx/nginx.conf      # 添加或修改反向代理配置
    nginx -t                       # 检查语法
    systemctl restart nginx
    netstat -tulpn | grep :80      # 确认80端口监听
  7. 防火墙与安全组

    bash

    复制代码
    firewall-cmd --add-port=80/tcp --permanent
    firewall-cmd --reload

    最后登录云控制台,确保安全组入方向放行 80 端口(来源 0.0.0.0/0)。


四、自动化部署脚本

将上述手动步骤封装为脚本,减少人工干预,提高部署效率。脚本已集成错误处理、等待机制和友好提示。

4.1 脚本内容

创建文件 /opt/campus_project/campus_crowdfunding/deploy.sh,并赋予执行权限:

bash

复制代码
chmod +x /opt/campus_project/campus_crowdfunding/deploy.sh

脚本完整内容如下(可根据实际路径修改变量):

bash

复制代码
#!/bin/bash
set -euo pipefail

# ==================================================
# 校园众筹项目自动部署脚本
# 适用环境:CentOS/RHEL 7+,使用 systemd、firewalld
# 使用方法:sudo ./deploy.sh
# 注意:请确保在运行前已手动修改 app.py 和 nginx.conf(如需)
# ==================================================

# ---------- 配置变量(请根据实际情况修改)----------
PROJECT_DIR="/opt/campus_project/campus_crowdfunding"
FLASK_PORT=8000
NGINX_PORT=80
COMPOSE_FILE="docker-compose.yml"
BACKUP_NGINX_CONF=true
AUTO_CLEAN_FILES=false
# -------------------------------------------------

# 颜色定义
GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m'; BLUE='\033[0;34m'; NC='\033[0m'

log_info() { echo -e "${GREEN}[INFO]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1"; }
log_step() { echo -e "${BLUE}>>>${NC} $1"; }

# 检查必要命令
check_commands() {
    local cmds=("docker" "nginx" "firewall-cmd" "systemctl" "curl")
    for cmd in "${cmds[@]}"; do
        if ! command -v "$cmd" &> /dev/null; then
            log_error "命令 '$cmd' 未找到,请安装后重试。"
            exit 1
        fi
    done
    if ! docker compose version &> /dev/null; then
        log_error "docker compose 插件不可用,请安装或使用旧版 docker-compose。"
        exit 1
    fi
}

# 等待 Flask 应用就绪
wait_for_flask() {
    local url="http://127.0.0.1:$FLASK_PORT"
    log_info "等待 Flask 应用启动(最多 60 秒)..."
    for i in {1..30}; do
        if curl -s -f "$url" > /dev/null 2>&1; then
            log_info "Flask 应用已就绪"
            return 0
        fi
        sleep 2
    done
    log_error "Flask 应用启动超时,请检查容器日志。"
    return 1
}

# 主流程
main() {
    log_step "开始部署校园众筹项目"
    check_commands

    # 进入项目目录
    if [ ! -d "$PROJECT_DIR" ]; then
        log_error "项目目录 $PROJECT_DIR 不存在"
        exit 1
    fi
    cd "$PROJECT_DIR"
    log_info "切换到目录:$PROJECT_DIR"

    # 清理旧容器和镜像
    log_step "步骤1:清理旧容器及镜像"
    if [ -f "$COMPOSE_FILE" ]; then
        log_info "执行 docker compose down --rmi all --volumes"
        docker compose down --rmi all --volumes 2>/dev/null || log_warn "清理过程中出现非致命错误,继续执行"
    else
        log_warn "未找到 $COMPOSE_FILE,跳过 compose 清理"
    fi

    # 清理旧文件(可选)
    if [ "$AUTO_CLEAN_FILES" = true ]; then
        log_step "步骤2:清理项目目录下的所有文件"
        read -p "是否确定删除 $PROJECT_DIR 下的所有文件?(y/N) " -n 1 -r
        echo
        if [[ $REPLY =~ ^[Yy]$ ]]; then
            rm -rf "${PROJECT_DIR:?}"/*
            log_info "已清空 $PROJECT_DIR"
        else
            log_warn "跳过文件清理"
        fi
    else
        log_info "跳过自动文件清理(AUTO_CLEAN_FILES=false),请手动确保文件已更新"
    fi

    # 设置目录权限
    log_step "步骤2:设置目录权限"
    chmod -R 755 "$PROJECT_DIR"
    chown -R root:root "$PROJECT_DIR"
    log_info "权限设置为 755,所有者 root:root"

    # 检查 Docker 和 Nginx 服务
    log_step "步骤3:检查基础服务状态"
    systemctl is-active --quiet docker || { log_error "Docker 未运行"; exit 1; }
    log_info "Docker 运行正常"
    systemctl is-active --quiet nginx || { log_error "Nginx 未运行"; exit 1; }
    log_info "Nginx 运行正常"

    # 检查 Nginx 当前语法
    log_info "检查现有 Nginx 配置语法"
    nginx -t || { log_error "Nginx 配置语法错误,请先手动修复"; exit 1; }

    # 构建并启动容器
    log_step "步骤5:构建并启动 Flask 容器"
    log_info "执行 docker compose up -d --build"
    docker compose up -d --build

    log_info "检查容器状态"
    docker compose ps
    log_info "容器最新日志:"
    docker compose logs --tail=20 campus_app || true

    wait_for_flask || { log_error "Flask 应用未正常响应,退出部署"; exit 1; }

    # Nginx 配置处理
    log_step "步骤6:Nginx 配置检查与重载"
    if [ "$BACKUP_NGINX_CONF" = true ] && [ -f /etc/nginx/nginx.conf ]; then
        backup_file="/etc/nginx/nginx.conf.bak.$(date +%Y%m%d-%H%M%S)"
        cp /etc/nginx/nginx.conf "$backup_file"
        log_info "已备份当前 Nginx 配置至 $backup_file"
    fi

    log_warn "请手动检查/编辑 Nginx 配置文件:vi /etc/nginx/nginx.conf"
    read -p "确认已完成 Nginx 配置修改?(y/N) " -n 1 -r
    echo
    if [[ ! $REPLY =~ ^[Yy]$ ]]; then
        log_error "用户取消部署"
        exit 1
    fi

    log_info "检查 Nginx 配置语法"
    nginx -t || { log_error "Nginx 配置语法错误,请检查刚才的修改"; exit 1; }

    log_info "重载 Nginx 服务"
    systemctl reload nginx

    # 验证端口监听
    log_info "验证端口 $NGINX_PORT 监听状态"
    if netstat -tulpn 2>/dev/null | grep -q ":$NGINX_PORT "; then
        log_info "端口 $NGINX_PORT 已被监听"
    else
        log_warn "端口 $NGINX_PORT 未被监听,请检查 Nginx 配置"
    fi

    # 防火墙放行
    log_info "检查防火墙端口 $NGINX_PORT"
    if firewall-cmd --list-ports | grep -q "$NGINX_PORT/tcp"; then
        log_info "防火墙端口 $NGINX_PORT 已开放"
    else
        log_warn "防火墙端口 $NGINX_PORT 未开放,尝试添加"
        firewall-cmd --add-port="$NGINX_PORT/tcp" --permanent
        firewall-cmd --reload
        log_info "防火墙端口已添加"
    fi

    # 最终提示
    log_step "部署完成"
    echo -e "${GREEN}================================================"
    echo "请务必登录云控制台,确认安全组已放行 $NGINX_PORT 端口(0.0.0.0/0)"
    echo "测试访问:http://你的服务器公网IP"
    echo "查看容器日志:docker compose logs -f campus_app"
    echo "================================================${NC}"
}

main "$@"

4.2 使用前准备

  • 修改变量 :根据实际项目路径修改 PROJECT_DIRFLASK_PORT 等。

  • 确保配置正确

    • app.py 已按生产环境配置(debug=False)。

    • Nginx 配置文件已准备好反向代理规则(示例见下文)。

    • docker-compose.yml 中服务名称为 campus_app(脚本中日志查看用了该名称,若不同请修改)。

  • 数据持久化 :若数据库使用容器,确保 docker-compose.yml 中已挂载卷,否则 down --volumes 会删除数据。

4.3 执行脚本

bash

复制代码
sudo /opt/campus_project/campus_crowdfunding/deploy.sh

脚本运行过程中会:

  1. 自动清理旧容器、镜像和网络。

  2. 询问是否删除项目目录文件(默认否,需手动更新代码)。

  3. 设置目录权限。

  4. 检查 Docker 和 Nginx 服务。

  5. 构建并启动容器,等待 Flask 就绪。

  6. 暂停等待用户编辑 Nginx 配置(按 y 继续)。

  7. 验证 Nginx 语法并重载。

  8. 开放防火墙端口。

  9. 提示检查云安全组。


五、Nginx 配置示例

/etc/nginx/nginx.confhttp 块内添加或修改以下 server 块(注意不要覆盖原有配置):

nginx

复制代码
server {
    listen 80;
    listen [::]:80;
    server_name _;

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

如果已有其他服务(如 8082 端口的默认页面),请保留并确保不冲突。


相关推荐
IT从业者张某某2 小时前
Docker部署Hadoop-02-Docker常见操作
hadoop·docker·容器
不懒不懒2 小时前
【苏宁易购商品评价文本分析实战:从自动化爬取到分词清洗全流程】
运维·数据库·自动化
Q鑫2 小时前
K8s之pod解析与调度策略
docker·容器·kubernetes
Codefengfeng2 小时前
如何本地部署大模型(以PaddleOCR-VL-1.5为例)
vscode·visualstudio·docker·语言模型·aigc·ocr
AquaPluto2 小时前
Nginx的性能优化
nginx·性能优化
●VON2 小时前
OpenClaw 技能扩展实战指南:从安装 Skills 到 Tavily 联网 + 多维表格自动化
运维·自动化·开发·openclaw·龙虾
正在走向自律2 小时前
OpenClaw 技术深度解析从智能助手到自动化引擎的范式革命
运维·自动化·智能体
Lupino13 小时前
别再只聊 AI 写代码了:技术负责人要把“变更治理”提到第一优先级
python·docker·容器
冬奇Lab1 天前
一天一个开源项目(第46篇):Caddy - 自动 HTTPS 的现代化 Web 服务器,支持 HTTP/3
网络协议·nginx·开源