#!/bin/bash # Ramex项目自动部署脚本 # 适用于Ubuntu 20.04+ set -e # 遇到错误立即退出 echo "==========================================" echo " Ramex项目 Linux服务器自动部署脚本" echo "==========================================" # 颜色定义 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color # 函数:打印彩色消息 print_status() { echo -e "${GREEN}[INFO]${NC} $1" } print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } print_error() { echo -e "${RED}[ERROR]${NC} $1" } # 检查是否为root用户 if [ "$EUID" -eq 0 ]; then print_error "请不要以root用户运行此脚本" exit 1 fi # 获取基本信息 PROJECT_DIR=$(pwd) PROJECT_NAME="ramex" USER_NAME=$(whoami) print_status "开始部署Ramex项目..." print_status "项目目录: $PROJECT_DIR" print_status "用户: $USER_NAME" # 1. 更新系统 print_status "更新系统包..." sudo apt update && sudo apt upgrade -y # 2. 安装系统依赖 print_status "安装系统依赖..." sudo apt install -y \ python3 \ python3-pip \ python3-venv \ python3-dev \ build-essential \ libssl-dev \ libffi-dev \ libxml2-dev \ libxslt1-dev \ libjpeg-dev \ libpng-dev \ zlib1g-dev \ git \ nginx \ dirmngr \ gnupg \ apt-transport-https \ ca-certificates \ software-properties-common # 3. 安装R语言 print_status "安装R语言环境..." if ! command -v R &> /dev/null; then sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E298A3A825C0D65DFD57CBB651716619E084DAB9 || true sudo add-apt-repository 'deb https://cloud.r-project.org/bin/linux/ubuntu focal-cran40/' -y || true sudo apt update sudo apt install -y r-base r-base-dev else print_status "R已经安装" fi # 4. 安装R包 print_status "安装必要的R包..." Rscript -e " if (!require('devtools', quietly = TRUE)) install.packages('devtools', repos='https://cloud.r-project.org/') if (!require('Rcpp', quietly = TRUE)) install.packages('Rcpp', repos='https://cloud.r-project.org/') if (!require('RcppArmadillo', quietly = TRUE)) install.packages('RcppArmadillo', repos='https://cloud.r-project.org/') if (!require('ggplot2', quietly = TRUE)) install.packages('ggplot2', repos='https://cloud.r-project.org/') if (!require('dplyr', quietly = TRUE)) install.packages('dplyr', repos='https://cloud.r-project.org/') if (!require('tidyr', quietly = TRUE)) install.packages('tidyr', repos='https://cloud.r-project.org/') " # 5. 创建Python虚拟环境 print_status "创建Python虚拟环境..." if [ ! -d "venv" ]; then python3 -m venv venv fi # 激活虚拟环境 source venv/bin/activate # 6. 升级pip并安装Python依赖 print_status "安装Python依赖..." pip install --upgrade pip pip install -r requirements.txt # 7. 配置Django print_status "配置Django应用..." # 执行数据库迁移 python manage.py makemigrations python manage.py migrate # 收集静态文件 python manage.py collectstatic --noinput # 8. 创建生产环境配置 print_status "创建生产环境配置..." # 获取服务器IP SERVER_IP=$(hostname -I | awk '{print $1}') # 创建生产环境settings文件 if [ ! -f "ramex/settings_prod.py" ]; then cp ramex/settings.py ramex/settings_prod.py # 修改生产环境设置 cat >> ramex/settings_prod.py << EOF # 生产环境设置 DEBUG = False ALLOWED_HOSTS = ['$SERVER_IP', 'localhost', '127.0.0.1'] # 静态文件设置 STATIC_ROOT = '$PROJECT_DIR/staticfiles' MEDIA_ROOT = '$PROJECT_DIR/media' # 日志配置 LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { 'file': { 'level': 'INFO', 'class': 'logging.FileHandler', 'filename': '$PROJECT_DIR/logs/django.log', }, 'console': { 'level': 'INFO', 'class': 'logging.StreamHandler', }, }, 'loggers': { 'django': { 'handlers': ['file', 'console'], 'level': 'INFO', 'propagate': True, }, }, } EOF fi # 9. 创建日志目录 mkdir -p logs # 10. 创建Gunicorn配置 print_status "创建Gunicorn配置..." cat > gunicorn.conf.py << EOF bind = "127.0.0.1:8000" workers = 4 worker_class = "sync" worker_connections = 1000 max_requests = 1000 max_requests_jitter = 100 timeout = 300 keepalive = 2 preload_app = True EOF # 11. 创建systemd服务 print_status "创建systemd服务..." sudo tee /etc/systemd/system/ramex.service > /dev/null << EOF [Unit] Description=Ramex Django Application After=network.target [Service] Type=exec User=$USER_NAME Group=$USER_NAME WorkingDirectory=$PROJECT_DIR Environment="DJANGO_SETTINGS_MODULE=ramex.settings_prod" ExecStart=$PROJECT_DIR/venv/bin/gunicorn -c gunicorn.conf.py ramex.wsgi:application ExecReload=/bin/kill -s HUP \$MAINPID Restart=always RestartSec=5 [Install] WantedBy=multi-user.target EOF # 12. 配置Nginx print_status "配置Nginx..." sudo tee /etc/nginx/sites-available/ramex > /dev/null << EOF server { listen 80; server_name $SERVER_IP localhost; client_max_body_size 100M; location /static/ { alias $PROJECT_DIR/staticfiles/; expires 1y; add_header Cache-Control "public, immutable"; } location /media/ { alias $PROJECT_DIR/media/; expires 1y; add_header Cache-Control "public"; } 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; proxy_set_header X-Forwarded-Proto \$scheme; proxy_read_timeout 300; proxy_connect_timeout 300; proxy_send_timeout 300; } } EOF # 启用Nginx站点 sudo ln -sf /etc/nginx/sites-available/ramex /etc/nginx/sites-enabled/ sudo rm -f /etc/nginx/sites-enabled/default # 测试Nginx配置 sudo nginx -t # 13. 启动服务 print_status "启动服务..." # 重新加载systemd配置 sudo systemctl daemon-reload # 启用并启动ramex服务 sudo systemctl enable ramex sudo systemctl start ramex # 启用并启动nginx服务 sudo systemctl enable nginx sudo systemctl restart nginx # 14. 创建备份脚本 print_status "创建备份脚本..." mkdir -p backups cat > backup.sh << EOF #!/bin/bash BACKUP_DIR="$PROJECT_DIR/backups" DATE=\$(date +%Y%m%d_%H%M%S) mkdir -p \$BACKUP_DIR # 备份SQLite数据库 if [ -f "$PROJECT_DIR/db.sqlite3" ]; then cp $PROJECT_DIR/db.sqlite3 \$BACKUP_DIR/db_\$DATE.sqlite3 fi # 备份媒体文件 if [ -d "$PROJECT_DIR/media" ]; then tar -czf \$BACKUP_DIR/media_\$DATE.tar.gz $PROJECT_DIR/media/ fi # 清理30天前的备份 find \$BACKUP_DIR -name "*.sqlite3" -mtime +30 -delete find \$BACKUP_DIR -name "*.tar.gz" -mtime +30 -delete echo "备份完成: \$DATE" EOF chmod +x backup.sh # 15. 检查服务状态 print_status "检查服务状态..." sleep 5 if systemctl is-active --quiet ramex; then print_status "Ramex服务运行正常" else print_error "Ramex服务启动失败" sudo systemctl status ramex fi if systemctl is-active --quiet nginx; then print_status "Nginx服务运行正常" else print_error "Nginx服务启动失败" sudo systemctl status nginx fi # 16. 输出完成信息 echo "==========================================" print_status "部署完成!" echo "==========================================" echo "" echo "访问信息:" echo " 网站地址: http://$SERVER_IP" echo " 管理后台: http://$SERVER_IP/admin/" echo "" echo "常用命令:" echo " 查看服务状态: sudo systemctl status ramex" echo " 重启服务: sudo systemctl restart ramex" echo " 查看日志: sudo journalctl -u ramex -f" echo " 运行备份: ./backup.sh" echo "" print_warning "请记得:" print_warning "1. 创建Django超级用户: python manage.py createsuperuser" print_warning "2. 根据需要修改 ramex/settings_prod.py 中的配置" print_warning "3. 配置防火墙开放80端口" print_warning "4. 考虑配置HTTPS证书" echo "" # 提示创建超级用户 read -p "是否现在创建Django超级用户?(y/n): " -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]]; then source venv/bin/activate python manage.py createsuperuser fi print_status "自动部署脚本执行完成!"