Top.Mail.Ru
OSEN-НИЙ SAAALEСкидка 50% на виртуальный хостинг и VDS
до 30.11.2025 Подробнее
Выберите продукт

Git‑деплой на виртуальном хостинге: bare‑репозиторий, post‑receive hook и права

Практичный Git‑деплой на виртуальном хостинге: создаём bare‑репозиторий, настраиваем post‑receive hook для выката кода в webroot, разбираем SSH, права, релизы и откаты. Подходит для PHP и статических проектов.
Git‑деплой на виртуальном хостинге: bare‑репозиторий, post‑receive hook и права

Git‑деплой на виртуальном хостинге — это быстрый и предсказуемый способ выкатывать изменения без ручной загрузки файлов. Достаточно создать bare‑репозиторий на сервере, добавить post‑receive hook и дисциплинированно следить за правами, чтобы автоматизировать релизы и откаты. Ниже — пошаговый, практичный сценарий с разбором типовых подводных камней.

Когда и зачем выбирать Git‑деплой на виртуальном хостинге

Если у вас небольшой или средний проект на PHP или статике, Git‑деплой отлично ложится на ограниченную среду виртуальный хостинг: минимум зависимостей, прозрачная история изменений, простые откаты по тегам. В отличие от rsync/FTP‑загрузок, push в Git гарантирует целостное состояние дерева исходников, а hook доводит процесс до публикации. Если же требуются фоновые демоны, очереди и сборки на сервере — имеет смысл смотреть в сторону VDS.

Ключевая идея: пушим в bare‑репозиторий по SSH — hook автоматически выкатывает целевой бранч в публичную директорию. Никаких ручных шагов на сервере.

Для сравнения сценариев на базе rsync и GitHub Actions см. разбор с практикой в статье https://fastfox.pro/blog/tutorials/php-cicd-github-rsync/.

Предпосылки и ограничения окружения

В виртуальном хостинге обычно доступен SSH, домашняя директория пользователя и современный Git (2.x). Веб‑сервер работает через PHP‑FPM под учётной записью пользователя, поэтому проблем с владельцем файлов меньше, чем на классическом LAMP с общим пользователем веб‑сервера. Однако есть нюансы:

  • Нельзя ставить системные пакеты и изменять глобальные конфиги — рассчитываем только на пользовательские настройки.
  • Нет sudo — любые операции с правами выполняем в пределах своего домашнего каталога.
  • Долгие сборки и тяжёлые бинарники нежелательны. Сборку лучше делать локально или в CI, а на хостинг пушить готовые артефакты.
Виртуальный хостинг FastFox
Виртуальный хостинг для сайтов
Универсальное решение для создания и размещения сайтов любой сложности в Интернете от 95₽ / мес

Архитектура: bare‑репозиторий + post‑receive

Схема простая:

  1. На сервере в домашнем каталоге создаём bare‑репозиторий, например: ~/repos/site.git. Он не содержит рабочего дерева, только объекты и ссылки.
  2. Внутри hooks/post-receive описываем, что делать после пуша: проверить, какой бранч приехал, и развернуть его в целевую директорию (например, ~/www/site).
  3. Локально настраиваем удалённый origin на SSH‑доступ и пушим ветки/теги.

Подготовка локального репозитория

В локальном проекте заведите чистый .gitignore, исключите рабочие директории и приватные файлы (кеши, логи, vendor при локальной сборке, секреты). Для продакшена рекомендуются теги: так проще фиксировать и откатывать релизы.

# локально, пример
git init
git add .
git commit -m "init"
# далее будете добавлять удалённый сервер и пушить

Создание bare‑репозитория на сервере

Подключаемся по SSH к аккаунту виртуального хостинга и создаём каталог под репозитории и целевой путь для кода:

mkdir -p ~/repos/site.git
mkdir -p ~/www/site
cd ~/repos/site.git
git init --bare

Внутренняя структура site.git содержит директории objects, refs и каталог hooks, где и живут сценарии.

Структура bare‑репозитория Git в домашнем каталоге пользователя

Базовый post-receive hook

Этот hook запускается после приёма пуша. Минимальный сценарий: деплоим только когда прилетает целевая ветка (например, main), и выкладываем её в ~/www/site. Важно: файл должен быть с правом исполнения и с переводами строк LF.

# файл: ~/repos/site.git/hooks/post-receive
#!/bin/sh
set -eu

# логирование в файл (в каталоге репозитория)
exec >>"$(dirname "$0")/../logs/post-receive.log" 2>&1 || true

echo "--- $(date '+%F %T') post-receive start"

TARGET_BRANCH="refs/heads/main"
WORKTREE="$HOME/www/site"
GIT_DIR="$HOME/repos/site.git"

