全栈手账 订阅 RSS
Git

CentOS 搭建 Git 仓库

在 CentOS 服务器上用 Git 搭建私有代码仓库,支持 SSH 免密推送,并通过 post-receive 钩子实现自动化部署。

读了 12 分钟 更新于 10 月 16 日

一、安装 Git

1.1 使用 yum 在线安装

shell
yum install -y git

1.2 查看版本验证

shell
git --version# 输出类似:git version 2.27.0

二、创建运行用户

创建一个专门用于运行 Git 服务的用户(本文以 miracle 为例):

shell
useradd miraclepasswd miracle      # 设置密码

单独建用户而非用 root,是为了隔离权限、提升安全性。


三、初始化裸仓库

3.1 切换目录并初始化

shell
cd /home/miraclegit init --bare miracle.git

--bare 创建的是裸仓库(只有 .git 内容,没有工作区),专用于做远程仓库接收 push。

3.2 设置仓库属主(关键)

裸仓库必须由运行 Git 的用户所有,否则 push 会报权限错误:

shell
chown -R miracle:miracle /home/miracle/miracle.git

四、客户端克隆与推送

4.1 克隆仓库

shell
git clone miracle@你的服务器IP:/home/miracle/miracle.git

输入 miracle 用户密码,克隆成功。

4.2 推送代码

shell
echo a >> a.txtgit add .git commit -m 'a'git push

4.3 常见报错:权限不足

shell
remote: error: insufficient permission for adding an object to repository database ./objectsremote: fatal: failed to write objecterror: remote unpack failed: unpack-objects abnormal exit! [remote rejected] master -> master (unpacker error)

原因:仓库目录属主不是 miracle(通常是 root 创建的)。

解决:

shell
sudo chown -R miracle:miracle /home/miracle/miracle.git

五、配置 SSH 免密登录(SSH Key)

每次 push 都输密码很麻烦,配置 SSH 公钥即可免密。

5.1 核心原理(先理解,别搞反)

文件 存放位置 内容 说明
私钥 id_ed25519 客户端本地 .ssh/ 私钥 只能留在客户端,绝不上传服务器
公钥 id_ed25519.pub 服务器 .ssh/authorized_keys 公钥 服务器保存的是客户端公钥

⚠️ 重点:authorized_keys 里存的是公钥(.pub),不是私钥。私钥永远只放客户端。

5.2 客户端生成密钥

在客户端(你的电脑)执行:

shell
ssh-keygen -t ed25519 -C "你的邮箱"# 一路回车即可,生成 ~/.ssh/id_ed25519(私钥)和 id_ed25519.pub(公钥)

ed25519 比 rsa 更安全更快(推荐)。如需兼容老系统也可 -t rsa。

5.3 把公钥上传到服务器

把客户端公钥内容追加到服务器的 authorized_keys:

shell
# 方式一:在客户端一键复制(Windows Git Bash / macOS / Linux 通用)ssh-copy-id miracle@你的服务器IP# 方式二:手动追加# 查看客户端公钥内容:cat ~/.ssh/id_ed25519.pub# 把输出内容复制到服务器的 /home/miracle/.ssh/authorized_keys 文件中(没有就新建)

在服务器上设置 .ssh 目录权限:

shell
mkdir -p /home/miracle/.ssh# 将客户端公钥写入 authorized_keys 后执行:chown -R miracle:miracle /home/miracle/.sshchmod 700 /home/miracle/.sshchmod 600 /home/miracle/.ssh/authorized_keys

5.4 开启 SSH 公钥认证

编辑 /etc/ssh/sshd_config,确保以下配置生效(被注释的取消注释,缺的补上):

shell
PubkeyAuthentication yesAuthorizedKeysFile  .ssh/authorized_keys

RSAAuthentication yes 是旧版 OpenSSH(7.x 以下)的配置,新版已废弃,无需添加。

保存后重启 sshd:

shell
systemctl restart sshd

相关命令:

shell
systemctl status sshd    # 查看 ssh 服务状态systemctl start sshd     # 开启 ssh 服务systemctl enable sshd    # 设置开机自启

5.5 客户端验证免密

shell
git clone miracle@你的服务器IP:/home/miracle/miracle.git

无需输入密码即为配置成功。


六、post-receive 自动部署

push 代码后,通过 post-receive 钩子自动把代码部署到站点目录。

