
使用共享主机的开发者经常发现自己每次修改代码后都要手动通过FTP上传文件——既费时又容易出错。好消息是,支持SSH的主机可以配置为使用Git裸存储库和post-receive钩子每次git push时自动部署。本指南将介绍在DirectAdmin主机上的完整设置步骤。
前提条件:主机已启用SSH访问,本地已安装Git(用git --version检查),已有GitHub或GitLab存储库。
1. 什么是主机上的CI/CD?
CI/CD(持续集成/持续部署)自动化了将代码更改部署到线上服务器的过程。对于共享主机,实际方法是在服务器上使用Git裸存储库结合post-receive钩子——一个在代码推送时自动运行的Shell脚本。
流程是:从本地机器推送代码到主机服务器 → post-receive钩子自动运行git checkout → 更新的文件立即出现在public_html中。
2. 您需要什么
- 已启用SSH访问的主机(通过DirectAdmin或支持工单申请)
- 本地机器上已安装Git
- 用于认证的SSH密钥(推荐而非密码)
- GitHub或GitLab存储库(如果您想要webhook触发的部署)
AsiaGB主机:通过提交包含您主机用户名的支持工单可以启用SSH访问。我们的团队将在24小时内激活。
3. 在服务器上创建Git裸存储库
通过SSH连接并在public_html之外创建裸存储库:
# Connect via SSH ssh [email protected] # Create a folder for the bare repo (outside public_html) mkdir ~/repos cd ~/repos git init --bare mysite.git
裸存储库没有工作目录——它纯粹作为推送的接收端点,而不是存储可编辑文件的地方。
4. 创建post-receive钩子脚本
钩子脚本是Git在接收到推送后自动运行的Shell脚本。创建钩子文件:
nano ~/repos/mysite.git/hooks/post-receive
粘贴以下内容,将/home/username/public_html替换为您的实际路径:
#!/bin/bash
# post-receive hook — deploy to public_html
GIT_WORK_TREE=/home/username/public_html
export GIT_WORK_TREE
GIT_DIR=/home/username/repos/mysite.git
export GIT_DIR
git checkout -f main
echo "Deploy complete: $(date)"保存文件,然后使其可执行:
chmod +x ~/repos/mysite.git/hooks/post-receive
⚠️ 检查您的分支名称:如果您的存储库使用master而不是main,请将git checkout -f main更改为git checkout -f master。
5. 在本地机器上添加远程
在您的本地项目目录中,将主机服务器添加为Git远程:
# Navigate to your local project cd ~/myproject # Add the hosting server as a remote named "hosting" git remote add hosting ssh://[email protected]/home/username/repos/mysite.git # Test with your first push git push hosting main
如果一切配置正确,您将看到来自钩子的"Deploy complete"消息,您更新的文件将立即出现在public_html中。
6. GitHub/GitLab Webhook(高级)
要在每次推送到GitHub或GitLab时自动触发部署,请在public_html中创建PHP webhook接收器:
# Create deploy.php in public_html
<?php
$secret = 'YOUR_WEBHOOK_SECRET';
$payload = file_get_contents('php://input');
$sig = 'sha256=' . hash_hmac('sha256', $payload, $secret);
if (!hash_equals($sig, $_SERVER['HTTP_X_HUB_SIGNATURE_256'] ?? '')) {
http_response_code(403); exit;
}
exec('cd /home/username/repos/mysite.git && git fetch && GIT_WORK_TREE=/home/username/public_html git checkout -f main 2>&1', $out);
echo implode("\n", $out);然后在GitHub的设置 → Webhooks下添加webhook,将Payload URL设置为https://yourdomain.com/deploy.php,并输入相同的密钥字符串。
7. 测试自动部署
在本地进行任何更改并推送:
git add . git commit -m "test: auto deploy" git push hosting main
打开您的网站——成功推送后更改应立即出现。
8. 主机与VPS的限制对比
| 功能 | 共享主机 | VPS |
|---|---|---|
| Git 裸存储库 | ✅ 是 | ✅ 是 |
| post-receive 钩子 | ✅ 是 | ✅ 是 |
| 运行 npm install / composer | ⚠️ 有限(取决于服务器) | ✅ 完全控制 |
| Docker / 容器 | ❌ 不支持 | ✅ 是 |
| GitHub Actions 自托管运行器 | ❌ 不支持 | ✅ 是 |
| 起始价格 | 500 THB/年 | 更高 |
对于标准PHP、HTML和CSS网站,共享主机上的Git钩子部署完全足够且极具性价比。对于包含构建和测试步骤的完整CI/CD管道,VPS更为适合。
提示:添加.gitignore文件以排除不必要的文件被推送:node_modules/、.env、*.log。这可以防止密钥意外出现在您的服务器上。
9. 安全的SSH密钥认证
使用SSH密钥而不是密码不仅更方便——它在安全性上也显著更高。密钥不能像密码那样被暴力破解,并且它们可以实现从本地机器到主机服务器的无缝无密码部署。
在本地生成SSH密钥
# Generate an Ed25519 key (recommended — fast and secure) ssh-keygen -t ed25519 -C "[email protected]" # Print the public key to copy to your hosting server cat ~/.ssh/id_ed25519.pub
将公钥添加到您的主机服务器
# Connect with password for the first time ssh [email protected] # Create the authorized_keys file mkdir -p ~/.ssh && chmod 700 ~/.ssh nano ~/.ssh/authorized_keys # Paste your public key, save, then set permissions chmod 600 ~/.ssh/authorized_keys
此后,SSH连接会自动使用密钥。运行git push hosting main将在没有任何密码提示的情况下进行部署,使工作流更快且适合脚本化自动化。
⚠️ 安全提醒:永远不要将您的私钥文件(~/.ssh/id_ed25519)提交到任何存储库。只将其保留在本地机器上,永远不要分享它。
10. 多分支部署 — 开发、预发布、生产
现实项目通常将代码分为多个环境。您可以通过修改post-receive钩子来支持这一点,在决定部署位置之前检查推送的是哪个分支。
#!/bin/bash
# post-receive hook supporting multiple branches
while read oldrev newrev refname; do
BRANCH=$(git rev-parse --symbolic --abbrev-ref "$refname")
if [ "$BRANCH" = "main" ]; then
GIT_WORK_TREE=/home/username/public_html git checkout -f main
echo "Deployed to PRODUCTION: $(date)"
elif [ "$BRANCH" = "staging" ]; then
GIT_WORK_TREE=/home/username/staging git checkout -f staging
echo "Deployed to STAGING: $(date)"
fi
done推送到main会部署到public_html供线上访客查看。推送到staging会部署到单独的子目录,让您在发布到生产环境之前审查更改。
| 分支 | 部署目标 | 用途 |
|---|---|---|
main | public_html/ | 生产环境 — 对所有访客可见 |
staging | staging/ | 预发布测试 |
develop | dev/ | 活跃开发环境 |
11. 向钩子脚本添加回滚
每个可靠的部署管道都需要回滚机制。您可以直接在post-receive钩子中添加此逻辑,这样如果部署失败,服务器会自动回退到最后已知的良好提交。
#!/bin/bash GIT_WORK_TREE=/home/username/public_html export GIT_WORK_TREE GIT_DIR=/home/username/repos/mysite.git export GIT_DIR # Record the current commit before deploying PREV_COMMIT=$(git -C /home/username/public_html rev-parse HEAD 2>/dev/null || echo "none") # Deploy new code if git checkout -f main; then echo "Deploy successful: $(date)" echo "Commit: $(git rev-parse HEAD)" else echo "Deploy failed — rolling back..." git checkout -f "$PREV_COMMIT" echo "Rolled back to $PREV_COMMIT" fi
您还应该维护一个部署日志以供审计。将此行添加到您的钩子脚本:
# Append deploy record to log file
echo "$(date): branch=main commit=$(git rev-parse HEAD)" >> /home/username/deploy.log12. 共享主机上部署方法的比较
开发者使用几种方法将代码部署到共享主机。如下比较所示,每种方法在速度、可靠性和复杂性方面有不同的权衡。
| 方法 | 易用性 | 错误风险 | 最适合 |
|---|---|---|---|
| 手动FTP上传 | 低 | 高(人为错误) | 完全初学者 |
| Git钩子(裸存储库) | 高 | 低 | 大多数PHP/HTML项目 |
| PHP Webhook接收器 | 非常高 | 低(如果设置了密钥) | 使用GitHub/GitLab的团队 |
| GitHub Actions + SCP | 中等 | 低 | 需要CI步骤的项目 |
对于中小型PHP项目,带有post-receive钩子的Git裸存储库提供了最佳的简单性和可靠性平衡——特别是在已经支持SSH访问的主机方案上。设置大约需要20分钟,并提供任何技能水平的开发者都能自信维护的工作流。
提示:添加.gitignore文件以排除不必要的文件被推送:node_modules/、.env、*.log。这可以防止密钥意外出现在您的服务器上。