# гарантируем, что целевой каталог есть
mkdir -p "$WORKTREE"

# читаем пакеты обновлений из stdin
UPDATED=0
while read oldrev newrev ref
 do
  if [ "$ref" = "$TARGET_BRANCH" ]; then
    UPDATED=1
  fi
done

if [ "$UPDATED" -eq 1 ]; then
  echo "Deploying branch main to $WORKTREE"
  umask 022
  GIT_WORK_TREE="$WORKTREE" git --git-dir="$GIT_DIR" checkout -f main
  # опционально: чистим файлы, которых больше нет в репозитории
  GIT_WORK_TREE="$WORKTREE" git --git-dir="$GIT_DIR" clean -fdx
  echo "Deploy done"
else
  echo "No deploy: branch is not main"
fi

echo "--- $(date '+%F %T') post-receive end"

Не забудьте выдать исполняемый бит и создать каталог логов (если его нет):

chmod +x ~/repos/site.git/hooks/post-receive
mkdir -p ~/repos/site.git/logs

Добавляем удалённый и пушим

Локально привязываем удалённый и проверяем доступ:

# локально
git remote add hosting user@example.com:repos/site.git
# первый пуш
git push -u hosting main

Если всё сделано верно, после пуша hook развернёт содержимое main в ~/www/site. Дальше остается привязать документ‑руткаталог хостинга к этому пути (в панели — соответствующая директория сайта). Не забудьте подключить SSL-сертификаты для домена.

Права и безопасность: что важно на виртуальном хостинге

Тема «права» — частый источник сюрпризов при деплое. На виртуальном хостинге PHP, как правило, исполняется от вашего системного пользователя, поэтому владелец файлов корректный сразу после выкладки. Но всё равно полезно учитывать следующие моменты.

Umask и режимы файлов

В хук установите umask до операций записи. Значение 022 даёт файлы 644 и директории 755, чего достаточно в одиночной команде. Если над проектом работает несколько человек в одной группе и нужен совместный запись, используйте umask 002 и убедитесь, что рабочее дерево имеет корректную группу (и при необходимости установлен бит setgid на директориях).

# внутри hook до checkout
umask 022

Исполняемые файлы

Git сохраняет только один исполняемый бит. Если в проекте есть утилиты, которые должны быть исполняемыми, убедитесь, что они с флагом +x в репозитории. Для PHP‑приложения это актуально редко.

Чистка «хвостов»

Команда git clean -fdx удалит всё, чего нет в репозитории, включая незакоммиченные артефакты. Это обеспечивает предсказуемый деплой, но будьте осторожны: не храните в рабочем дереве секреты и пользовательские данные. Директории с загрузками, кэши и т. п. вынесите за пределы работающего дерева или добавьте в исключения логикой hook.

SSH‑ключи и ограничение доступа

Рекомендуется использовать отдельную ключевую пару для деплоя. На виртуальном хостинге обычно нет возможности прописать командные ограничения в authorized_keys системно, но вы всё равно можете контролировать доступ на уровне аккаунтов и не шарить один ключ между разработчиками. По возможности отключите пароли и оставьте только ключи.

Релизы и откаты: теги и ветки

Чтобы управлять релизами, заведите простую политику:

  • Пуш в main триггерит продакшен‑деплой.
  • Префиксные теги (например, v1.4.2) помечают релизы. Хук может разворачивать не только ветку, но и конкретный тег.

В базовом варианте достаточно придерживаться правила: откат — это git revert или git reset локально и пуш в тот же main. Для аккуратного отката на определённую версию сделайте новый коммит, возвращающий состояние к нужному тегу, либо форс‑пуш, если политика команды это допускает.

Расширение hook для тегов

Если хотите деплоить по тегам, добавьте в хук простую логику: когда прилетает аннотированный тег, развернуть его содержимое. Впрочем, на виртуальном хостинге чаще удобнее держать продакшен на стабильной ветке, а теги использовать только для меток релизов.

Схема деплоя: push, post‑receive hook и выкладка в webroot

Прод и стейдж: несколько рабочих деревьев

Нужно одновременно держать продакшен и тестовый стенд? Разделите их по веткам и целевым директориям. Один bare‑репозиторий — два рабочих дерева:

  • main~/www/site (продакшен)
  • develop~/www/stage (стейдж)

В хук добавьте вторую секцию деплоя по ветке develop. Так вы сможете проверять изменения на поддомене перед выпуском.

FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

Субмодули, артефакты и Composer/NPM

