File size: 8,387 Bytes
e657e99 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 | #!/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 "自动部署脚本执行完成!" |