بسیاری از سایتها هنوز اینطور بهروز میشوند: فایلها را با FTP میکشند، یکی را جا میاندازند، نسخهی قدیمی را اشتباهی رونویسی میکنند و بعد نمیدانند سایت زنده دقیقاً با کدام کد اجرا میشود. گیت این مشکل را حل میکند: سایت همیشه روی یک کامیت مشخص است، بهروزرسانی با یک دستور انجام میشود و برگشت به نسخهی قبل ممکن است.
هاست اشتراکی محدودیتهایی دارد: دسترسی ریشه نیست، گاهی SSH بسته است و بعضی توابع غیرفعالاند. با این حال دو روش ساده معمولاً جواب میدهد. پیشنیاز این مقاله آشنایی با گیت برای شروع و داشتن یک مخزن است.
قبل از شروع: چه چیزی نباید در مخزن باشد#
استقرار با گیت فقط وقتی امن است که چیزهای حساس وارد مخزن نشده باشند. فایل .gitignore پروژه باید دستکم اینها را ببندد:
.env
vendor/
node_modules/
storage/logs/*
wp-config.php
wp-content/uploads/آپلودهای کاربران و فایل تنظیمات واقعی روی سرور میمانند و در مخزن نیستند. اگر پروژهتان لاراول است، پیش از ادامه لاراول در public_html و htaccess و چکلیست هاست اشتراکی برای لاراول را هم نگاه کنید.
دو روش رایج#
| روش | نیاز | مزیت | ایراد |
|---|---|---|---|
| ۱. push به مخزن bare و hook | SSH | استقرار با یک push، بدون نیاز به دسترسی مخزن از سمت سرور | ساخت اولیه کمی کار دارد |
| ۲. git pull روی سرور | SSH یا ابزار Git کنترلپنل | سادهترین مسیر | سرور باید به مخزن دسترسی بخواند |
روش اول تمیزتر است و اینجا مفصلتر توضیح داده میشود.
روش اول: مخزن bare و hook پس از push#
ایده این است که روی هاست یک مخزن «برهنه» (فقط تاریخچه، بدون فایلهای کار) بسازید. وقتی از کامپیوتر خودتان به آن push میکنید، یک hook فایلهای آخرین نسخه را در پوشهی سایت بیرون میریزد.
۱. ساخت مخزن روی سرور#
از طریق SSH به هاست وصل شوید. مخزن را بیرون از پوشهی عمومی بسازید:
mkdir -p ~/repos/site.git
cd ~/repos/site.git
git init --bare --initial-branch=main۲. نوشتن hook#
فایل hooks/post-receive را بسازید. این اسکریپت فقط وقتی شاخهی main push شود، فایلها را در پوشهی سایت قرار میدهد:
cat > ~/repos/site.git/hooks/post-receive <<'EOF'
#!/bin/bash
set -euo pipefail
TARGET="$HOME/public_html"
GIT_DIR="$HOME/repos/site.git"
while read -r oldrev newrev ref; do
if [ "$ref" = "refs/heads/main" ]; then
echo "Deploying main to $TARGET"
git --work-tree="$TARGET" --git-dir="$GIT_DIR" checkout -f main
cd "$TARGET"
if [ -f composer.json ]; then
composer install --no-dev --optimize-autoloader --no-interaction
fi
fi
done
EOF
chmod +x ~/repos/site.git/hooks/post-receiveچند نکته دربارهی این اسکریپت:
set -euo pipefailاجرا را در اولین خطا متوقف میکند و استقرار نیمهکاره را کم میکند.checkout -fفایلهای ردیابیشده را رونویسی میکند، ولی فایلهایی که در مخزن نیستند (مثل.envو آپلودها) را پاک نمیکند.- اگر
composerروی هاست در دسترس نیست یا توابع لازمش بسته است، وابستگیها را روی کامپیوتر خودتان نصب و فقط همان نتیجه را منتقل کنید؛ بخشی از آن در توابع بستهی PHP روی هاست اشتراکی آمده است.
۳. اتصال و اولین push#
روی کامپیوتر خودتان، مخزن سرور را بهعنوان remote اضافه کنید. آدرس را با اطلاعات واقعی هاستتان جایگزین کنید:
git remote add production ssh://USER@HOST/home/USER/repos/site.git
git push production mainاز این به بعد هر بار git push production main سایت را بهروز میکند. برای ورود، از کلید SSH استفاده کنید نه رمز حساب هاست.
روش دوم: git pull روی سرور#
اگر مخزن شما در یک سرویس مثل گیتهاب است و میخواهید سرور آن را بکشد، در پوشهی پروژه یک بار git clone و بعد هر بار بهروزرسانی انجام دهید:
cd ~/public_html
git fetch origin
git reset --hard origin/mainبرای اینکه سرور به مخزن خصوصی دسترسی داشته باشد، از Deploy key استفاده کنید: یک جفت کلید SSH مخصوص همین سرور بسازید، بخش عمومی را در تنظیمات مخزن بهعنوان کلید فقطخواندنی اضافه کنید و بخش خصوصی را فقط روی همان سرور نگه دارید. به این ترتیب اگر هاست آلوده شد، مهاجم نمیتواند در مخزن بنویسد. بهجای git reset --hard که تغییرهای دستی روی سرور را دور میاندازد، بهتر است اصلاً روی سرور کد را دستی ویرایش نکنید.
بعضی کنترلپنلها هم ابزار Git داخلی دارند که همین کار را با رابط گرافیکی انجام میدهد؛ اگر هاستتان دارد، همان را بخوانید و گزینهها را از مستندات خود هاست ببینید.
پنهانکردن پوشهی .git#
بزرگترین خطر استقرار با روش دوم این است که پوشهی .git داخل پوشهی عمومی بماند. اگر وبسرور آن را سرو کند، دیگران میتوانند تاریخچه و سورس کد و گاهی رمزهای قدیمی را بخوانند. در روش اول .git اصلاً داخل پوشهی عمومی نیست، که ایمنتر است. اگر مجبورید، در .htaccess دسترسی را ببندید:
RedirectMatch 404 /\.gitبعد در مرورگر آدرس https://example.com/.git/config را امتحان کنید؛ باید خطای ۴۰۴ یا ۴۰۳ بگیرید، نه محتوای فایل.
بعد از استقرار#
- کش را پاک کنید. در لاراول
php artisan config:cacheو در وردپرس پاککردن افزونهی کش لازم است، وگرنه تغییرها دیده نمیشوند. - مایگریشن دیتابیس را جدا و با احتیاط اجرا کنید. قبلش پشتیبان بگیرید؛ بکآپ خودکار دیتابیس در اینجا به کار میآید.
- برچسب نسخه بزنید.
git tag release-checkout-fixکمک میکند بدانید چه چیزی کی مستقر شد.
خلاصه#
- استقرار با گیت، سایت را به یک کامیت مشخص وصل میکند و برگشت را ممکن میسازد.
- روش push به مخزن bare و hook، تمیزترین راه روی هاستی با SSH است.
- رمزها،
.envو آپلودها نباید در مخزن باشند. - از Deploy key فقطخواندنی استفاده کنید و رمز حساب هاست را در اسکریپت نگذارید.
- مخزن را بیرون پوشهی عمومی نگه دارید یا دسترسی به
.gitرا ببندید و با مرورگر امتحان کنید. - پیش از هر تغییر دیتابیس پشتیبان بگیرید.