GitHub + сервер: связка за один вечер

Зачем это нужно

Знакомая картина: код пишется на локалке, а на сервер живёт отдельной жизнью. Правки руками по SSH, «а какая версия сейчас на проде?» — вопрос без ответа, откат — поиск по файлам. Git решает это раз и навсегда: GitHub становится единственным источником правды, а сервер просто забирает оттуда актуальное состояние.

Целевая схема, к которой мы пришли:

text
локалка → git push → GitHub → git pull → сервер

Шаг 1. Ключ доступа с сервера

Серверу нужен свой SSH-ключ для чтения репозитория. Регистрируем его в GitHub как deploy key — ключ даёт доступ к одному репозиторию, а не ко всему аккаунту. Безопасно и достаточно для деплоя.

На сервере:

bash
ssh-keygen -t ed25519 -C "server-deploy"
cat ~/.ssh/id_ed25519.pub

Публичный ключ вставляем на GitHub: Settings → Deploy keys → Add. Затем проверяем связь:

bash
ssh -T git@github.com

Удобно сразу добавить в ~/.ssh/config короткий алиас, чтобы в командах не путаться:

text
Host github-sad
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519

Шаг 2. Сделать папку сайта репозиторием

Если сайт уже работает, а репозитория на нём нет — не нужно ничего клонировать заново. Папка превращается в репозиторий и выравнивается по GitHub:

bash
cd ~/www/pozitivsad.ru
git init
git remote add origin github-sad:логин/репозиторий.git
git fetch origin
git branch -m master main          # если ветка на GitHub называется main
git reset --hard origin/main
git branch --set-upstream-to=origin/main main

Подводный камень: ничего не пострадает. reset --hard перезаписывает только те файлы, которые есть в git. Ваши .env, vendor, storage, загруженные картинки — этого в репозитории нет, значит, тронуться не может. Но бэкап перед первым запуском всё равно делаем, он стоит 30 секунд:

bash
cp -a ~/www/pozitivsad.ru ~/backup_pozitivsad

Шаг 3. Обычный цикл

Всё, дальше — рутина из трёх команд:

Локалка:

bash
git add -A
git commit -m "что изменил"
git push origin main

Сервер:

bash
cd ~/www/pozitivsad.ru && git pull

Сайт на обычном хостинге читает код прямо с диска — никаких пересборок и перезапусков не нужно. Если после пулла Laravel капризничает с кешем:

bash
php artisan config:clear
php artisan cache:clear

Подводные камни

Промежуточные папки не нужны. Клонировать репозиторий в отдельную папку «для начала» — соблазн, который приводит к двум копиям кода на сервере и вечному вопросу «какую из них править». Папка сайта и есть репозиторий.

Править код на сервере — нельзя. Сервер только принимает готовое с GitHub. Если поправили файл прямо на проде — локалка отстала, и рано или поздно git pull затрёт правку или упрётся в конфликт. Заметил баг — правь локально, пуши, пулли.

git status после пулла — привычка. Один взгляд показывает, что на сервере нет случайных правок и репозиторий чист.

Docker — отдельная история. Если сайт работает в контейнерах и код вшивается в образ, то git pull недостаточен — нужен docker compose up -d --build. Но это другая схема развёртывания: у классического хостинга файлы на диске и есть работающий сайт.

Мини-шпаргалка

bash
git init                                   # превратить папку в репозиторий
git remote add origin <адрес>              # привязать GitHub
git fetch origin                           # скачать историю коммитов
git reset --hard origin/main               # выровнять файлы по GitHub
git branch -m master main                  # переименовать ветку
git branch --set-upstream-to=origin/main main   # связать ветки (pull без аргументов)
git pull                                   # забрать обновления (ежедневная команда)

Три вывода

GitHub — единственный источник правды. Что в нём — то и на сервере. Любое расхождение — признак того, что кто-то правил код в обход.

Деплой — это одна команда. git pull на сервере. Всё остальное (commit, push) происходит на локалке, где и место разработке.

Первое настроение важнее скорости. Ключ, алиас в SSH-конфиге, бэкап, привязка веток — делается один раз и навсегда. Дальше только pull.