Kichik va o'rta saytlarda deploy jarayoni ko'pincha FTP orqali fayllarni qo'lda ko'chirishdan iborat bo'ladi. Bu usul ishlaydi, lekin qaysi fayl o'zgargani esdan chiqadi, eski fayllar serverda qolib ketadi va ikki dasturchi bir vaqtda ishlasa, bir-birining o'zgarishini ustidan yozib yuboradi. Agar loyiha Git repozitoriyasida saqlansa, serverni ham o'sha repozitoriyaning bir nusxasi sifatida ko'rish mumkin. Shunda yangilash bitta git pull buyrug'iga aylanadi va serverdagi kod har doim aniq bir commit'ga mos keladi.
Bu usul qachon to'g'ri keladi
git pull bilan deploy qilish oddiy PHP saytlar, WordPress mavzusi yoki plagini, Laravel loyihasi va statik sahifalar uchun yaxshi ishlaydi. Shart bitta: hostingingizda SSH kirish va serverda git dasturi bo'lishi kerak. sayt.uz hostingida SSH tarifingizda bor-yo'qligini kabinetdan yoki texnik yordam orqali bilib olasiz, VPS'da esa Git'ni o'zingiz o'rnatasiz. Agar loyiha Node.js yoki frontend yig'ishni (build) talab qilsa, pull'dan keyin qo'shimcha buyruqlar kerak bo'ladi, buni quyida ko'rib chiqamiz.
Shuni ham aytish kerakki, bu usul har bir yangilanishda bir necha soniyalik "oraliq holat" yaratadi: fayllarning bir qismi yangilangan, bir qismi hali eski bo'ladi. Oddiy saytlarda bu sezilmaydi, lekin katta trafikli do'konlarda uzilishsiz deploy uchun release papkalari va symlink usulidan foydalangan ma'qul.
Serverda deploy kalit yaratish
Repozitoriya yopiq (private) bo'lsa, server unga kirish uchun o'z kalitiga ega bo'lishi kerak. Shaxsiy GitHub yoki GitLab parolingizni serverga yozish xato, buning o'rniga faqat o'qish huquqiga ega "deploy key" ishlatiladi. Server terminalida kalit yaratiladi va uning ochiq qismi repozitoriya sozlamalaridagi Deploy keys bo'limiga qo'shiladi.
ssh-keygen -t ed25519 -C "deploy@example.uz" -f ~/.ssh/deploy_key -N ""
cat ~/.ssh/deploy_key.pub # shu qatorni repozitoriyaning Deploy keys bo'limiga qo'shing
# ~/.ssh/config ga yozuv:
Host github.com
IdentityFile ~/.ssh/deploy_key
IdentitiesOnly yes
Ulanishni ssh -T git@github.com buyrug'i bilan tekshirasiz: muvaffaqiyatli bo'lsa, GitHub sizni tanigani haqida xabar qaytaradi. Deploy kalitni "faqat o'qish" rejimida qoldirish muhim, shunda server buzilgan taqdirda ham hujumchi repozitoriyangizga kod yoza olmaydi.
Birinchi klonlash va papka tuzilishi
Ko'p hostinglarda saytning ildiz papkasi oldindan belgilangan bo'ladi, masalan ~/www/example.uz. Agar papka bo'sh bo'lsa, repozitoriyani to'g'ridan-to'g'ri unga klonlash mumkin. Papkada allaqachon fayllar bo'lsa, avval ularning zaxira nusxasini olib, keyin papkani bo'shatib klonlash xavfsizroq.
cd ~/www
git clone git@github.com:misol/example-sayt.git example.uz
cd example.uz
git log --oneline -1 # serverda qaysi commit turganini ko'rish
Eng ko'p e'tibordan chetda qoladigan narsa bu .git papkasi. Sayt ildizida turgan bu papka butun loyiha tarixini, ba'zan eski parollarni ham saqlaydi va veb-server uni ochiq bersa, istalgan odam kodni yuklab olishi mumkin. Apache'da quyidagi qoida .htaccess fayliga qo'shilsa, bunday so'rovlar rad etiladi; Nginx'da esa shunga o'xshash location qoidasi kerak. Yanada yaxshi yechim, agar framework imkon bersa, veb-ildizni public kabi ichki papkaga yo'naltirishdir.
# .htaccess (Apache)
RedirectMatch 404 /\.git
# Nginx
location ~ /\.git { deny all; return 404; }
.gitignore va serverdagi maxfiy fayllar
Serverga xos fayllar, ya'ni .env, wp-config.php, foydalanuvchilar yuklagan rasmlar va kesh papkalari repozitoriyaga kirmasligi kerak. Aks holda har bir git pull ularni lokal nusxa bilan almashtirib yuboradi yoki, aksincha, ishlab turgan serverdagi parollar GitHub'ga chiqib ketadi. Shuning uchun .gitignore faylida bu yo'llarni aniq ko'rsatib qo'ying.
.env
wp-config.php
storage/logs/
wp-content/uploads/
vendor/
node_modules/
Yangilash skripti
Har safar bir nechta buyruqni qo'lda terish o'rniga ularni kichik skriptga yig'ib qo'yish qulay. Quyidagi misol Laravel loyihasi uchun: u avval lokal o'zgarishlar yo'qligini tekshiradi, keyin faqat "fast-forward" usulida yangilaydi, ya'ni serverdagi tarix repozitoriyadagidan ajralib qolgan bo'lsa, birlashtirishga urinmasdan to'xtaydi.
#!/bin/bash
set -e
cd ~/www/example.uz
if [ -n "$(git status --porcelain --untracked-files=no)" ]; then
echo "Serverda commit qilinmagan o'zgarishlar bor, to'xtatildi"; exit 1
fi
git fetch origin
git pull --ff-only origin main
composer install --no-dev --optimize-autoloader
php artisan migrate --force
php artisan config:cache
echo "Deploy tugadi: $(git log --oneline -1)"
Skriptni deploy.sh nomi bilan saqlab, chmod +x deploy.sh buyrug'i bilan bajariladigan qilasiz. WordPress mavzusi uchun Composer va migratsiya qatorlari kerak emas, odatda faqat git pull va kesh plaginini tozalash yetarli.
Misol: Samarqanddagi o'quv markazi sayti
Samarqanddagi o'quv markazining sayti oddiy PHP'da yozilgan va unda kurslar jadvali hamda ro'yxatdan o'tish formasi bor. Avval dasturchi har bir tuzatishdan keyin o'nlab fayllarni FTP orqali yuklardi va bir marta eski versiyadagi forma faylini yuklab, bir kun davomida arizalar kelmay qolgan. Git'ga o'tgach u o'zgarishlarni noutbukda qilib, git push bilan GitHub'ga yuboradi, so'ng serverda ./deploy.sh ni ishga tushiradi. Xato chiqsa, git log orqali oldingi commit'ni topib, git checkout bilan bir daqiqada qaytaradi.
Tez-tez uchraydigan xatolar
"Your local changes would be overwritten by merge" xabari serverda kimdir fayllarni to'g'ridan-to'g'ri tahrirlaganini bildiradi. Bu holatda avval git diff bilan o'zgarishni ko'rib chiqing: kerakli bo'lsa, uni repozitoriyaga ko'chiring, keraksiz bo'lsa git checkout -- fayl bilan bekor qiling. "Permission denied (publickey)" esa deploy kalit qo'shilmagan yoki config fayli noto'g'ri ekanini ko'rsatadi. Fayllar egasi noto'g'ri bo'lsa, ya'ni klonlash root nomidan qilingan bo'lsa, sayt yuklagan rasmlarni saqlay olmay qoladi, shuning uchun Git buyruqlarini doim sayt egasi bo'lgan foydalanuvchi nomidan bajaring.