6.1 进入 hooks 目录并创建钩子

shell
cd /home/miracle/miracle.git/hooksvim post-receive

vim 用法:按 i 进入编辑,编辑完按 ESC,再输入 :wq 保存退出。

6.2 基础版(仅部署代码)

shell
#!/bin/bash# 项目部署目录(push 后代码出现的位置)PROJECT_DIR="/www/wwwroot/你的站点目录"# 仓库目录GIT_DIR="/home/miracle/miracle.git"# 将代码 checkout 到部署目录git --work-tree=$PROJECT_DIR --git-dir=$GIT_DIR checkout -f

6.3 进阶版(构建 + 通知,可选)

若部署的是需构建的前端项目(Vue 等),可加上安装依赖、构建、通知(token 请换成你自己的):

shell
#!/bin/bashBUILD_TIME=$(date "+%Y-%m-%d %H:%M:%S")PROJECT_DIR="/www/wwwroot/你的站点目录"GIT_DIR="/home/miracle/miracle.git"# 你的钉钉机器人 Webhook(token 换成自己的)DINGDING_WEBHOOK="https://oapi.dingtalk.com/robot/send?access_token=你的token"# 拉取代码git --work-tree=$PROJECT_DIR --git-dir=$GIT_DIR checkout -fcd $PROJECT_DIR# 安装依赖并构建yarnyarn build# 按构建结果发通知if [ $? -eq 0 ]; then  curl -X POST "$DINGDING_WEBHOOK" \    -H 'Content-Type: application/json' \    -d "{\"msgtype\":\"text\",\"text\":{\"content\":\"构建成功:$BUILD_TIME\"}}"else  curl -X POST "$DINGDING_WEBHOOK" \    -H 'Content-Type: application/json' \    -d "{\"msgtype\":\"text\",\"text\":{\"content\":\"构建失败:$BUILD_TIME\"}}"fi

6.4 添加执行权限

shell
cd /home/miracle/miracle.git/hookschmod +x post-receive

6.5 权限说明

部署目录需对执行用户可写。若 push 时出现 remote: error: unable to create file 某某文件,说明部署目录无写权限:

shell
# 部署目录属主改为执行 git 的用户chown -R miracle:miracle /www/wwwroot/你的站点目录

建议用 chown 修正属主,而非盲目 chmod 777(777 会让所有用户可写,不安全)。

配置成功后,客户端 git push,代码会自动出现在部署目录。


七、同时推送到多个远程仓库

一份代码同时推到服务器私有仓库和 Gitee/GitHub。

7.1 查看当前远程

shell
git remote -v

7.2 添加多个远程

shell
# 添加 Giteegit remote add gitee https://gitee.com/你的用户名/仓库名.git# 添加 GitHubgit remote add github https://github.com/你的用户名/仓库名.git

7.3 给同一 remote 配置多个地址(一次 push 全同步)

shell
git remote rm origingit remote add origin git@你的服务器:/home/miracle/miracle.gitgit remote set-url --add origin https://gitee.com/你的用户名/仓库名.git

之后一次 git push origin master 会同时推到两个地址。

7.4 建立本地与远程分支跟踪

shell
git branch --set-upstream-to=origin/master master

7.5 强制推送(慎用)

shell
git push gitee master --force

附:常见问题排查

1. REMOTE HOST IDENTIFICATION HAS CHANGED

code
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@Host key verification failed.

原因:服务器 IP 变更或重装系统,导致主机指纹与本地记录的 known_hosts 不一致。

解决(Windows 客户端):删除 C:\Users\Administrator\.ssh 下的 known_hosts(和 known_hosts.old)文件,重新连接即可。

2. push 报 insufficient permission

见「四、4.3」,根因是仓库属主不对,chown 修正即可。

3. 免密不生效

按顺序检查:

  1. 服务器 authorized_keys 里存的是客户端公钥(不是私钥);
  2. sshd_config 中 PubkeyAuthentication yes 已开启;
  3. .ssh 目录权限 700、authorized_keys 权限 600;
  4. 重启了 sshd 服务;
  5. 客户端私钥路径正确(Windows 默认 C:\Users\用户名\.ssh\id_ed25519)。

完

前端、后端、部署、客服都是我一个人。写这里的东西都是真踩过的坑,不是抄来的教程。