Skip to content

This article is available in Russian. An English version is on the way.Open the Russian page

Деплой из Git: push на сервер и GitHub Actions

Три способа доставлять код на сервер: bare-репозиторий с хуком, git pull по deploy-ключу и автоматический деплой из GitHub Actions.

Level
Advanced
Reading time
3 min read
Updated
Tested on
Ubuntu 22.04, Ubuntu 24.04, Debian 12
Contents
  1. Способ 1: push прямо на сервер
  2. Способ 2: git pull по deploy-ключу
  3. Способ 3: GitHub Actions по SSH
  4. Частые ошибки

Копировать файлы вручную долго и ненадёжно. Выберите способ под свой процесс: для личного проекта хватит push на сервер, для команды удобнее деплой из CI.

Способ 1: push прямо на сервер

На сервере создаётся «голый» репозиторий. После каждого push хук post-receive выкладывает код в рабочий каталог и перезапускает приложение.

bash
$ adduser --disabled-password --gecos "" deploy$ mkdir -p /srv/app$ chown deploy:deploy /srv/app$ su - deploy$ git init --bare ~/app.git
/home/deploy/app.git/hooks/post-receive
$ #!/bin/bash$ set -euo pipefail$ TARGET=/srv/app$ BRANCH=main$ while read oldrev newrev ref; do$   if [ "$ref" = "refs/heads/$BRANCH" ]; then$     git --work-tree="$TARGET" --git-dir="$HOME/app.git" checkout -f "$BRANCH"$     cd "$TARGET"$     npm ci --omit=dev$     pm2 reload app$     echo "Deployed $newrev"$   fi$ done
bash
$ chmod +x ~/app.git/hooks/post-receive

На своём компьютере добавьте удалённый репозиторий и отправьте код. Публичный SSH-ключ разработчика должен лежать в /home/deploy/.ssh/authorized_keys.

bash
$ git remote add production deploy@203.0.113.10:app.git$ git push production main

Способ 2: git pull по deploy-ключу

Код лежит на GitHub или GitLab, а сервер забирает его сам. Deploy key даёт доступ только к одному репозиторию и только на чтение — это безопаснее, чем личный ключ.

bash
$ su - deploy$ ssh-keygen -t ed25519 -f ~/.ssh/deploy_app -N "" -C "deploy@server"$ cat ~/.ssh/deploy_app.pub

Добавьте выведенный ключ в настройках репозитория (в GitHub: Settings → Deploy keys, без права записи). Затем укажите ключ для хоста:

/home/deploy/.ssh/config
Host github.com    IdentityFile ~/.ssh/deploy_app    IdentitiesOnly yes
bash
$ git clone git@github.com:you/app.git /srv/app$ cd /srv/app && git pull --ff-only

Способ 3: GitHub Actions по SSH

CI подключается к серверу по отдельному ключу и выполняет команды деплоя. Создайте ключ, положите публичную часть в authorized_keys пользователя deploy, а приватную — в секреты репозитория (Settings → Secrets and variables → Actions) под именем DEPLOY_KEY. Туда же добавьте адрес сервера как DEPLOY_HOST и вывод ssh-keyscan как KNOWN_HOSTS.

bash
$ ssh-keygen -t ed25519 -f ./ci_deploy -N "" -C "github-actions"$ ssh-keyscan -t ed25519 203.0.113.10
.github/workflows/deploy.yml
name: deployon:  push:    branches: [main]jobs:  deploy:    runs-on: ubuntu-latest    steps:      - name: SSH key        run: |          mkdir -p ~/.ssh          echo "${{ secrets.DEPLOY_KEY }}" > ~/.ssh/id_ed25519          chmod 600 ~/.ssh/id_ed25519          echo "${{ secrets.KNOWN_HOSTS }}" > ~/.ssh/known_hosts      - name: Deploy        run: ssh deploy@${{ secrets.DEPLOY_HOST }} 'cd /srv/app && git pull --ff-only && npm ci --omit=dev && pm2 reload app'

Чтобы ограничить CI-ключ, в authorized_keys перед ним можно указать from="адрес" или command="скрипт" — тогда ключ сработает только с нужных адресов или только для одной команды.

Частые ошибки

  • Хук не срабатывает — файл post-receive не исполняемый или ветка называется не так, как в BRANCH.
  • В хуке «command not found» для npm или pm2 — у неинтерактивной оболочки другой PATH. Пропишите полные пути.
  • git pull просит пароль — репозиторий клонирован по HTTPS, а ключ настроен для SSH. Смените адрес: git remote set-url origin git@github.com:you/app.git.

Read to the end and the article counts toward your learning progress.

  • Git
  • деплой
  • CI/CD
  • GitHub Actions
  • deploy key

Was this article helpful?