Главная / База знаний / Git на сервере: базовые команды и деплой через git pull
инструкция · 5 октября 2026

Git на сервере: базовые команды и деплой через git pull

Разбираем команды Git, которые реально нужны при работе с сервером, простую схему деплоя через git pull, права доступа после обновления файлов и что делать, если в репозиторий попал секрет.

Git на сервере: не тот же набор задач, что при разработке

Работа с Git на production-сервере отличается от повседневной работы разработчика в IDE — здесь редко создают ветки, почти никогда не делают коммиты и не разрешают сложные конфликты слияния. Типичный набор операций на сервере узкий: получить актуальную версию кода, посмотреть, что изменилось, и, если что-то пошло не так, откатиться к рабочей версии.

Эта статья не претендует на полный курс по Git — она разбирает именно тот минимальный, но абсолютно необходимый набор команд, который реально используется при управлении сервером, простейшую схему деплоя через git pull, типичные проблемы с правами доступа после обновления файлов и отдельно — серьёзный вопрос о секретах, случайно попавших в репозиторий.

Если процесс деплоя на вашем проекте уже перерос простой git pull и требует автоматического тестирования перед выкладкой — соответствующий следующий шаг разобран отдельно в статье про CI/CD с GitHub Actions.

Базовые команды: то, что реально используется на сервере

git clone разворачивает копию удалённого репозитория в новую директорию — эта команда выполняется на сервере обычно один раз, при первом развёртывании проекта.

Клонирование репозитория в целевую директорию на сервере
git clone git@github.com:acme/site.git /var/www/example.ru

git status показывает текущее состояние рабочей директории — какие файлы изменены, добавлены или не отслеживаются Git; на сервере эта команда — первое, что стоит выполнить перед любым git pull, чтобы убедиться, что в рабочей копии нет случайных незакоммиченных правок, которые могли бы конфликтовать с обновлением.

Проверка состояния, просмотр последних 10 коммитов и различий с предыдущим коммитом
git status
git log --oneline -10
git diff HEAD~1

git log --oneline даёт компактный список последних коммитов с их короткими хешами — полезно, когда нужно точно понять, какая версия кода сейчас развёрнута на сервере, особенно если несколько человек имеют доступ к деплою и нужно быстро восстановить хронологию изменений.

Временный откат рабочей директории к конкретному коммиту по его хешу
git checkout a1b2c3d

git checkout по хешу коммита переводит рабочую директорию в состояние на момент этого коммита — удобно для быстрого аварийного отката на сервере, если только что задеплоенная версия оказалась нерабочей, хотя для регулярного использования правильнее откатывать сам код в репозитории (через revert) и потом уже деплоить исправленную версию, а не оставлять сервер в отсоединённом (detached HEAD) состоянии надолго.

.gitignore: что не должно попадать в репозиторий

Не каждый файл проекта должен отслеживаться Git — сгенерированные зависимости, временные файлы и, что особенно важно, файлы с секретами конфигурации не место в истории репозитория. Список исключений задаётся файлом .gitignore в корне проекта.

Минимальный .gitignore для типичного PHP- или Node.js-проекта
# PHP-проект
/vendor/
.env
*.log
/storage/cache/

# Node.js-проект
/node_modules/
.env
npm-debug.log*
/dist/

Директория vendor (для PHP) или node_modules (для Node.js) полностью восстанавливается из composer.lock или package-lock.json соответствующей командой установки зависимостей — хранить её в Git избыточно и раздувает репозиторий без какой-либо пользы для воспроизводимости.

Файл .env, содержащий пароли от базы данных, ключи внешних API и другие секреты конкретного окружения, — самый важный пункт этого списка: в отличие от кода, значения в .env различаются между разработкой, staging и production, и попадание production-секретов в общий репозиторий, доступный, например, всей команде разработки, превращает утечку доступа во внутренний, а не только внешний риск.

Важная деталь: .gitignore действует только на файлы, которые Git ещё не отслеживает. Если .env был закоммичен раньше, а правило в .gitignore добавлено уже потом, файл продолжит отслеживаться — его нужно явно убрать из индекса командой git rm --cached .env, и только после этого правило .gitignore начнёт применяться к нему в будущих коммитах.

Простейшая схема деплоя: git pull на сервере

Для небольшого проекта без сложного CI/CD-пайплайна вполне рабочая схема деплоя — зайти на сервер по SSH и выполнить git pull в директории проекта, после чего перезапустить нужные сервисы (PHP-FPM, менеджер процессов Node.js).

