【服务器】云服务器部署指南,一步一步的教你怎么部署项目(Java+Django两种项目)
云服务器部署指南
一、云服务器环境准备
1.1 服务器选择
选择云服务器就像是给项目选房子,要考虑预算、位置、周边配套等多种因素。我总结出几家主流厂商的对比:
| 服务商 | 适用场景 | 优势 | 劣势 | 价格区间(2核4G) | 官网地址 |
|---|---|---|---|---|---|
| 阿里云ECS | 国内主流业务 | 国内访问速度最快,BGP线路覆盖全面,技术支持响应及时,中文服务完善,DDoS防护免费 | 价格相对较高,国际带宽成本贵,某些高级功能需要额外付费 | 150-200元/月 | https://www.aliyun.com/product/ecs |
| 腾讯云CVM | 预算有限项目 | 性价比极高,经常有优惠活动,新用户享受大额代金券,微信小程序/公众号集成便捷 | 高并发性能略逊于阿里云,某些区域网络稳定性一般 | 120-160元/月 | https://cloud.tencent.com/product/cvm |
| AWS EC2 | 国际化业务 | 全球覆盖最广,服务生态最完善,按秒计费成本控制精确,自动化运维工具丰富 | 国内访问速度较慢需要备案,界面全英文学习成本高,支付和客服支持复杂 | $15-25/月 | https://aws.amazon.com/ec2/ |
| 华为云ECS | 政企项目 | 企业级安全性高,国产化程度高,政企项目首选合规性强,硬件配置稳定性能可靠 | 价格偏高个人用户不友好,文档和社区相对较少,某些配置灵活性不足 | 160-220元/月 | https://www.huaweicloud.com/product/ecs.html |
实际选择时,建议根据项目性质来决定:如果是面向国内用户的首选阿里云,预算有限可以考虑腾讯云的优惠活动,有海外业务需求那AWS是绕不开的选择,政府或企业项目华为云会更合适一些。价格方面,经常关注各家的活动,有时候能拿到很好的折扣。
1.2 基础环境配置
系统更新 - 必须执行的第一步
系统安全是服务器运维的基础,第一时间更新系统可以修复已知的安全漏洞,这是最基本的防护措施。内核补丁不仅能提升系统稳定性,还能优化性能。更新软件包仓库则能确保后续安装的软件都是最新版本,避免使用有漏洞的旧版本。
执行方法:
# Ubuntu/Debian系统
sudo apt update && sudo apt upgrade -y
# CentOS/RHEL系统
sudo yum update -y
# 查看系统版本
lsb_release -a # Ubuntu
cat /etc/redhat-release # CentOS
基础开发工具安装 - 项目部署的必备组件
部署过程中这些工具都是必备的。wget和curl用于下载各种软件包和脚本,git用于从代码仓库拉取项目代码,vim或nano则是服务器上的文本编辑器。nginx作为反向代理服务器,处理HTTP请求和静态文件服务是标配。htop能帮你快速查看系统资源占用情况,unzip和tar处理各种压缩文件。虽然看起来工具不少,但这些都是运维过程中经常用到的。
安装命令:
# Ubuntu/Debian
sudo apt install -y wget curl git vim nginx htop unzip tar build-essential
# CentOS/RHEL
sudo yum install -y wget curl git vim nginx htop unzip tar gcc gcc-c++ make
时区和时间同步 - 确保日志时间准确
时间同步虽然看起来是个小事,但在生产环境中特别重要。统一的时间戳能让你在排查问题时快速定位事件发生的时间,不会因为时间不一致而误判。定时任务比如备份、日志清理等都依赖准确的时间。还有SSL证书验证对时间很敏感,时间不正确可能导致证书验证失败,直接影响HTTPS访问。
配置方法:
# 设置时区为东八区
sudo timedatectl set-timezone Asia/Shanghai
# 启用NTP时间同步
sudo timedatectl set-ntp yes
# 查看时间状态
timedatectl status
防火墙基础配置 - 服务器安全第一道防线
防火墙就像是服务器的门卫,只允许必要的流量通过。默认情况下应该关闭所有端口,然后只开放SSH(22端口)、HTTP(80端口)和HTTPS(443端口)这几个必需的端口。这样能有效防止端口扫描和恶意攻击,大大降低服务器被入侵的风险。记住,安全策略应该是默认拒绝,明确允许。
配置步骤:
# 启用UFW防火墙
sudo ufw enable
# 允许SSH连接(重要:否则会被锁在服务器外)
sudo ufw allow ssh
# 允许HTTP和HTTPS
sudo ufw allow 80
sudo ufw allow 443
# 查看防火墙状态
sudo ufw status verbose
SSH安全配置 - 远程管理安全加固
SSH是服务器管理的生命线,也是黑客攻击的重点目标。暴力破解SSH密码是最常见的攻击方式之一,一定要禁用密码认证改用密钥认证。root账号权限太大,被攻破后果严重,建议禁用直接登录,日常操作使用普通用户。密钥认证不仅安全性更高,还便于自动化部署脚本的执行。
配置方法:
# 编辑SSH配置文件
sudo vim /etc/ssh/sshd_config
# 修改以下配置项:
Port 22 # 可以改为其他端口
PermitRootLogin no # 禁止root登录
PasswordAuthentication no # 禁用密码认证
PubkeyAuthentication yes # 启用密钥认证
UsePAM no # 禁用PAM认证
# 重启SSH服务
sudo systemctl restart sshd
1.3 安全配置
创建专用部署用户 - 权限分离最佳实践
千万不要图省事直接用root用户操作服务器,这是很多新手的坏习惯。创建专门的部署用户可以避免误操作造成系统级损坏,比如不小心rm掉了重要系统文件。应用和系统权限分离后,即使应用被攻破,攻击者也只能拿到有限权限,无法控制系统。这样还便于日志审计和责任追踪。
操作步骤:
# 创建部署用户
sudo useradd -m -s /bin/bash deploy
# 设置用户密码
sudo passwd deploy
# 将用户添加到sudo组
sudo usermod -aG sudo deploy
# 创建.ssh目录
sudo mkdir -p /home/deploy/.ssh
sudo chmod 700 /home/deploy/.ssh
sudo chown deploy:deploy /home/deploy/.ssh
SSH密钥认证配置 - 替代密码认证
SSH密钥认证比密码安全太多了,密码再复杂也可能被暴力破解,但密钥几乎不可能被破解。配置一次后就不用每次输入密码,登录更方便也支持自动化脚本执行。现在的CI/CD流水线、自动化部署工具都依赖SSH密钥认证,这是现代DevOps实践的基础。
配置方法:
# 在本地机器生成SSH密钥对
ssh-keygen -t rsa -b 4096 -C "your-email@example.com"
# 将公钥复制到服务器
ssh-copy-id deploy@your-server-ip
# 或者手动复制
cat ~/.ssh/id_rsa.pub | ssh deploy@your-server-ip "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
# 设置权限
chmod 600 ~/.ssh/authorized_keys
chmod 700 ~/.ssh
fail2ban入侵防护 - 自动封禁恶意IP
fail2ban就像一个自动化的保安,能实时监控SSH登录日志,发现暴力破解行为就自动封禁IP。现在的网络环境很复杂,各种扫描器和僵尸程序24小时不间断地尝试攻击服务器,人工防护根本忙不过来。配置fail2ban后,大部分低水平的攻击都会被自动处理,大大减轻服务器的安全压力。
安装配置:
# 安装fail2ban
sudo apt install fail2ban -y
# 创建本地配置文件
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
# 编辑配置
sudo vim /etc/fail2ban/jail.local
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 3
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
# 启动fail2ban服务
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
sudo systemctl status fail2ban
# 查看封禁状态
sudo fail2ban-client status sshd
系统安全加固 - 内核参数优化
Linux内核参数优化能从系统层面提升安全性和性能。开启SYN cookies等防护参数可以有效防止SYN洪水攻击,关闭IP转发功能防止IP欺骗。调整网络相关参数能提升并发连接处理能力,这对于高并发应用特别重要。还要记得关闭不需要的系统服务,每个运行的服务都是潜在的安全风险点。
配置方法:
# 编辑系统参数
sudo vim /etc/sysctl.conf
# IP安全配置
net.ipv4.ip_forward = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.icmp_echo_ignore_broadcasts = 1
# 防止SYN洪水攻击
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 2048
net.ipv4.tcp_synack_retries = 2
# 文件描述符限制
fs.file-max = 65535
# 应用配置
sudo sysctl -p
日志监控配置 - 及时发现异常
日志监控就像是服务器的健康监测系统,能帮你及时发现问题。实时监控登录日志可以发现异常登录行为,比如有人在半夜尝试登录或者短时间内大量失败尝试。定期检查系统资源使用情况能发现性能瓶颈或异常进程。很多安全事件在发生前都会有预兆,通过日志分析能提前预警,避免问题扩大化。
配置方法:
# 查看登录日志
sudo tail -f /var/log/auth.log
# 安装logwatch进行日志分析
sudo apt install logwatch -y
# 配置logwatch
sudo vim /etc/logwatch/conf/logwatch.conf
# 发送日志到邮箱
MailTo = your-email@example.com
Range = yesterday
Detail = Med
二、Java项目部署
2.1 Java环境安装
# 安装OpenJDK 11
sudo apt install openjdk-11-jdk -y
# 验证安装
java -version
javac -version
# 设置JAVA_HOME
echo 'export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64' >> ~/.bashrc
source ~/.bashrc
2.2 数据库配置
MySQL安装配置 - 关系型数据库首选
MySQL是Java项目的老搭档了,性能稳定、配置简单,文档和社区资源都很丰富。它的读写性能在大多数场景下都够用,特别是配合Java Spring框架使用时,集成度非常高。主从复制配置也相对简单,适合中小型项目的读写分离需求。虽然PostgreSQL在某些高级功能上更强大,但MySQL的简单性和稳定性让它在实际项目中更受欢迎。
安装步骤:
# 安装MySQL服务器
sudo apt install mysql-server -y
# 安全配置向导
sudo mysql_secure_installation
# 启动并设置开机自启
sudo systemctl enable mysql
sudo systemctl start mysql
# 登录MySQL
sudo mysql -u root -p
创建数据库和用户:
-- 创建应用数据库
CREATE DATABASE myapp CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 创建应用用户
CREATE USER 'appuser'@'localhost' IDENTIFIED BY 'StrongPassword123!';
-- 授权
GRANT ALL PRIVILEGES ON myapp.* TO 'appuser'@'localhost';
-- 刷新权限
FLUSH PRIVILEGES;
-- 退出
EXIT;
MySQL性能优化配置:
# 编辑MySQL配置文件
sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf
[mysqld]
# 基础配置
bind-address = 127.0.0.1
port = 3306
# 内存配置
innodb_buffer_pool_size = 1G
innodb_log_file_size = 256M
innodb_flush_log_at_trx_commit = 2
# 连接配置
max_connections = 200
max_connect_errors = 1000
# 查询缓存
query_cache_type = 1
query_cache_size = 64M
PostgreSQL安装配置 - 高级功能数据库
PostgreSQL可以说是最强大的开源关系型数据库了。它的JSON支持非常完善,对于现代应用很有用。事务处理能力很强,ACID特性完整,适合金融等对数据一致性要求极高的场景。PostgreSQL的扩展性也很强,可以自定义函数和数据类型。虽然是开源免费,但功能不输任何商业数据库,特别适合Django项目,因为Django对PostgreSQL的原生支持很好。
安装步骤:
# 安装PostgreSQL
sudo apt install postgresql postgresql-contrib -y
# 启动服务
sudo systemctl enable postgresql
sudo systemctl start postgresql
# 切换到postgres用户
sudo -u postgres psql
创建数据库和用户:
-- 创建应用用户
CREATE USER django_user WITH PASSWORD 'StrongPassword123!';
-- 创建数据库
CREATE DATABASE mydjangoapp OWNER django_user;
-- 授权
GRANT ALL PRIVILEGES ON DATABASE mydjangoapp TO django_user;
-- 退出
q
PostgreSQL配置优化:
# 编辑主配置文件
sudo vim /etc/postgresql/12/main/postgresql.conf
# 连接配置
listen_addresses = 'localhost'
port = 5432
max_connections = 100
# 内存配置
shared_buffers = 256MB
effective_cache_size = 1GB
work_mem = 4MB
maintenance_work_mem = 64MB
# WAL配置
wal_buffers = 16MB
checkpoint_completion_target = 0.9
# 编辑访问控制文件
sudo vim /etc/postgresql/12/main/pg_hba.conf
# 添加本地连接规则
local all postgres peer
local all all md5
host all all 127.0.0.1/32 md5
数据库备份策略 - 数据安全保障
MySQL备份脚本:
#!/bin/bash
# mysql_backup.sh
BACKUP_DIR="/backup/mysql"
DATE=$(date +%Y%m%d_%H%M%S)
DB_NAME="myapp"
DB_USER="appuser"
# 创建备份目录
mkdir -p $BACKUP_DIR
# 执行备份
mysqldump -u $DB_USER -p$DB_PASS $DB_NAME > $BACKUP_DIR/backup_$DATE.sql
# 压缩备份文件
gzip $BACKUP_DIR/backup_$DATE.sql
# 删除7天前的备份
find $BACKUP_DIR -name "backup_*.sql.gz" -mtime +7 -delete
PostgreSQL备份脚本:
#!/bin/bash
# pg_backup.sh
BACKUP_DIR="/backup/postgresql"
DATE=$(date +%Y%m%d_%H%M%S)
DB_NAME="mydjangoapp"
# 创建备份目录
mkdir -p $BACKUP_DIR
# 执行备份
pg_dump -U postgres $DB_NAME > $BACKUP_DIR/pg_backup_$DATE.sql
# 压缩备份文件
gzip $BACKUP_DIR/pg_backup_$DATE.sql
# 删除7天前的备份
find $BACKUP_DIR -name "pg_backup_*.sql.gz" -mtime +7 -delete
2.3 项目部署步骤
打包工具选择和安装 - 构建自动化工具
Maven - Java项目标准构建工具
Maven是Java项目的老牌构建工具了。最大的好处是依赖管理自动化,再也不用手动下载和管理jar包,也不用担心版本冲突问题。它的项目结构是标准化的,团队成员之间协作很方便。插件生态非常丰富,从编译、测试到打包部署,几乎每个环节都有对应的插件。在CI/CD流水线中集成也很简单,是大多数Java项目的首选。
安装配置:
# 下载Maven
cd /opt
sudo wget https://archive.apache.org/dist/maven/maven-3/3.8.6/binaries/apache-maven-3.8.6-bin.tar.gz
# 解压
sudo tar -xzf apache-maven-3.8.6-bin.tar.gz
sudo mv apache-maven-3.8.6 maven
# 配置环境变量
echo 'export M2_HOME=/opt/maven' >> ~/.bashrc
echo 'export PATH=$M2_HOME/bin:$PATH' >> ~/.bashrc
source ~/.bashrc
# 验证安装
mvn -version
Maven打包命令:
# 清理并打包
mvn clean package
# 跳过测试打包(生产环境不推荐)
mvn clean package -DskipTests
# 打包并安装到本地仓库
mvn clean install
# 多环境打包
mvn clean package -P prod
Gradle - 现代化构建工具
Gradle是新一代的构建工具,比Maven更灵活。它使用Groovy或Kotlin DSL,配置代码更加简洁易懂。增量构建机制让它在日常开发中构建速度更快,只编译变化的部分。除了Java,还支持Kotlin、Groovy等多种语言,特别适合Android开发。虽然学习曲线比Maven陡峭一些,但一旦上手就会发现它的强大和灵活。
安装配置:
# 下载Gradle
cd /opt
sudo wget https://services.gradle.org/distributions/gradle-7.5.1-bin.zip
# 解压
sudo unzip gradle-7.5.1-bin.zip
sudo mv gradle-7.5.1 gradle
# 配置环境变量
echo 'export GRADLE_HOME=/opt/gradle' >> ~/.bashrc
echo 'export PATH=$GRADLE_HOME/bin:$PATH' >> ~/.bashrc
source ~/.bashrc
# 验证安装
gradle -version
Gradle打包命令:
# 构建项目
./gradlew build
# 跳过测试
./gradlew build -x test
# 打包发布版本
./gradlew clean assembleRelease
# 查看依赖树
./gradlew dependencies
项目上传工具 - 文件传输解决方案
SCP - 安全复制协议
SCP是基于SSH的安全传输协议,传输过程全程加密,安全性很高。命令语法很简单,很容易集成到自动化脚本中。而且几乎所有Linux系统都自带,不需要额外安装什么。对于简单的文件上传下载,SCP是最直接的选择,特别是在脚本化部署时用起来很顺手。
使用方法:
# 上传单个文件
scp target/myapp.jar deploy@your-server:/home/deploy/
# 上传整个目录
scp -r target/ deploy@your-server:/home/deploy/
# 指定端口
scp -P 2222 target/myapp.jar deploy@your-server:/home/deploy/
Rsync - 高效同步工具
Rsync是我最喜欢的同步工具,它只传输变化的文件部分,大大节省带宽和时间。网络中断后可以断点续传,不会传输一半重来一次。最重要的是它能保持文件的权限、时间戳等属性,和本地完全一致。对于项目代码同步和备份,Rsync是最佳选择,特别是项目文件较大时,优势特别明显。
安装和使用:
# 安装rsync
sudo apt install rsync -y
# 同步文件
rsync -avz --progress target/ deploy@your-server:/home/deploy/
# 删除目标目录多余文件
rsync -avz --delete target/ deploy@your-server:/home/deploy/
# 排除某些文件
rsync -avz --exclude '*.log' --exclude 'tmp/' target/ deploy@your-server:/home/deploy/
SFTP - 安全文件传输协议
SFTP提供了交互式的文件操作界面,可以像操作本地文件一样管理远程服务器。支持目录的创建、删除、重命名等操作,比SCP功能更丰富。它使用标准的SSH端口,一般不会被防火墙拦截。当你需要手动管理服务器文件或者查看远程目录结构时,SFTP是最方便的选择。
使用方法:
# 连接SFTP
sftp deploy@your-server
# SFTP命令
sftp> put target/myapp.jar /home/deploy/
sftp> get /home/deploy/app.log
sftp> mkdir /home/deploy/logs
sftp> ls -la
sftp> exit
启动脚本配置 - 应用生命周期管理
基础启动脚本
#!/bin/bash
# start.sh
# 设置环境变量
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
export PATH=$JAVA_HOME/bin:$PATH
# 应用配置
APP_NAME="myapp"
JAR_FILE="/home/deploy/myapp.jar"
PID_FILE="/home/deploy/myapp.pid"
LOG_FILE="/home/deploy/logs/myapp.log"
# 创建日志目录
mkdir -p /home/deploy/logs
# JVM参数配置
JVM_OPTS="-Xms512m -Xmx2g -XX:+UseG1GC -XX:MaxGCPauseMillis=200"
SPRING_OPTS="--spring.profiles.active=prod --server.port=8080"
# 启动应用
start() {
if [ -f $PID_FILE ]; then
echo "Application is already running with PID $(cat $PID_FILE)"
return 1
fi
echo "Starting $APP_NAME..."
nohup java $JVM_OPTS -jar $JAR_FILE $SPRING_OPTS > $LOG_FILE 2>&1 &
echo $! > $PID_FILE
echo "Application started with PID $(cat $PID_FILE)"
}
# 停止应用
stop() {
if [ ! -f $PID_FILE ]; then
echo "Application is not running"
return 1
fi
PID=$(cat $PID_FILE)
echo "Stopping $APP_NAME with PID $PID..."
kill $PID
rm -f $PID_FILE
echo "Application stopped"
}
# 重启应用
restart() {
stop
sleep 2
start
}
# 查看状态
status() {
if [ -f $PID_FILE ]; then
PID=$(cat $PID_FILE)
if ps -p $PID > /dev/null 2>&1; then
echo "Application is running with PID $PID"
else
echo "PID file exists but process is not running"
rm -f $PID_FILE
fi
else
echo "Application is not running"
fi
}
# 主逻辑
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
status)
status
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
exit 1
;;
esac
高级启动脚本(带健康检查)
#!/bin/bash
# advanced_start.sh
APP_NAME="myapp"
JAR_FILE="/home/deploy/myapp.jar"
PORT=8080
HEALTH_CHECK_URL="http://localhost:$PORT/actuator/health"
MAX_RETRIES=30
RETRY_INTERVAL=5
# 健康检查函数
health_check() {
local retries=0
echo "Performing health check..."
while [ $retries -lt $MAX_RETRIES ]; do
if curl -f -s $HEALTH_CHECK_URL > /dev/null 2>&1; then
echo "Application is healthy ✓"
return 0
fi
echo "Health check failed, retrying in $RETRY_INTERVAL seconds... ($((retries+1))/$MAX_RETRIES)"
sleep $RETRY_INTERVAL
((retries++))
done
echo "Health check failed after $MAX_RETRIES retries"
return 1
}
# 启动应用并等待健康检查
start_with_health_check() {
echo "Starting $APP_NAME with health check..."
./start.sh start
echo "Waiting for application to be ready..."
sleep 10
if health_check; then
echo "$APP_NAME started successfully ✓"
return 0
else
echo "Failed to start $APP_NAME, rolling back..."
./start.sh stop
return 1
fi
}
# 执行带健康检查的启动
start_with_health_check
配置文件权限
# 设置执行权限
chmod +x start.sh advanced_start.sh
# 设置文件所有者
chown deploy:deploy *.sh
# 测试脚本
./start.sh status
2.4 进程管理(使用systemd)
# 创建服务文件
sudo vim /etc/systemd/system/myapp.service
[Unit]
Description=My Java Application
After=network.target
[Service]
Type=simple
User=deploy
WorkingDirectory=/home/deploy
ExecStart=/usr/bin/java -jar /home/deploy/myapp.jar
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
# 启用并启动服务
sudo systemctl enable myapp
sudo systemctl start myapp
sudo systemctl status myapp
2.5 反向代理配置(Nginx)
server {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
三、Django项目部署
3.1 Python环境配置
# 安装Python和pip
sudo apt install python3 python3-pip python3-venv -y
# 创建虚拟环境
python3 -m venv /home/deploy/myenv
source /home/deploy/myenv/bin/activate
# 安装依赖
pip install -r requirements.txt
3.2 数据库配置
# PostgreSQL安装
sudo apt install postgresql postgresql-contrib -y
# 创建数据库和用户
sudo -u postgres psql
CREATE DATABASE mydjangoapp;
CREATE USER django_user WITH PASSWORD 'password';
ALTER ROLE django_user SET client_encoding TO 'utf8';
GRANT ALL PRIVILEGES ON DATABASE mydjangoapp TO django_user;
q
3.3 Django项目配置
settings.py生产环境配置
import os
# 安全设置
DEBUG = False
ALLOWED_HOSTS = ['your-domain.com', 'your-server-ip']
# 数据库配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'mydjangoapp',
'USER': 'django_user',
'PASSWORD': 'password',
'HOST': 'localhost',
'PORT': '5432',
}
}
# 静态文件配置
STATIC_ROOT = '/var/www/django/static/'
MEDIA_ROOT = '/var/www/django/media/'
数据库迁移和静态文件收集
# 数据库迁移
python manage.py makemigrations
python manage.py migrate
# 收集静态文件
python manage.py collectstatic --noinput
# 创建超级用户
python manage.py createsuperuser
3.4 Gunicorn配置
# 安装Gunicorn
pip install gunicorn
# 创建Gunicorn配置文件
cat > gunicorn.conf.py << EOF
bind = "127.0.0.1:8000"
workers = 4
worker_class = "sync"
worker_connections = 1000
timeout = 30
keepalive = 2
max_requests = 1000
max_requests_jitter = 100
preload_app = True
EOF
测试Gunicorn运行
gunicorn --config gunicorn.conf.py myproject.wsgi:application
3.5 Systemd服务配置
# 创建Django服务文件
sudo vim /etc/systemd/system/django.service
[Unit]
Description=Django Gunicorn Service
After=network.target
[Service]
Type=notify
User=deploy
Group=deploy
WorkingDirectory=/home/deploy/myproject
Environment=PATH=/home/deploy/myenv/bin
ExecStart=/home/deploy/myenv/bin/gunicorn --config gunicorn.conf.py myproject.wsgi:application
ExecReload=/bin/kill -s HUP $MAINPID
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
# 启用并启动服务
sudo systemctl enable django
sudo systemctl start django
sudo systemctl status django
3.6 Nginx配置
server {
listen 80;
server_name your-domain.com;
location /static/ {
alias /var/www/django/static/;
expires 30d;
}
location /media/ {
alias /var/www/django/media/;
expires 30d;
}
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;
}
}
四、额外配置
4.1 SSL证书配置 - HTTPS安全访问保障
SSL证书现在已经不是可选项,而是现代网站的标配。通过HTTPS加密可以有效防止数据在传输过程中被窃取或篡改,这对于用户登录、支付等敏感操作至关重要。浏览器会为HTTPS网站显示安全锁标,这直接影响用户对网站的信任度。从SEO角度来看,搜索引擎明确表示偏好HTTPS站点,采用HTTPS能获得更好的排名。另外,现在很多第三方服务(如支付接口、地图API等)都要求使用HTTPS,这是技术发展的必然趋势。
Let’s Encrypt免费证书配置:
# 安装Certbot
sudo apt install certbot python3-certbot-nginx -y
# 自动配置Nginx
sudo certbot --nginx -d your-domain.com -d www.your-domain.com
# 手动配置(选择此选项)
sudo certbot certonly --nginx -d your-domain.com
# 强制HTTPS重定向
sudo vim /etc/nginx/sites-available/your-domain
server {
listen 80;
server_name your-domain.com www.your-domain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name your-domain.com www.your-domain.com;
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
# SSL配置优化
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
location / {
proxy_pass http://localhost:8080;
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;
}
}
自动续期配置:
# 测试续期
sudo certbot renew --dry-run
# 设置自动续期(系统自带)
sudo systemctl status certbot.timer
# 手动添加cron任务
sudo crontab -e
# 添加:0 12 * * * /usr/bin/certbot renew --quiet
4.2 监控和日志系统 - 运维可视化管理
系统服务监控
# 查看所有服务状态
sudo systemctl list-units --type=service --state=running
# 查看特定服务日志
sudo journalctl -u myapp -f
sudo journalctl -u nginx -f
sudo journalctl -u mysql -f
# 查看系统资源使用
htop
df -h
free -h
netstat -tulpn
应用日志配置
# 创建日志目录结构
mkdir -p /home/deploy/logs/{app,nginx,system}
# 配置日志轮转
sudo vim /etc/logrotate.d/myapp
/home/deploy/logs/app/*.log {
daily
missingok
rotate 30
compress
delaycompress
notifempty
create 644 deploy deploy
postrotate
systemctl reload myapp
endscript
}
Prometheus + Grafana监控搭建
# 安装Prometheus
wget https://github.com/prometheus/prometheus/releases/download/v2.36.2/prometheus-2.36.2.linux-amd64.tar.gz
tar -xzf prometheus-2.36.2.linux-amd64.tar.gz
cd prometheus-2.36.2.linux-amd64
# 配置prometheus.yml
cat > prometheus.yml << EOF
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'myapp'
static_configs:
- targets: ['localhost:8080']
- job_name: 'node'
static_configs:
- targets: ['localhost:9100']
EOF
# 启动Prometheus
./prometheus --config.file=prometheus.yml --web.listen-address=:9090
4.3 自动化部署流程 - CI/CD最佳实践
Git自动化部署脚本
#!/bin/bash
# auto_deploy.sh
set -e # 遇到错误立即退出
# 配置变量
PROJECT_DIR="/home/deploy/myproject"
BACKUP_DIR="/backup/deploy"
LOG_FILE="/var/log/deploy.log"
DATE=$(date +%Y%m%d_%H%M%S)
# 日志函数
log() {
echo "[$DATE] $1" | tee -a $LOG_FILE
}
# 错误处理
error_exit() {
log "ERROR: $1"
exit 1
}
# 创建备份
create_backup() {
log "Creating backup..."
mkdir -p $BACKUP_DIR
cp -r $PROJECT_DIR $BACKUP_DIR/project_$DATE
log "Backup created at $BACKUP_DIR/project_$DATE"
}
# 更新代码
update_code() {
log "Updating code from git repository..."
cd $PROJECT_DIR
git pull origin main || error_exit "Git pull failed"
log "Code updated successfully"
}
# Java项目部署
deploy_java() {
log "Starting Java application deployment..."
# 检查Maven
if ! command -v mvn &> /dev/null; then
error_exit "Maven not found"
fi
# 打包项目
mvn clean package -DskipTests || error_exit "Maven build failed"
# 备份当前jar包
if [ -f "$PROJECT_DIR/target/myapp.jar" ]; then
cp $PROJECT_DIR/target/myapp.jar $PROJECT_DIR/target/myapp.jar.backup
fi
# 重启服务
sudo systemctl restart myapp || error_exit "Service restart failed"
# 健康检查
sleep 10
if curl -f http://localhost:8080/actuator/health > /dev/null 2>&1; then
log "Java application deployed successfully ✓"
else
log "Java application health check failed, rolling back..."
cp $PROJECT_DIR/target/myapp.jar.backup $PROJECT_DIR/target/myapp.jar
sudo systemctl restart myapp
error_exit "Deployment failed, rollback completed"
fi
}
# Django项目部署
deploy_django() {
log "Starting Django application deployment..."
# 激活虚拟环境
source /home/deploy/myenv/bin/activate || error_exit "Virtual environment activation failed"
# 安装依赖
pip install -r requirements.txt || error_exit "Dependencies installation failed"
# 数据库迁移
python manage.py migrate || error_exit "Database migration failed"
# 收集静态文件
python manage.py collectstatic --noinput || error_exit "Static files collection failed"
# 重启服务
sudo systemctl restart django || error_exit "Service restart failed"
# 健康检查
sleep 5
if curl -f http://localhost:8000/ > /dev/null 2>&1; then
log "Django application deployed successfully ✓"
else
error_exit "Django application health check failed"
fi
}
# 清理旧备份
cleanup_backups() {
log "Cleaning up old backups..."
find $BACKUP_DIR -name "project_*" -mtime +7 -exec rm -rf {} ;
log "Old backups cleaned up"
}
# 主流程
main() {
log "Starting automated deployment process..."
create_backup
update_code
# 根据项目类型选择部署方式
if [ -f "$PROJECT_DIR/pom.xml" ]; then
deploy_java
elif [ -f "$PROJECT_DIR/manage.py" ]; then
deploy_django
else
error_exit "Unknown project type"
fi
cleanup_backups
log "Deployment completed successfully ✓"
}
# 执行主流程
main
Webhook自动部署配置
# 安装webhook接收服务
pip install webhook-receiver
# 创建配置文件
cat > webhook_config.json << EOF
{
"port": 9000,
"secret": "your-webhook-secret",
"commands": {
"main": "/home/deploy/auto_deploy.sh"
}
}
EOF
# 启动webhook服务
webhook-receiver --config webhook_config.json --daemon
4.4 备份和恢复策略 - 数据安全保障
全量备份脚本
#!/bin/bash
# full_backup.sh
BACKUP_ROOT="/backup"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="$BACKUP_ROOT/full_backup_$DATE"
# 创建备份目录
mkdir -p $BACKUP_DIR
# 数据库备份
echo "Backing up databases..."
mysqldump -u root -p --all-databases > $BACKUP_DIR/mysql_all_$DATE.sql
pg_dumpall -U postgres > $BACKUP_DIR/postgresql_all_$DATE.sql
# 应用文件备份
echo "Backing up application files..."
tar -czf $BACKUP_DIR/app_files_$DATE.tar.gz /home/deploy/
# 配置文件备份
echo "Backing up configuration files..."
tar -czf $BACKUP_DIR/config_files_$DATE.tar.gz /etc/nginx/ /etc/systemd/system/ /home/deploy/.ssh/
# 生成备份清单
echo "Backup Summary:" > $BACKUP_DIR/backup_info.txt
echo "Date: $DATE" >> $BACKUP_DIR/backup_info.txt
echo "MySQL Database: mysql_all_$DATE.sql" >> $BACKUP_DIR/backup_info.txt
echo "PostgreSQL Database: postgresql_all_$DATE.sql" >> $BACKUP_DIR/backup_info.txt
echo "Application Files: app_files_$DATE.tar.gz" >> $BACKUP_DIR/backup_info.txt
echo "Configuration Files: config_files_$DATE.tar.gz" >> $BACKUP_DIR/backup_info.txt
# 压缩整个备份目录
cd $BACKUP_ROOT
tar -czf full_backup_$DATE.tar.gz full_backup_$DATE/
rm -rf full_backup_$DATE/
echo "Full backup completed: full_backup_$DATE.tar.gz"
五、性能优化建议
5.1 JVM参数调优 - Java应用性能提升
内存配置优化
# 生产环境JVM参数示例
JAVA_OPTS="-Xms2g -Xmx4g
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
-XX:+UnlockExperimentalVMOptions
-XX:+UseStringDeduplication
-XX:+OptimizeStringConcat
-XX:+UseCompressedOops
-XX:+UseCompressedClassPointers
-Djava.security.egd=file:/dev/./urandom
-Dfile.encoding=UTF-8
-Duser.timezone=Asia/Shanghai"
Spring Boot应用优化
# application-prod.yml
server:
tomcat:
max-threads: 200
min-spare-threads: 10
max-connections: 8192
accept-count: 100
compression:
enabled: true
mime-types: text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json
min-response-size: 1024
spring:
datasource:
hikari:
maximum-pool-size: 20
minimum-idle: 5
idle-timeout: 300000
max-lifetime: 1200000
connection-timeout: 20000
cache:
type: redis
redis:
time-to-live: 600000
logging:
level:
root: WARN
com.yourpackage: INFO
file:
max-size: 100MB
max-history: 30
5.2 Django应用优化 - Python Web性能提升
数据库连接池配置
# settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'mydjangoapp',
'USER': 'django_user',
'PASSWORD': 'password',
'HOST': 'localhost',
'PORT': '5432',
'OPTIONS': {
'MAX_CONNS': 20,
'MIN_CONNS': 5,
}
}
}
# 连接池配置
CONN_MAX_AGE = 600
缓存配置优化
# Redis缓存配置
CACHES = {
'default': {
'BACKEND': 'django_redis.cache.RedisCache',
'LOCATION': 'redis://127.0.0.1:6379/1',
'OPTIONS': {
'CLIENT_CLASS': 'django_redis.client.DefaultClient',
'COMPRESSOR': 'django_redis.compressors.zlib.ZlibCompressor',
'IGNORE_EXCEPTIONS': True,
},
'KEY_PREFIX': 'myapp',
'TIMEOUT': 300,
}
}
# Session配置
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
SESSION_CACHE_ALIAS = 'default'
5.3 数据库性能优化
MySQL优化配置
[mysqld]
# InnoDB优化
innodb_buffer_pool_size = 2G
innodb_log_file_size = 512M
innodb_flush_log_at_trx_commit = 2
innodb_flush_method = O_DIRECT
innodb_io_capacity = 2000
innodb_io_capacity_max = 4000
# 查询缓存
query_cache_type = 1
query_cache_size = 256M
query_cache_limit = 2M
# 连接优化
max_connections = 500
max_connect_errors = 1000
connect_timeout = 10
wait_timeout = 600
PostgreSQL优化配置
# postgresql.conf
shared_buffers = 1GB
effective_cache_size = 3GB
work_mem = 16MB
maintenance_work_mem = 128MB
# 检查点优化
checkpoint_completion_target = 0.9
wal_buffers = 16MB
default_statistics_target = 100
# 连接优化
max_connections = 200
superuser_reserved_connections = 3
5.4 Nginx性能优化
worker进程配置
# nginx.conf
worker_processes auto;
worker_rlimit_nofile 65535;
events {
worker_connections 10240;
use epoll;
multi_accept on;
}
http {
# 基础优化
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
keepalive_requests 100;
# 压缩优化
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_comp_level 6;
gzip_types
text/plain
text/css
text/xml
text/javascript
application/javascript
application/xml+rss
application/json;
# 缓存配置
open_file_cache max=200000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
}
5.5 系统级性能优化
内核参数调优
# 添加到 /etc/sysctl.conf
# 网络优化
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.ipv4.tcp_congestion_control = bbr
# 文件描述符限制
fs.file-max = 2097152
# 虚拟内存优化
vm.swappiness = 10
vm.dirty_ratio = 15
vm.dirty_background_ratio = 5
磁盘I/O优化
# 设置I/O调度器
echo 'mq-deadline' > /sys/block/sda/queue/scheduler
# 磁盘参数优化
echo '0' > /proc/sys/vm/swappiness
echo '1' > /proc/sys/vm/drop_caches
5.6 CDN和负载均衡配置
多实例负载均衡
upstream app_servers {
least_conn;
server 127.0.0.1:8080 weight=1 max_fails=3 fail_timeout=30s;
server 127.0.0.1:8081 weight=1 max_fails=3 fail_timeout=30s;
server 127.0.0.1:8082 weight=1 max_fails=3 fail_timeout=30s;
}
server {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://app_servers;
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_connect_timeout 30s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
}
六、总结
经过无数次云服务器部署项目的实战经验,我深刻体会到,一个成功的部署不仅仅是把代码跑起来那么简单。真正的生产环境部署需要考虑安全性、稳定性、可维护性和性能的完美平衡。
从服务器选型开始,就要根据业务规模和用户群体做出明智选择 - 国内项目优先考虑阿里云的BGP网络优势,预算有限的项目可以借助腾讯云的高性价比,而国际化业务则离不开AWS的全球覆盖。环境配置看似繁琐,但每一步都有其存在的意义:系统更新是对安全的基本负责,时区同步确保日志的准确性,防火墙配置是安全的第一道防线。
在数据库选择上,我更倾向于PostgreSQL的强大功能和出色的并发处理能力,但MySQL的简单易用和成熟的生态系统也是不错的选择。无论是Java还是Django,一个好的启动脚本都能让运维工作事半功倍,配合systemd的服务管理和健康检查机制,才能真正做到无人值守运行。
SSL证书不再是可选项,而是现代网站的标配,Let’s Encrypt让HTTPS部署变得简单。监控和日志系统就像是医生听诊器,能让你在问题发生前就发现异常。自动备份策略则是最后的保险,确保即使出现最坏情况也能快速恢复。
性能优化是一个持续的过程,从JVM参数调优到数据库连接池配置,从Nginx worker进程优化到系统内核参数调整,每一个细节都可能影响最终的用户体验。记住,没有一刀切的优化方案,只有根据实际业务场景不断测试和调整,才能找到最佳的配置组合。
最终,一个稳定的生产环境就像一台精密的机器,需要每个部件都精心配置和维护。希望这些实战经验能帮助你在云服务器部署的道路上少走弯路,构建出真正企业级的应用服务。










