Замість ручного FTP при кожній зміні — налаштуйте git push для автоматичного деплою. Займає 15 хвилин, економить години роботи.
Деплой на VPS через Git bare repo
# На VPS: створити bare репозиторій
mkdir -p /var/repo/mysite.git
cd /var/repo/mysite.git
git init --bare
# Створити хук post-receive
nano hooks/post-receive
#!/bin/bash
GIT_WORK_TREE=/var/www/mysite git checkout -f main
echo "Deployed to /var/www/mysite"
chmod +x hooks/post-receive
# На локальному комп'ютері:
git remote add production user@server-ip:/var/repo/mysite.git
git push production main
Деплой на cPanel хостинг через Git
cPanel → Файли → Git™ Version Control:
- Create → вкажіть шлях до репозиторію (
public_html) - Вкажіть URL GitHub/GitLab репозиторію
- Натисніть Update from Remote для ручного деплою
GitHub Actions: повний автодеплой
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy via SSH
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.SERVER_IP }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
cd /var/www/mysite
git pull origin main
composer install --no-dev
php artisan migrate --force
Часті помилки під час Git-деплою
Нижче — повідомлення, з якими реально стикаються під час першого налаштування bare-репозиторію та хуків, і що за ними стоїть.
Permission denied (publickey).
fatal: Could not read from remote repository.
bash: hooks/post-receive: Permission denied
remote: error: hook declined to update refs/heads/main
error: failed to push some refs to 'server-ip:/var/repo/mysite.git'
fatal: 'production' does not appear to be a git repository
| Повідомлення | Причина | Рішення |
|---|---|---|
| Permission denied (publickey) | SSH-ключ клієнта не доданий на сервері або використовується не той ключ | Перевірити ssh -T user@server-ip -i шлях_до_ключа, додати публічний ключ у ~/.ssh/authorized_keys |
| hooks/post-receive: Permission denied | Хук не позначений виконуваним файлом — пропущено chmod +x | Виконати chmod +x hooks/post-receive і перевірити перший рядок файлу (#!/bin/bash) |
| hook declined to update refs / failed to push some refs | Сам хук завершився з ненульовим кодом — наприклад, git checkout -f впав через права на робочій директорії | Запустити хук вручну: bash hooks/post-receive, виправити власника і права на /var/www/mysite |
| fatal: 'production' does not appear to be a git repository | Невірний URL remote або описка у шляху до bare-репозиторію | Звірити git remote -v з реальним шляхом на сервері — каталог має закінчуватися на .git |
Порівняння способів деплою
| Спосіб | Чи потрібен SSH | Швидкість деплою | Коли застосовувати |
|---|---|---|---|
| Bare repo + post-receive hook | Так, ключовий доступ обов'язковий | Миттєво після git push | VPS із повним доступом, власний пайплайн без сторонніх сервісів |
| cPanel Git Version Control | Не обов'язковий, працює через вебінтерфейс | Вручну кнопкою Update from Remote | Shared-хостинг, розробник без SSH-доступу |
| GitHub Actions | Так, для кроку підключення по SSH до сервера | Автоматично при push у main, 1–3 хвилини | Команда, потрібні тести і збірка перед викладенням |
Коли Git-деплой не підходить
- Сайт зберігає файли користувачів (медіатеку, завантаження) прямо в робочій директорії репозиторію —
git checkout -fпід час деплою може зачепити їх без акуратного.gitignore - Потрібен zero-downtime деплой із миттєвим відкатом — простий
checkout -fне дає атомарної підміни версії, для цього потрібна схема з релізами і симлінком на поточний каталог - На хостингу немає ні SSH, ні розділу Git Version Control у панелі — тоді залишається лише звичайне завантаження по FTP
- У репозиторії регулярно змінюються важкі бінарні файли (відео, дампи БД) — Git погано справляється з ними без Git LFS, а LFS доступний не на кожному сервері
Як перевірити, що деплой пройшов успішно
# На сервері: порівняти поточний коміт із тим, що запушили локально
cd /var/repo/mysite.git && git log -1 --oneline
# У робочій директорії: час зміни файлів має бути свіжим
stat -c '%y' /var/www/mysite/index.php
# Сайт відповідає без помилки 500
curl -I https://yourdomain.com/
- Порівняйте хеш коміту в bare-репозиторії з тим, що було запушено локально — вони мають збігатися
- Перевірте час зміни файлів у робочій директорії через
stat— він має оновитися в момент деплою - Відкрийте сайт через
curl -I: якщо хук відпрацював, аcomposer installвпав, файли оновляться, але сайт усе одно зламається - У GitHub Actions перевірте вкладку Actions — останній workflow run має бути зеленим, навіть якщо
git pushпройшов без помилок
Налаштування доступу за ключами замість пароля для самого сервера розглядає стаття SSH-доступ на shared-хостингу, а автоматизацію супутніх завдань після деплою — матеріал про cron-завдання в cPanel.
Часті питання
Як налаштувати деплой без простою і зі швидким відкатом, якщо git checkout -f не атомарний?
Простий checkout -f підмінює файли прямо в робочій директорії, і сайт на мить бачить неповний набір файлів. Для надійності код розгортають в окрему папку під кожен реліз і тримають симлінк на поточну версію: хук збирає новий реліз, перевіряє його і перемикає симлінк однією операцією. Відкат — просто симлінк на попередню папку.
Що станеться з файлами, зміненими вручну прямо на сервері, під час наступного git push?
Хук виконує git checkout -f, а це примусовий перезапис відстежуваних файлів версією з коміту — будь-яка ручна правка конфігу чи коду прямо на сервері зникне без попередження під час наступного деплою. Файли користувачів і медіатеку це не зачіпає, лише якщо вони не відстежуються репозиторієм і описані в .gitignore.
Як відкотитися до попередньої версії сайту, якщо новий деплой зламав роботу?
На VPS з bare-репозиторієм досить перемкнутися на потрібний коміт у робочій директорії командою git checkout і повторити кроки хука вручну — composer install і міграції за потреби. У cPanel простіше вказати в Git Version Control попередній коміт і знову натиснути оновлення з віддаленого репозиторію. Для миттєвого відкату корисна схема релізів із симлінком.
Чи варто переходити на GitHub Actions, якщо вже налаштовано git push через bare-репозиторій?
Bare-репозиторій із хуком швидший і простіший для одного розробника — деплой відбувається одразу після push без очікування зовнішнього сервісу. GitHub Actions виправданий, коли перед викладенням потрібні збірка, тести чи крок composer install із перевіркою результату: пайплайн зупинить деплой при помилці збірки, тоді як простий хук застосує код у будь-якому разі.