Минимальный ручной деплой: обновление кода, зависимостей и перезапуск PHP-FPM
cd /var/www/example.ru
git pull origin main
composer install --no-dev --optimize-autoloader
systemctl restart php8.3-fpm

Эту последовательность легко оформить одним shell-скриптом, чтобы не выполнять команды по одной вручную каждый раз, а вызывать единой командой deploy.sh — это снижает риск человеческой ошибки вроде забытого шага установки зависимостей после обновления кода.

Скрипт deploy.sh с обновлением кода, зависимостей, прав доступа и перезапуском сервиса
#!/bin/bash
set -e
cd /var/www/example.ru
git pull origin main
composer install --no-dev --optimize-autoloader
chown -R www-data:www-data /var/www/example.ru
systemctl restart php8.3-fpm
echo "Деплой завершён: $(git rev-parse --short HEAD)"

Директива set -e в начале скрипта останавливает выполнение при первой же ошибке любой из команд — без неё, например, неудачный git pull из-за проблем сети не остановит скрипт, и composer install продолжит выполняться уже поверх старого кода, создавая ложное впечатление успешного деплоя.

Такой скрипт можно запускать вручную по SSH, привязать к cron-задаче с определённым интервалом (менее удобно, так как деплой происходит не в момент реального обновления кода, а по расписанию) или вызывать через веб-хук — небольшой обработчик на сервере, который GitHub или GitLab дёргает автоматически при пуше в нужную ветку, инициируя git pull сразу после появления новых коммитов без участия человека.

Права доступа после git pull: частая практическая проблема

git pull по умолчанию создаёт и изменяет файлы от имени того пользователя, под которым выполняется команда — обычно это личная учётная запись администратора, использующего SSH для подключения к серверу. Веб-сервер и PHP-FPM при этом чаще всего работают от отдельного системного пользователя (www-data, nginx или аналогичного), которому нужны права на чтение (а иногда и запись, например для директории загрузок) этих же файлов.

Если после git pull не привести владельца файлов в соответствие с пользователем веб-сервера, результат бывает разным в зависимости от конкретной настройки: от полностью рабочего сайта (если группа доступа настроена достаточно широко) до ошибок доступа к отдельным файлам или полной невозможности PHP-FPM прочитать обновлённый код.

Приведение владельца и прав доступа файлов проекта к пользователю веб-сервера после обновления
chown -R www-data:www-data /var/www/example.ru
find /var/www/example.ru -type d -exec chmod 755 {} \;
find /var/www/example.ru -type f -exec chmod 644 {} \;

Правильная практика — не выполнять этот шаг вручную после каждого git pull (что легко забыть), а включить его как обязательный этап в сам скрипт деплоя, как показано в предыдущем разделе, так что права доступа автоматически приводятся в порядок при каждом обновлении кода без дополнительных действий со стороны того, кто запускает деплой.

Отдельная деталь: директории, куда приложение само пишет во время работы (загруженные пользователями файлы, кэш, логи), должны оставаться доступными на запись пользователю веб-сервера и после git pull — если такая директория случайно попадёт под общий chown с ограничивающими правами 644 для файлов внутри неё, приложение перестанет мочь писать новые файлы в неё, хотя сам код при этом обновится без видимых ошибок.

Когда git pull перестаёт быть достаточным решением

Прямой git pull на боевом сервере хорошо работает для небольших проектов с редкими обновлениями и невысокими требованиями к отказоустойчивости самого процесса деплоя. По мере роста проекта у этой схемы проявляются ограничения, о которых стоит знать заранее.

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

Ещё одно ограничение — отсутствие автоматической проверки, что обновляемый код вообще работает, перед тем как он окажется на продакшне: git pull применяет любые коммиты из указанной ветки без какой-либо проверки, был ли код протестирован. Решение этой проблемы — вынесение тестирования в отдельный автоматизированный этап перед деплоем, что подробно разобрано в статье про CI/CD с GitHub Actions.

Секреты в репозитории: почему это серьёзная ошибка

Коммит файла .env, файла с приватным ключом или любого другого файла с реальными паролями и токенами доступа — одна из самых распространённых и при этом самых опасных ошибок в работе с Git. Проблема не ограничивается тем, что файл виден в текущем состоянии репозитория.

Git не забывает — однажды закоммиченный файл остаётся доступным через историю репозитория даже после того, как его удалили последующим коммитом; единственный надёжный способ убрать секрет из истории — считать его скомпрометированным и заменить.

Общепринятая практика реагирования на утечку секретов через систему контроля версий

