Git --bare部署VPS应用的疑问:应用启停与方案对比
用Git Bare仓库部署编译后应用到VPS的解决方案
场景说明
仅使用Git与原生Linux VPS,无第三方平台(GitHub、Docker Hub等),源码与编译输出分离,已为预发布(staging)和生产(production)环境分别创建--bare仓库,完成初始化、权限配置、本地远程推送,但推送后仓库仅含Git核心文件,需获取可运行文件并实现推送新版本后自动重启Docker应用。
方案选型
对比三种部署方案后选择Git:
- FTP/Zip:无法自动删除旧文件、无版本回滚功能,自动化实现复杂
- Rsync:支持
--delete参数删除旧文件、可自动化,但Windows下SSH兼容性差,不符合跨平台需求 - Git:支持自动删除旧文件、推送即可完成自动化部署、支持版本回滚,因此选用该方案
核心问题解决
1. 从Bare仓库导出可运行应用文件
Bare仓库本身不存储工作目录,需通过**Git钩子(post-receive)**将推送的代码检出到实际运行目录:
- 在VPS上创建应用运行目录(如
/var/www/staging-app和/var/www/production-app),确保Git用户拥有读写权限 - 进入对应bare仓库的
hooks目录(如/var/www/staging.git/hooks/) - 创建
post-receive脚本,示例内容:
#!/bin/bash # 预发布环境示例配置 TARGET_DIR="/var/www/staging-app" GIT_DIR="/var/www/staging.git" BRANCH="main" while read oldrev newrev refname; do # 仅处理指定分支的推送请求 if [[ $refname == "refs/heads/$BRANCH" ]]; then echo "Deploying $BRANCH branch to $TARGET_DIR..." git --work-tree="$TARGET_DIR" --git-dir="$GIT_DIR" checkout -f $BRANCH echo "Deployment completed." fi done
- 给脚本添加执行权限:
chmod +x post-receive
推送代码时,Git会自动触发该钩子,将指定分支的文件检出到目标运行目录,即可获取可运行的应用文件。
2. 推送新版本后自动重启Docker应用
在上述post-receive脚本中添加Docker操作命令即可实现自动重启,修改后的示例脚本:
#!/bin/bash TARGET_DIR="/var/www/staging-app" GIT_DIR="/var/www/staging.git" BRANCH="main" DOCKER_COMPOSE_FILE="$TARGET_DIR/docker-compose.yml" while read oldrev newrev refname; do if [[ $refname == "refs/heads/$BRANCH" ]]; then echo "Deploying $BRANCH branch to $TARGET_DIR..." git --work-tree="$TARGET_DIR" --git-dir="$GIT_DIR" checkout -f $BRANCH echo "Restarting Docker containers..." # 停止旧容器、重新构建(按需)并启动新容器 docker-compose -f "$DOCKER_COMPOSE_FILE" down docker-compose -f "$DOCKER_COMPOSE_FILE" up -d --build echo "Deployment and restart completed." fi done
注意:需确保运行Git的用户具备Docker命令执行权限,可将用户加入docker组:usermod -aG docker git-user
补充说明
- Bare仓库是Git部署场景的标准用法,并非误用,它避免了工作目录与仓库的冲突,适合作为远程部署仓库
- 如需版本回滚,只需在本地回滚分支后重新推送,或直接在VPS运行目录执行
git checkout <commit-hash>,再重启Docker即可
内容的提问来源于stack exchange,提问作者Takeshi Tokugawa YD
相关产品推荐
相关产品推荐

