Linux使用Docker部署项目后期更新
在CentOS中使用docker部署了项目,对项目想改后,可以使用以下是几种更新部署方法:
1. 手动更新方法
方法一:重新构建镜像
# 进入项目目录
cd /path/to/your-project# 停止当前容器
docker stop node-app# 删除旧容器
docker rm node-app# 重新构建镜像(使用新代码)
docker build -t node-express-app .# 启动新容器
docker run -d \--name node-app \-p 3000:3000 \-v $(pwd)/database:/usr/src/app/database \node-express-app
方法二:使用Docker Compose更新
# 进入项目目录
cd /path/to/your-project# 拉取最新代码(如果使用Git)
git pull# 重新构建并启动
docker-compose down
docker-compose up -d --build
2. 自动化更新脚本
创建部署脚本 deploy.sh
#!/bin/bash# 部署脚本
set -eecho "开始部署 Node.js 应用..."# 进入项目目录
cd /path/to/your-project# 拉取最新代码(如果使用Git)
echo "拉取最新代码..."
git pull origin main# 备份数据库(重要!)
echo "备份数据库..."
cp -r database/database.backup.$(date +%Y%m%d_%H%M%S)# 停止并删除旧容器
echo "停止旧容器..."
docker-compose down || true# 重新构建镜像
echo "构建新镜像..."
docker-compose build# 启动服务
echo "启动新容器..."
docker-compose up -d# 等待应用启动
sleep 10# 检查应用状态
echo "检查应用状态..."
curl -f http://localhost:3000/health || echo "应用可能还在启动中"echo "部署完成!"
给脚本执行权限:
chmod +x deploy.sh
3. 使用Git Webhooks自动部署
创建自动部署脚本 webhook-deploy.sh
#!/bin/bash# Webhook 部署脚本
WEBHOOK_SECRET="your-secret-token"
PROJECT_DIR="/path/to/your-project"
DOCKER_COMPOSE_FILE="$PROJECT_DIR/docker-compose.yml"# 验证webhook签名(可选)
verify_signature() {local signature=$1local payload=$2# 实现签名验证逻辑
}# 处理部署
deploy() {cd $PROJECT_DIR# 拉取最新代码git pull origin main# 重新部署docker-compose -f $DOCKER_COMPOSE_FILE downdocker-compose -f $DOCKER_COMPOSE_FILE up -d --buildecho "部署完成: $(date)"
}# 主逻辑
read payload
signature=$(echo "$payload" | grep -o '"signature":"[^"]*' | cut -d'"' -f4)# 验证签名(如果设置了secret)
# verify_signature "$signature" "$payload"deploy
设置GitHub Webhook
- 在GitHub仓库设置中添加Webhook
- URL:
http://your-server:8080/webhook
- Content type:
application/json
- Secret: 你的密钥
4. 使用Watchtower自动更新(推荐用于开发环境)
安装和运行Watchtower
# 拉取Watchtower镜像
docker pull containrrr/watchtower# 运行Watchtower监控特定容器
docker run -d \--name watchtower \-v /var/run/docker.sock:/var/run/docker.sock \containrrr/watchtower \--interval 30 \node-app
在Docker Compose中添加Watchtower
version: '3.8'services:app:build: .ports:- "3000:3000"volumes:- ./database:/usr/src/app/databaseenvironment:- NODE_ENV=productionrestart: unless-stoppedwatchtower:image: containrrr/watchtowervolumes:- /var/run/docker.sock:/var/run/docker.sockcommand: --interval 30restart: unless-stopped
5. 蓝绿部署策略(零停机更新)
创建蓝绿部署脚本 blue-green-deploy.sh
#!/bin/bash# 蓝绿部署脚本
BLUE_PORT=3000
GREEN_PORT=3001
CURRENT_COLOR="blue"# 检测当前运行的颜色
detect_current_color() {if docker ps --format "table {{.Names}}" | grep -q "node-app-blue"; thenCURRENT_COLOR="blue"NEW_COLOR="green"NEW_PORT=$GREEN_PORTelseCURRENT_COLOR="green"NEW_COLOR="blue"NEW_PORT=$BLUE_PORTfi
}# 部署新版本
deploy_new_version() {echo "部署 $NEW_COLOR 版本..."docker build -t node-express-app:$NEW_COLOR .docker run -d \--name node-app-$NEW_COLOR \-p $NEW_PORT:3000 \-v $(pwd)/database:/usr/src/app/database \node-express-app:$NEW_COLOR# 等待新应用启动echo "等待新应用启动..."sleep 10# 健康检查if curl -f http://localhost:$NEW_PORT/health > /dev/null 2>&1; thenecho "$NEW_COLOR 版本健康检查通过"return 0elseecho "$NEW_COLOR 版本健康检查失败"return 1fi
}# 切换流量
switch_traffic() {echo "切换到 $NEW_COLOR 版本..."# 使用Nginx或负载均衡器切换流量# 这里简单演示停止旧版本docker stop node-app-$CURRENT_COLORdocker rm node-app-$CURRENT_COLOR# 重命名新容器docker rename node-app-$NEW_COLOR node-app-$CURRENT_COLOR
}# 主部署流程
detect_current_color
echo "当前运行: $CURRENT_COLOR, 新部署: $NEW_COLOR"if deploy_new_version; thenswitch_trafficecho "部署成功完成!"
elseecho "部署失败,回滚到 $CURRENT_COLOR 版本"docker stop node-app-$NEW_COLORdocker rm node-app-$NEW_COLOR
fi
6. 数据库迁移处理
创建数据库迁移脚本
// migrations/migrate.js
const sqlite3 = require('sqlite3').verbose();
const path = require('path');function runMigrations() {const dbPath = process.env.NODE_ENV === 'production' ? '/usr/src/app/database/mydb.sqlite' : path.join(__dirname, '../database/mydb.sqlite');const db = new sqlite3.Database(dbPath);// 执行迁移db.serialize(() => {// 示例:添加新表db.run(`CREATE TABLE IF NOT EXISTS new_features (id INTEGER PRIMARY KEY AUTOINCREMENT,feature_name TEXT,created_at DATETIME DEFAULT CURRENT_TIMESTAMP)`);// 示例:修改现有表db.run(`ALTER TABLE users ADD COLUMN phone TEXT`, (err) => {// 忽略列已存在的错误if (err && !err.message.includes('duplicate column name')) {console.error('迁移错误:', err);}});});db.close();
}module.exports = { runMigrations };
在应用启动时运行迁移
// app.js
const { runMigrations } = require('./migrations/migrate');// 应用启动时运行数据库迁移
runMigrations();// 其他应用代码...
7. 回滚策略
创建回滚脚本 rollback.sh
#!/bin/bash# 回滚脚本
echo "开始回滚..."# 停止当前容器
docker stop node-app
docker rm node-app# 使用之前的镜像启动
docker run -d \--name node-app \-p 3000:3000 \-v $(pwd)/database:/usr/src/app/database \node-express-app:previousecho "回滚完成"
8. 最佳实践建议
-
版本标签: 为镜像打上版本标签
docker build -t node-express-app:v1.2.3 .
-
健康检查: 在Dockerfile中添加健康检查
HEALTHCHECK --interval=30s --timeout=3s \CMD curl -f http://localhost:3000/health || exit 1
-
日志管理: 配置日志轮转
docker run -d \--log-opt max-size=10m \--log-opt max-file=3 \node-express-app
选择适合你项目规模的更新策略。对于小型项目,简单的重新构建方法就足够了;对于生产环境,建议使用蓝绿部署或自动化部署流程。