Даже если репозиторий приватный и доступен только внутренней команде, риск не исчезает: список людей с доступом к репозиторию меняется, доступ к клонированным копиям на локальных машинах разработчиков не всегда так же строго контролируется, как доступ к самому production-серверу, а при случайном или намеренном изменении видимости репозитория (например, при переносе в другую организацию на GitHub) исторические коммиты остаются доступны вместе со всем содержимым.

Простое удаление файла последующим коммитом (git rm .env && git commit) не решает проблему — файл продолжает существовать в истории и доступен любому, кто выполнит git log и посмотрит на более ранние коммиты или просто скачает файл конкретной ревизии командой git show.

Единственно правильная последовательность действий при обнаружении утечки: во-первых, немедленно считать все секреты в утёкшем файле скомпрометированными и сменить их — новые пароли к базе данных, перевыпущенные ключи API, новые токены доступа; во-вторых, уже после смены реальных значений, при желании почистить историю репозитория инструментами вроде git filter-repo, что решает проблему на будущее, но никак не отменяет факт, что старые (теперь уже недействительные) значения кто-то мог успеть увидеть.

Веб-хук как альтернатива ручному деплою

Промежуточный шаг между полностью ручным git pull по SSH и полноценным CI/CD-пайплайном — веб-хук, автоматически запускающий скрипт деплоя на сервере сразу после пуша в нужную ветку, без участия человека и без необходимости заходить на сервер вручную для каждого обновления.

Механизм простой: на сервере поднимается небольшой обработчик (отдельный лёгкий HTTP-сервис или обработчик внутри уже существующего веб-сервера), слушающий определённый путь; GitHub или GitLab при пуше в репозиторий отправляет на этот путь POST-запрос с информацией о коммите, и обработчик в ответ запускает уже знакомый скрипт deploy.sh.

Важная деталь безопасности такой схемы — проверка подписи входящего запроса (GitHub и GitLab подписывают тело запроса секретным ключом, заданным при настройке веб-хука), чтобы обработчик не запускал деплой по любому произвольному запросу на этот URL, а только по запросу, действительно пришедшему от настроенного репозитория.

Для проектов, где уже используется тестирование перед деплоем, установка зависимостей на отдельном шаге сборки или деплой сразу на несколько серверов, веб-хук на голом shell-скрипте быстро становится тесен — это естественная граница, за которой имеет смысл переходить на полноценный CI/CD-пайплайн, разобранный в отдельной статье.

Резервная копия перед обновлением: страховка на случай неудачного деплоя

Git сам по себе не заменяет резервное копирование — история коммитов защищает код проекта, но ничего не знает о содержимом базы данных, загруженных пользователями файлах или содержимом .env, которые обновление кода может затронуть косвенно, например через миграцию структуры базы данных, идущую вместе с новым релизом.

Перед деплоем, вносящим изменения в структуру базы данных, разумная практика — сделать её резервную копию отдельно от самого шага git pull, чтобы в случае неудачной миграции откат состоял не только из возврата к предыдущему коммиту кода, но и из восстановления базы данных к согласованному с этим кодом состоянию.

Быстрый бэкап базы данных прямо перед обновлением кода на сервере
mysqldump -u backup_user -p myapp | gzip > /backups/pre-deploy_$(date +\%Y\%m\%d_\%H\%M).sql.gz
git pull origin main

Полноценная стратегия резервного копирования (регулярные автоматические копии, хранение вне самого сервера, проверка восстановления) выходит за рамки одного лишь процесса деплоя и разобрана отдельно — но даже простой ручной дамп базы данных перед деплоем, вносящим изменения в её структуру, снимает значительную часть риска, связанного с миграциями схемы.

Чек-лист безопасного git-деплоя

Шаг 1. Настройте .gitignore для vendor/node_modules, .env и любых временных или сгенерированных файлов ещё до первого коммита проекта.

Шаг 2. Разворачивайте проект на сервере через git clone по SSH-ключу, а не по логину и паролю к репозиторию.

Шаг 3. Оформите последовательность git pull, установки зависимостей, приведения прав доступа и перезапуска сервисов единым скриптом deploy.sh с set -e.

Шаг 4. Убедитесь, что права на файлы после деплоя принадлежат пользователю веб-сервера, а не личной учётной записи администратора.

Шаг 5. Никогда не коммитьте .env и другие файлы с реальными секретами — используйте .env.example с пустыми плейсхолдерами вместо реальных значений.

Шаг 6. Если секрет всё же попал в репозиторий — немедленно смените его реальное значение, а не ограничивайтесь удалением файла новым коммитом.

