• DevOps
  • Настройка автодеплоя GitHub через SSH

    Введение

    В статье разберём простой и рабочий способ автодеплоя из GitHub на VPS через SSH.

    Он рассчитан на личные проекты и приватные репозитории, когда сервер полностью под вашим контролем, а для деплоя используется один SSH-ключ, добавленный в GitHub-аккаунт.

    Это не универсальное решение для всех случаев, а практичный вариант для соло-разработчика без лишней инфраструктуры.

    Для каких случаев подходит:

    • у вас VPS с внешним SSH-доступом;
    • сервер используется для личных проектов;
    • все репозитории приватные;
    • доступ к GitHub-аккаунту есть только у вас.

    В таком сценарии один ключ для всех проектов — нормальный и управляемый компромисс.

    Когда использовать не стоит:

    • вы работаете в команде;
    • репозитории публичные;
    • нужен раздельный доступ для разных проектов;
    • важны строгие ограничения прав.

    Предполагаемая база

    В предыдущей статье Создание сайта на VPS мы уже:

    • создали пользователя deploy;
    • настроили вход по SSH-ключу;
    • добавили его в группу www-data;
    • подготовили /var/www.

    Важно

    Следующие команды должны выполняться от имени пользователя deploy, а не root и не admin.

    Есть два способа войти под этим пользователем:

    Вариант 1 — если вы уже залогинены под admin

     1sudo -u deploy -i
    

    Вариант 2 — открыть отдельную SSH-сессию

     1ssh deploy@your-server-ip
    

    Почему это обязательный шаг

    Все команды, связанные с:

    • генерацией SSH-ключей
    • клонированием репозитория
    • выполнением git pull
    • запуском деплой-скриптов

    должны выполняться от имени deploy.

    Если сделать это от admin или root:

    • файлы получат другого владельца
    • сломаются права доступа
    • www-data может потерять доступ
    • автодеплой через GitHub Actions начнёт падать
    • придётся вручную чинить chown -R

    Базовая настройка SSH для GitHub

    В этом разделе мы выполняем первичную настройку SSH-доступа к GitHub с сервера.

    ⚠️ Эти шаги выполняются один раз для сервера и пользователя deploy.

    1. Создание SSH ключа для GitHub

    Подробно процесс создания и настройки SSH-ключей разобран в статье Создание SSH-ключей и их настройка.

    Ключ создаётся не на локальном компьютере, а на сервере (под пользователем deploy).

    Создаём ключ без пароля (для автодеплоя это допустимо):

     1ssh-keygen -t ed25519 -f ~/.ssh/github_deploy -C "github_deploy"
    

    В результате появятся файлы:

     1~/.ssh/github_deploy
     2~/.ssh/github_deploy.pub
    

    Устанавливаем права:

     1chmod 600 ~/.ssh/github_deploy
     2chmod 644 ~/.ssh/github_deploy.pub
    

    2. Добавление ключа в аккаунт GitHub

    Открываем содержимое публичного ключа:

     1cat ~/.ssh/github_deploy.pub
    

    Копируем вывод.

    Далее в GitHub:

    Profile SettingsSSH and GPG keysNew SSH key

    Вставляем ключ и сохраняем.

    Теперь сервер имеет доступ ко всем вашим приватным репозиториям.

    3. Создаём файл config

     1nano ~/.ssh/config
    

    Добавляем:

     1Host github.com
     2    HostName github.com
     3    User git
     4    IdentityFile ~/.ssh/github_deploy
     5    IdentitiesOnly yes
    

    Если имя вашего приватного ключа отличается (например id_ed25519, my_deploy_key и т.д.), замените только значение в IdentityFile.
    Остальные строки менять не нужно.

    Устанавливаем права:

     1chmod 600 ~/.ssh/config
    

    Что делает этот конфиг

    • говорит SSH использовать конкретный ключ
    • отключает перебор других ключей (IdentitiesOnly yes)

    4. Проверка подключения

     1ssh -T [email protected]
    

    Если всё корректно, вы увидите сообщение:

     1Hi username! You've successfully authenticated, but GitHub does not provide shell access.
    

    Настройка автодеплоя в репозитории

    Клонирование проекта на сервер

    Перед тем как настраивать автодеплой, репозиторий должен быть один раз клонирован на сервер.

    ⚠️ Клонирование должно выполняться от имени пользователя deploy.

    Переходим в директорию сайта (она должна быть пустой):

     1cd /var/www/example
    

    Клонируем проект по SSH:

     1git clone [email protected]:your-username/your-repository.git .
    

    Обратите внимание на точку в конце команды — это означает клонирование в текущую директорию.

    Проверяем:

     1git status
    

    Если всё корректно, Git покажет текущую ветку.

    Добавление секретов

    На странице GitHub репозитория:

    SettingsSecrets and variablesActionsNew repository secret

    Добавляем:

    • HOST — IP-адрес или доменное имя сервера, к которому выполняется SSH-подключение
    • USERNAME — пользователь на сервере (в нашем случае deploy), от имени которого выполняются команды
    • KEY — содержимое приватного SSH-ключа для подключения к серверу. Это ключ доступа к серверу (настроенный ранее), а не ключ github_deploy, который используется для подключения сервера к GitHub.
    • PORT — SSH-порт сервера (по умолчанию 22, можно удалить port: ${{ secrets.PORT }}, если используется стандартный порт)

    Настройка GitHub Actions

    Теперь на стороне GitHub нужно создать workflow.

    В репозитории создаём файл:

     1.github/workflows/main.yml
    

    Часто его называют по назначению (deploy.yml, production.yml) или по ветке, к которой он относится (main.yml) — для удобства навигации.

    Минимальный пример:

     1name: Deploy (main)
     2
     3on:
     4  push:
     5    branches:
     6      - main
     7
     8concurrency:
     9  group: deploy-main
    10  cancel-in-progress: true
    11
    12jobs:
    13  deploy:
    14    runs-on: ubuntu-latest
    15
    16    steps:
    17      - name: Deploy via SSH
    18        uses: appleboy/ssh-action@v1
    19        with:
    20          host: ${{ secrets.HOST }}
    21          username: ${{ secrets.USERNAME }}
    22          key: ${{ secrets.KEY }}
    23          port: ${{ secrets.PORT }}
    24          script: |
    25            set -e
    26
    27            cd /var/www/example
    28
    29            git fetch origin main
    30            git reset --hard origin/main
    31
    32            composer install
    33            npm run build
    

    Здесь cd /var/www/example нужно указать путь к директории репозитория.

    После git reset --hard origin/main можно добавить любые команды, необходимые для деплоя проекта: установку зависимостей, сборку фронтенда, миграции, очистку кэша и т.д. Все они будут выполнены на сервере последовательно.

    Итог

    Мы настроили минимальный автодеплой через GitHub Actions и пакет appleboy/ssh-action.

    Теперь при каждом push в ветку main:

    • GitHub запускает workflow
    • выполняется SSH-подключение к серверу
    • происходит обновление кода на сервере
    • запускаются команды деплоя (composer, сборка и т.д.)