Ubuntu下 ThinkPHP 项目自动化部署实战
一、方案总览
二、环境与目录准备
三、自动化部署脚本
#!/usr/bin/env bash
set -e
APP_DIR="/var/www/your_project"
REPO_URL="git@github.com:username/your_project.git"
BRANCH="${1:-main}"
LOG_FILE="/var/log/deploy.log"
log() {
echo "[$(date '+%F %T')] $*" | tee -a "$LOG_FILE"
}
# 1) 拉取代码(裸仓库或工作区均可,这里演示工作区)
if [ ! -d "$APP_DIR/.git" ]; then
log "首次克隆 $REPO_URL 到 $APP_DIR"
git clone -b "$BRANCH" "$REPO_URL" "$APP_DIR"
else
log "更新 $APP_DIR 分支 $BRANCH"
git -C "$APP_DIR" fetch --all
git -C "$APP_DIR" reset --hard "origin/$BRANCH"
git -C "$APP_DIR" clean -fd
fi
# 2) 安装依赖
log "安装 Composer 依赖"
composer install --optimize-autoloader --no-dev -o -d "$APP_DIR"
# 3) 发布资源(ThinkPHP 6 常用)
if [ -f "$APP_DIR/artisan" ]; then
log "发布 ThinkPHP 资源"
php "$APP_DIR/artisan" config:cache
php "$APP_DIR/artisan" route:cache
php "$APP_DIR/artisan" view:cache
fi
# 4) 权限
log "设置目录权限"
chown -R www-data:www-data "$APP_DIR"
find "$APP_DIR" -type d -exec chmod 755 {} \;
find "$APP_DIR" -type f -exec chmod 644 {} \;
chmod -R 755 "$APP_DIR/runtime"
# 5) 重启服务
log "重启 PHP-FPM 与 Nginx"
systemctl reload php7.4-fpm || systemctl restart php7.4-fpm
systemctl reload nginx || systemctl restart nginx
log "部署完成 -> $APP_DIR (branch: $BRANCH)"
四、触发方式与免密拉取
#!/usr/bin/env bash
TARGET="/var/www/your_project"
GIT_DIR="/var/repo/your_project.git"
BRANCH="main"
while read oldrev newrev ref; do
if [[ $ref = refs/heads/$BRANCH ]]; then
git --work-tree="$TARGET" --git-dir="$GIT_DIR" checkout -f "$BRANCH"
bash "$TARGET/deploy.sh" "$BRANCH"
fi
done
<?php
$secret = 'your_webhook_secret';
$body = file_get_contents('php://input');
$sig = $_SERVER['HTTP_X_HUB_SIGNATURE_256'] ?? '';
if (!hash_equals('sha256=' . hash_hmac('sha256', $body, $secret), $sig)) {
http_response_code(403); exit('签名验证失败');
}
$payload = json_decode($body, true);
if (($payload['ref'] ?? '') === 'refs/heads/main') {
exec('cd /var/www/your_project && bash deploy.sh main >> /var/log/deploy.log 2>&1 &');
echo '部署已触发';
}
五、常见问题与加固建议