Итог: простая схема, которая закрывает 80% практических задач

Git pull на сервере — не самая элегантная схема деплоя, но для многих проектов её более чем достаточно: она проста в настройке, понятна любому, кто хоть немного знаком с Git, и не требует поддержки отдельной CI/CD-инфраструктуры.

Главное — соблюдать базовую дисциплину: не хранить секреты в репозитории, приводить права доступа в порядок после каждого обновления и оформлять деплой единым скриптом, а не набором команд, набираемых вручную каждый раз из памяти. Эти простые правила закрывают подавляющее большинство практических проблем, с которыми сталкиваются на этой схеме.

Если проект перерос простой git pull и нужна автоматизация тестирования и деплоя — следующий логичный шаг разобран в статье про CI/CD с GitHub Actions. Если же нужна помощь с настройкой деплоя на конкретном сервере — оставьте заявку внизу страницы.

почему мы

Почему стоит выбрать нас

Быстрый запуск

Подберём конфигурацию и развернём проект в день обращения.

Надёжность

NVMe-диски, защита от DDoS и резервные копии по расписанию.

Поддержка 24/7

Дежурные инженеры на связи в любое время суток.

Настройка под ключ

Установим CMS, настроим веб-сервер, SSL и почту за вас.

Перенос без простоя

Аккуратно перенесём сайт и базу данных на новый сервер.

Прозрачные цены

Актуальные тарифы и честный подбор без навязывания.

частые вопросы

Вопросы и ответы

Чем git pull отличается от git fetch?

git fetch скачивает изменения из удалённого репозитория, но не применяет их к текущей рабочей копии, тогда как git pull — это фактически fetch с последующим автоматическим слиянием (merge) изменений в текущую ветку; для сервера, где нужно сразу получить актуальный код, используется именно pull.

Можно ли просто скопировать файлы на сервер вместо git pull?

Технически можно, но это лишает возможности быстро откатиться к предыдущей версии, теряет историю изменений на самом сервере и усложняет диагностику, какая именно версия кода сейчас развёрнута — git pull даёт всё это почти бесплатно при минимальной настройке.

Что делать, если после git pull изменённые файлы принадлежат не тому пользователю?

Явно указать владельца после обновления командой chown -R www-data:www-data /путь/к/проекту (или другого пользователя, от которого работает веб-сервер) — это стоит делать автоматически как часть скрипта деплоя, а не забывать вручную после каждого обновления.

Можно ли деплоить продакшн прямо из ветки main без промежуточных шагов?

Можно для небольших проектов, но правильнее иметь хотя бы минимальный процесс — тестирование перед мержем в main и, желательно, отдельную ветку или окружение для staging, чтобы изменения проверялись перед попаданием на боевой сервер.

Что произойдёт, если в рабочей директории на сервере есть незакоммиченные изменения при git pull?

Git откажется выполнять pull с сообщением о конфликте, если изменения затрагивают те же строки, что обновляются из удалённого репозитория — на сервере таких локальных правок в принципе не должно быть, любая ручная правка файлов проекта в обход Git на продакшне считается плохой практикой.

Достаточно ли удалить .env из репозитория новым коммитом, если он туда случайно попал?

Нет — файл останется в истории Git и будет доступен через git log и просмотр старых коммитов сколько угодно долго; единственно надёжное решение — считать все секреты в этом файле скомпрометированными и немедленно их сменить (сменить пароли, перевыпустить ключи API), а уже потом чистить историю репозитория.

Как посмотреть, что именно изменилось в файле перед коммитом?

Командой git diff для ещё не добавленных в индекс изменений или git diff --staged для уже добавленных через git add — обе команды показывают построчные различия между текущим состоянием файла и последним коммитом.

Нужно ли добавлять в .gitignore файлы, которые уже закоммичены в репозиторий?

.gitignore не действует на уже отслеживаемые Git файлы — их сначала нужно явно убрать из индекса командой git rm --cached, и только после этого правило в .gitignore начнёт работать и предотвратит повторное попадание файла в будущие коммиты.

Как оплачивать услуги?

Оплата помесячная, для облачных серверов доступна почасовая тарификация. Принимаются карты, банковские переводы и электронные кошельки.

Есть ли круглосуточная поддержка?

Да, дежурные инженеры на связи 24/7.

Выдаёте ли закрывающие документы?

Да, предоставим необходимые документы для оплаты.

Как оставить заявку?

Заполните форму на странице или нажмите «Заказать» — мы свяжемся и поможем с подбором.

заявка

Оставьте заявку

Ответим и поможем с подбором и настройкой.