Если проект использует Git‑субмодули, добавьте в хук обновление субмодулей в рабочем дереве. Но учтите, что на виртуальном хостинге сетевые операции в hook могут работать медленно и отъедать лимиты. Практичнее собирать артефакты локально или в CI и пушить уже «толстый» репозиторий: без лишних сетевых шагов на сервере.

То же и с Composer/NPM: без root‑прав и с ограничениями по памяти сборки на стороне хостинга могут быть нестабильны. Безопаснее собрать локально и доставить готовые vendor и скомпилированные бандлы. Не забывайте про корректный .gitignore и размер репозитория.

Типичные ошибки и их диагностика

Hook не запускается

Чаще всего виноваты права или перевод строк. Проверьте, что у файла hooks/post-receive есть +x, а переводы строк LF (не CRLF). Также загляните в лог, если вы его включили в начале скрипта.

«Permission denied» при записи в рабочее дерево

Убедитесь, что хук пишет в каталог, доступный вашему пользователю, и не пересекается с защищёнными путями. На виртуальном хостинге рабочее дерево держите внутри домашнего каталога, например ~/www/site. Проверьте umask и фактические режимы создаваемых файлов.

«Detected dubious ownership» / «unsafe repository»

Такие сообщения появляются при несовпадении владельца и настроек безопасности Git. В bare‑репозитории это редкость, но если вы вызываете Git относительно рабочего дерева, которое создавалось другим пользователем, приведите владельца в порядок или добавьте путь в safe.directory в пользовательском конфиге. На виртуальном хостинге лучше не смешивать пользователей и права групп.

Хук отрабатывает, но сайт не обновляется

Проверьте, что документ‑руткаталог веб‑сервера действительно указывает на директорию, куда выкладывает хук. Убедитесь, что не осталось старых симлинков или копий. Запустите хук вручную для проверки: он обычный shell‑скрипт и может быть исполнен из командной строки с нужными переменными окружения.

Усиление предсказуемости релизов

Даже в базовом варианте можно добавить пару шагов, чтобы релизы были стабильнее:

  • Логирование hook в файл с датой — проще разбирать инциденты.
  • Опциональная валидация composer.json или package.json без установки зависимостей (только синтаксис).
  • Быстрый smoke‑тест: проверка наличия ключевых файлов и прав на запись в директории кэша/загрузок.

Если нужен безостановочный деплой, рассмотрите схему с выкладкой в новую директорию релиза и атомарной сменой симлинка на current. На виртуальном хостинге это чаще всего возможно, но учитывайте квоты по inode и место на диске. Подробнее об атомарном деплое через симлинки — в статье https://fastfox.pro/blog/tutorials/symlink-atomic-deploy/.

Полезные практики для команды

  • Договоритесь, какие ветки деплоятся и куда. Не смешивайте прод и стейдж.
  • Используйте теги для отметки релизов и changelog. Это облегчает откаты.
  • Не храните секреты в репозитории. Конфиги с чувствительными данными держите вне рабочего дерева или используйте шаблоны и переменные окружения, задаваемые на уровне PHP.
  • Проверяйте размер репозитория. На виртуальном хостинге квоты реальны; git gc и аккуратное обращение с бинарниками спасают от сюрпризов.

Итог

Git‑деплой через bare‑репозиторий и post-receive — надёжная и минималистичная стратегия для виртуального хостинга. Она хорошо склеивается с командной разработкой: пуш — это релиз, а проблемы воспроизводимы и диагностируемы логами hook. Начните с базовой схемы на одной ветке, добавьте стейдж при необходимости, стабилизируйте права через umask — и вы получите быстрый, управляемый процесс выката без громоздких инструментов.

Поделиться статьей

Вам будет интересно

mTLS для админок и API на VDS: клиентские сертификаты, ssl_verify_client и ротация OpenAI Статья написана AI Fastfox

mTLS для админок и API на VDS: клиентские сертификаты, ssl_verify_client и ротация

mTLS — способ ограничить доступ к админке и приватному API только доверенным клиентам. В статье: как поднять клиентский CA, выпуск ...
nftables на VDS: современный файрвол, базовые правила, persist и отладка OpenAI Статья написана AI Fastfox

nftables на VDS: современный файрвол, базовые правила, persist и отладка

Кратко о nftables на VDS: почему он удобнее iptables, как быстро собрать базовый файрвол для IPv4/IPv6, сохранить правила через /e ...
PgBouncer на VDS: пулы соединений PostgreSQL, конфиг, лимиты и метрики OpenAI Статья написана AI Fastfox

PgBouncer на VDS: пулы соединений PostgreSQL, конфиг, лимиты и метрики

Почему PgBouncer обязателен на нагруженном VDS с PostgreSQL: пулы соединений экономят память и ускоряют отклик. Разберём установку ...