本文目录导读:

我来帮你编写一个自动部署服务端脚本,这里提供几种常见场景的脚本示例:
基础Shell部署脚本
示例1:Java应用部署
#!/bin/bash
# 自动部署脚本 - Java应用
# 作者:AI助手
# 日期:2024
# 配置变量
APP_NAME="myapp"
APP_VERSION="1.0.0"
JAR_NAME="${APP_NAME}-${APP_VERSION}.jar"
DEPLOY_DIR="/opt/${APP_NAME}"
BACKUP_DIR="${DEPLOY_DIR}/backup"
LOG_DIR="${DEPLOY_DIR}/logs"
REMOTE_HOST="your-server.com"
REMOTE_USER="deploy"
REMOTE_PATH="/opt/${APP_NAME}"
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
# 日志函数
log_info() {
echo -e "${GREEN}[INFO]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1"
}
log_warn() {
echo -e "${YELLOW}[WARNING]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1"
}
# 错误处理
set -e
trap 'log_error "脚本执行失败,在第 $LINENO 行"' ERR
# 1. 检查环境
check_environment() {
log_info "检查部署环境..."
# 检查Java环境
if ! command -v java &> /dev/null; then
log_error "Java未安装"
exit 1
fi
# 检查目录
for dir in "${DEPLOY_DIR}" "${BACKUP_DIR}" "${LOG_DIR}"; do
if [ ! -d "$dir" ]; then
mkdir -p "$dir"
log_info "创建目录: $dir"
fi
done
log_info "环境检查完成"
}
# 2. 备份当前版本
backup_current() {
log_info "备份当前版本..."
if [ -f "${DEPLOY_DIR}/${JAR_NAME}" ]; then
local timestamp=$(date '+%Y%m%d_%H%M%S')
cp "${DEPLOY_DIR}/${JAR_NAME}" "${BACKUP_DIR}/${JAR_NAME}.${timestamp}"
log_info "已备份到: ${BACKUP_DIR}/${JAR_NAME}.${timestamp}"
else
log_warn "未找到当前版本,跳过备份"
fi
}
# 3. 停止应用
stop_application() {
log_info "停止应用..."
local pid=$(pgrep -f "${JAR_NAME}" || true)
if [ -n "$pid" ]; then
kill -15 "$pid"
sleep 5
# 检查是否成功停止
if pgrep -f "${JAR_NAME}" > /dev/null; then
kill -9 "$pid"
log_warn "强制停止应用"
fi
log_info "应用已停止"
else
log_warn "应用未运行"
fi
}
# 4. 部署新版本
deploy_new_version() {
log_info "部署新版本..."
# 从远程服务器或构建产物复制
if [ -f "./build/libs/${JAR_NAME}" ]; then
cp "./build/libs/${JAR_NAME}" "${DEPLOY_DIR}/"
log_info "从本地构建目录复制"
elif [ -f "/tmp/${JAR_NAME}" ]; then
cp "/tmp/${JAR_NAME}" "${DEPLOY_DIR}/"
log_info "从临时目录复制"
else
log_error "未找到新版本文件"
exit 1
fi
# 设置权限
chmod 755 "${DEPLOY_DIR}/${JAR_NAME}"
}
# 5. 配置应用
configure_application() {
log_info "配置应用..."
# 读取配置文件
if [ -f "${DEPLOY_DIR}/application.yml" ]; then
log_info "使用现有配置"
else
log_warn "未找到配置文件,使用默认配置"
fi
# 设置环境变量
export JAVA_OPTS="-Xms512m -Xmx1024m -XX:+UseG1GC"
export APP_ENV="${APP_ENV:-production}"
}
# 6. 启动应用
start_application() {
log_info "启动应用..."
cd "${DEPLOY_DIR}"
nohup java ${JAVA_OPTS} \
-jar "${DEPLOY_DIR}/${JAR_NAME}" \
--spring.profiles.active="${APP_ENV}" \
>> "${LOG_DIR}/${APP_NAME}.log" 2>&1 &
sleep 10
# 检查启动状态
if pgrep -f "${JAR_NAME}" > /dev/null; then
log_info "应用启动成功"
return 0
else
log_error "应用启动失败"
return 1
fi
}
# 7. 健康检查
health_check() {
log_info "执行健康检查..."
local retries=5
local wait_time=5
for i in $(seq 1 $retries); do
if curl -s "http://localhost:8080/actuator/health" | grep -q "UP"; then
log_info "健康检查通过"
return 0
fi
log_warn "等待服务就绪... (${i}/${retries})"
sleep $wait_time
done
log_error "健康检查失败"
return 1
}
# 8. 清理旧文件
cleanup() {
log_info "清理旧文件..."
# 保留最近5个备份
cd "${BACKUP_DIR}"
ls -t *.jar.* | tail -n +6 | xargs -r rm -f
# 清理超过30天的日志
find "${LOG_DIR}" -name "*.log" -mtime +30 -delete
log_info "清理完成"
}
# 主部署流程
main() {
log_info "=== 开始自动部署 ==="
# 执行部署步骤
check_environment
backup_current
stop_application
deploy_new_version
configure_application
start_application
health_check
cleanup
log_info "=== 部署完成 ==="
}
# 执行主函数
main
示例2:Node.js应用部署
#!/bin/bash
# Node.js应用自动部署脚本
NODE_ENV="production"
APP_DIR="/var/www/app"
GIT_REPO="https://github.com/yourusername/yourapp.git"
BRANCH="main"
# 部署函数
deploy() {
echo "开始部署 Node.js 应用..."
# 1. 拉取最新代码
cd "$APP_DIR" || exit
git fetch --all
git checkout "$BRANCH"
git pull origin "$BRANCH"
# 2. 安装依赖
npm ci --only=production
# 3. 构建(如果需要)
if [ -f "package.json" ]; then
if grep -q '"build"' "package.json"; then
npm run build
fi
fi
# 4. 数据库迁移
if [ -f "node_modules/.bin/prisma" ]; then
npx prisma migrate deploy
fi
# 5. 重启应用
pm2 restart ecosystem.config.js --env production
echo "部署完成!"
}
# 执行部署
deploy
Docker部署脚本
#!/bin/bash
# Docker自动化部署脚本
IMAGE_NAME="myapp"
CONTAINER_NAME="myapp-container"
REGISTRY="your-registry.com"
# 部署函数
deploy_docker() {
echo "Docker自动部署..."
# 1. 拉取最新镜像
docker pull ${REGISTRY}/${IMAGE_NAME}:latest
# 2. 停止并删除旧容器
docker stop ${CONTAINER_NAME} || true
docker rm ${CONTAINER_NAME} || true
# 3. 启动新容器
docker run -d \
--name ${CONTAINER_NAME} \
-p 8080:8080 \
-e NODE_ENV=production \
--restart unless-stopped \
${REGISTRY}/${IMAGE_NAME}:latest
# 4. 清理旧镜像
docker image prune -f
echo "Docker部署完成"
}
deploy_docker
CI/CD管道脚本(GitHub Actions)
# .github/workflows/deploy.yml
name: Auto Deploy
on:
push:
branches: [ main ]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup SSH
run: |
mkdir -p ~/.ssh
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
- name: Deploy to Server
run: |
ssh -o StrictHostKeyChecking=no user@server '
cd /opt/app &&
git pull origin main &&
./deploy.sh
'
自动化部署平台(Ansible)
# deploy.yml
---
- name: Auto Deploy Application
hosts: webservers
become: yes
vars:
app_name: myapp
deploy_path: /opt/{{ app_name }}
git_repo: https://github.com/yourusername/yourapp.git
tasks:
- name: Pull latest code
git:
repo: "{{ git_repo }}"
dest: "{{ deploy_path }}"
version: main
force: yes
- name: Install dependencies
npm:
path: "{{ deploy_path }}"
state: present
- name: Build application
command: npm run build
args:
chdir: "{{ deploy_path }}"
- name: Restart service
systemd:
name: "{{ app_name }}"
state: restarted
使用方法
- 保存脚本:将脚本保存为
deploy.sh - 添加执行权限:
chmod +x deploy.sh - 配置参数:修改变量为你的实际配置
- 执行部署:
./deploy.sh
最佳实践建议
- 版本控制:使用Git标记版本
- 回滚机制:保留至少3个历史版本
- 日志记录:记录所有操作日志
- 通知机制:部署成功/失败发送通知
- 灰度发布:先部署到少量服务器测试
需要我针对特定场景或技术栈提供更详细的脚本吗?