Моя краткая универсальная инструкция-шпаргалка по автодеплою темы WordPress-сайта с GitHub через cron.
Как выглядит процесс в целом:
- Локально вношу изменения в код темы сайта.
- Делаю коммиты и пушу в GitHub.
- Сервер регулярно по крону проверяет репозиторий.
- Если в нужной ветке есть новый коммит, он подтягивается автоматически.
В репозитории у меня не весь сайт, а только тема. Эта же схема может быть применима и к плагинам.
После настройки этой схемы источник истины – GitHub, поэтому все изменения, которые будут сделаны в теме на сервере, перезатрутся после очередных изменений в репозитории GitHub.
Пошаговая инструкция
В этой инструкции нужно заменять значения этих «заглушек» на свои:
SITEDOMAINTHEME_NAMEGITHUB_USERNAME/GITHUB_REPOSITORY- при необходимости ветка
main
Все команды выыполняются в терминале на сервере под тем же пользователем, от которого размещён сайт.
1. Создать отдельный deploy key
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_github_SITE -C "SITE deploy key"
SITE не забыть заменить на имя проекта (далее по тексту напоминать не буду). Парольную фразу (passphrase) оставить пустой.
2. Добавить SSH alias
nano ~/.ssh/config
Добавить:
Host github-SITE
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_github_SITE
IdentitiesOnly yes
Выставить права:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/config
chmod 600 ~/.ssh/id_ed25519_github_SITE
chmod 644 ~/.ssh/id_ed25519_github_SITE.pub
3. Добавить публичный ключ в GitHub
Показать ключ:
cat ~/.ssh/id_ed25519_github_SITE.pub
Дальше в GitHub открыть репозиторий, перейти в Settings → Deploy keys → Add deploy key, задать какое-нибудь имя и вставить содержимое ключа.
Галочку Allow write access ставить не нужно.
Проверить:
ssh -T git@github-SITE
4. Подготовить папку темы на сервере
Если папка уже есть, но это не git-репозиторий, безопаснее всего:
- Переименовать её в бэкап.
- Заново сделать чистый
git clone.
Пример:
cd /home/admin/web/DOMAIN/public_html/wp-content/themes
mv THEME_NAME THEME_NAME_backup_$(date +%F_%H-%M-%S)
git clone -b main git@github-SITE:GITHUB_USERNAME/GITHUB_REPOSITORY.git THEME_NAME
Почему так лучше: не останется лишних старых файлов, и рабочая папка будет ровно такой, как в GitHub.
Важно: нужно учесть, что если это папка с активной темой, то её переименование «поломает» отображение сайта. Если это критично даже на короткое время, то лучше сделать аккуратнее.
5. Создать deploy-скрипт
Создать файл:
mkdir -p $HOME/bin
nano $HOME/bin/deploy_SITE.sh
Вставить в него содержимое ниже, но ещё раз отдельно упомяну, что нужно:
- заменить
DOMAINиTHEME_NAMEв пути к папке проекта - проверить значения
BRANCHиREMOTE, если вдруг у вас они отличаются - для
TAGвписать своё значение вместоsite
#!/usr/bin/env bash
set -Eeuo pipefail
# Путь к папке проекта
PROJECT_DIR="$HOME/web/DOMAIN/public_html/wp-content/themes/THEME_NAME"
# Лог-файл
LOG="$HOME/deploy.log"
# Ветка и remote
BRANCH="main"
REMOTE="origin"
# Метка проекта в логе
TAG="[site]"
# Весь вывод и ошибки пишем в лог
exec >> "$LOG" 2>&1
# При ошибке пишем в лог, на какой команде всё упало
trap 'CODE=$?; echo "$(date "+%F %T") $TAG error on line $LINENO while running: $BASH_COMMAND (exit code: $CODE)"' ERR
cd "$PROJECT_DIR"
# Явно находим git, это полезно для cron
GIT_BIN="$(command -v git)"
# Обновляем сведения о remote-ветке
$GIT_BIN fetch "$REMOTE" --prune --quiet
# Сравниваем локальный и удалённый commit
LOCAL_HEAD="$($GIT_BIN rev-parse HEAD)"
REMOTE_HEAD="$($GIT_BIN rev-parse "$REMOTE/$BRANCH")"
# Если есть новый commit – жёстко обновляем проект
if [[ "$LOCAL_HEAD" != "$REMOTE_HEAD" ]]; then
$GIT_BIN reset --hard "$REMOTE/$BRANCH" >/dev/null
LATEST_COMMIT="$($GIT_BIN log -1 --pretty='%h %s')"
echo "$(date '+%F %T') $TAG updated to $LATEST_COMMIT"
fi
Сделать исполняемым:
chmod +x $HOME/bin/deploy_SITE.sh
Важный момент: не сохранять скрипт в формате CRLF. Для Linux нужен формат LF. Поэтому редактировать такой .sh-файл в Windows нужно осторожно, а ещё лучше редактировать через командную строку на сервере.
Иначе будет ошибка вида:
/usr/bin/env: «bash\r»: Нет такого файла или каталога
Но если файл уже сохранён неправильно, исправить можно так:
sed -i 's/\r$//' "$HOME/bin/deploy_SITE.sh"
chmod +x "$HOME/bin/deploy_SITE.sh"
6. Проверить скрипт вручную
Запушить какой-нибудь коммит и запустить:
/bin/bash -lc "$HOME/bin/deploy_SITE.sh"
Проверить лог:
tail -n 50 $HOME/deploy.log
7. Добавить cron
Важно: если на сервере работает какая-нибудь панель для управления (допустим, Vesta), то вероятно, что она и управляет cron, поэтому задания нужно ставить тогда через неё.
Открыть cron:
crontab -e
Добавить строку:
* * * * * flock -n /tmp/SITE_deploy.lock -c '/bin/bash -lc "$HOME/bin/deploy_SITE.sh"'
flock нужен, чтобы новый запуск не стартовал, пока не закончился предыдущий.
* * * * * это запуск раз в минуту, можете поставить свой предпочтительный период.
8. Проверить, что cron реально работает
Проверить запись:
crontab -l
Проверить, что указано правильное имя файла. Это частая ошибка.
Проверить сервис cron:
systemctl status cron
После очередного пуша в GitHub в лог должна попасть строка вида:
2026-06-04 23:10:00 [site] updated to abc1234 Commit message
Проверить в логе:
tail -f $HOME/deploy.log
Послесловие
По итогу процесс работы у меня выглядит так:
- Локально развёрнуты в WSL через DDEV мои WordPress-сайты.
- В теме каждого сайта инициализирован git.
- Вношу правки и доработки, коммичу, а когда всё готово и протестировано пушу в GitHub в main.
- Скрипт деплоя на сервере раз в минуту проверяет GitHub и, если видит новые коммиты, синхронизирует изменения.
На мой взгляд, довольно удобная и простая схема для небольших сайтов.