Gitea Actions не запускаются: причины и решение
Пуш прошёл, а во вкладке Actions пусто — или запуск появился и намертво завис в жёлтом «Waiting». Жалоба «gitea actions не работают» покрывает четыре разные поломки: выключенный модуль, ненайденный workflow, раннер без нужной метки и джоб, упавший на первом шаге. Определим, на каком шаге всё встало, и пройдём слои по порядку.
Содержание
- «Gitea Actions не работают» — это четыре разные поломки
- Actions выключены: три выключателя, а не один
- Workflow не найден: каталог, расширение и молчаливый YAML
- Раннер не зарегистрирован — или зарегистрирован не туда
- Задача висит в Waiting: метки, capacity и мёртвый раннер
- Джоб стартовал и упал: checkout, ROOT_URL и docker.sock
- Какой сервер под Gitea с Actions брать в MAATRIX
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →«Gitea Actions не работают» — это четыре разные поломки
Actions — конвейер из трёх частей: Gitea создаёт запуск, act_runner его забирает, контейнер джоба выполняет шаги. Симптом указывает на звено.
| Что видно в интерфейсе | Где ломается |
|---|---|
| Вкладки Actions в репозитории нет вообще | Модуль выключен глобально или в репозитории |
| Вкладка есть, после пуша список запусков пуст | Workflow не найден или не совпал триггер |
Запуск создан, но висит в Waiting | Нет раннера с нужной меткой либо занят capacity |
Running висит часами, лог пустой | Раннер отвалился, задача ждёт ZOMBIE_TASK_TIMEOUT |
| Первый шаг падает за 5–20 секунд | Раннер жив, ломается окружение джоба |
Смотрим логи:
sudo journalctl -u gitea -n 200 --no-pager | grep -iE 'actions|workflow'
sudo journalctl -u act_runner -n 100 --no-pager
В норме раннер опрашивает Gitea раз в пару секунд. Тишина или повторяющееся Failed to fetch task — он до Gitea не достучался, и правки в workflow ничего не изменят. Третий источник — админка Site Administration → Actions → Runners: метки раннера и статус, Idle — ждёт работу, Offline — молчит дольше минуты.
Actions выключены: три выключателя, а не один
Уровень 1 — конфиг Gitea. В /etc/gitea/app.ini:
[actions]
ENABLED = true
DEFAULT_ACTIONS_URL = github
С Gitea 1.21 ENABLED включён по умолчанию, но при переезде со старой версии в конфиг едет старый ENABLED = false. Проверка — sudo grep -A5 '^\[actions\]' /etc/gitea/app.ini, дальше обязателен sudo systemctl restart gitea: на лету конфиг не перечитывается. В Docker то же задаётся переменной GITEA__actions__ENABLED=true — правка app.ini внутри контейнера при пересоздании затрётся.
Уровень 2 — юнит репозитория. Settings → Advanced Settings → чекбокс Enable Repository Actions: у репозиториев, созданных до включения модуля, он снят.
Уровень 3 — глобальный запрет юнита. Если в секции [repository] осталось DISABLED_REPO_UNITS = repo.actions, чекбокса из второго уровня в интерфейсе не будет вовсе: настройки выглядят нормально, а включить нечего. Признак, что первый уровень в порядке, — раздел Actions в админке виден только при ENABLED = true.
Развернуть за пару минут
Готовый образ на VPS MAATRIX: NVMe, AMD EPYC, root-доступ. Локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Развернуть GiteaWorkflow не найден: каталог, расширение и молчаливый YAML
Gitea ищет файлы в двух каталогах, но не в обоих сразу. Сначала .gitea/workflows/, и если этот каталог непуст, .github/workflows/ не читается вообще. Классика переезда с GitHub: положили .gitea/workflows/lint.yaml для пробы — и старые пайплайны перестали запускаться.
- Расширение только
.ymlили.yaml—ci.yml.disabledигнорируется молча. И файл должен лежать в ветке, куда вы пушите: workflow изfeature/ciна пуш вmainне сработает. - YAML должен парситься. Ошибку Gitea показывает в самом запуске:
workflow is not valid. .gitea/workflows/ci.yaml: yaml: line 14: did not find expected key. Табуляция вместо пробелов даётfound character that cannot start any token; ловите это до пуша черезactionlint.
Файл на месте и валиден, а запуска нет — не совпал триггер:
- Ветка и пути.
on: push: branches: [main]не поймает ни пуш вmaster, ни пуш тега — для тегов нужен ключtags. А фильтрpaths: ['src/**']смотрит на изменённые файлы коммита: правкаREADME.mdне запустит ничего. - Коммит с
[skip ci]. Gitea сверяет сообщение коммита со списком[actions] SKIP_WORKFLOW_STRINGS, где по умолчанию[skip ci],[ci skip],[no ci],[skip actions],[actions skip]. Одна такая строка в сообщении мержа — и «Actions сломались». - Пуш, сделанный самим Actions. Коммит, отправленный встроенным
GITEA_TOKEN, нового запуска не порождает: защита от рекурсии, настройкой не отключается. Нужна цепочка — заводите токен бота. scheduleиworkflow_dispatch. Расписания читаются только из ветки по умолчанию. А кнопкаRun workflowпоявилась в Gitea 1.24: на старых сборках workflow с единственнымworkflow_dispatchзапустить нечем.
Раннер не зарегистрирован — или зарегистрирован не туда
Gitea сама ничего не выполняет: без act_runner запуски копятся в очереди вечно. Токен регистрации выпускается в Site Administration → Actions → Runners → Create new Runner, и здесь важна область токена: из админки он даёт раннера всему инстансу, а со страницы репозитория Settings → Actions → Runners — только ему. Зарегистрировали раннера на team/app, а ждёте сборок в team/api — задачи там будут висеть в Waiting вечно.
cd /var/lib/act_runner
sudo -u act_runner /usr/local/bin/act_runner register --no-interactive \
--instance https://git.example.com \
--token <REGISTRATION_TOKEN> \
--labels 'ubuntu-latest:docker://gitea/runner-images:ubuntu-latest'
Команда создаёт файл .runner в текущем каталоге — с идентификатором и постоянным токеном. Отсюда две поломки: systemd стартует демон из другого WorkingDirectory и .runner не находит, либо файл принадлежит root, а сервис ходит от act_runner. Рабочий юнит:
[Service]
User=act_runner
WorkingDirectory=/var/lib/act_runner
ExecStart=/usr/local/bin/act_runner daemon --config /etc/act_runner/config.yaml
Типовые строки в логе раннера:
| Строка в логе | Причина |
|---|---|
Failed to ping the Gitea instance server: connection refused | не тот адрес или закрытый порт |
x509: certificate signed by unknown authority | самоподписанный сертификат Gitea |
unknown method ... / Unimplemented | act_runner старше, чем Gitea |
token is invalid при register | токен использован или из другой области |
Сертификат лечится CA в /usr/local/share/ca-certificates/gitea-ca.crt плюс sudo update-ca-certificates, а не флагом insecure: true: он снимает проверку целиком, а по этому каналу ездит постоянный токен раннера. И держите версии парой: обновили Gitea — обновите act_runner.
Задача висит в Waiting: метки, capacity и мёртвый раннер
Запуск создан, раннер Idle, задача не двигается. Gitea не отдаёт её «любому свободному» — она ищет раннера с меткой, дословно равной значению runs-on. Для планировщика ubuntu-latest и ubuntu-22.04 — разные строки, self-hosted и Self-Hosted тоже. Формат метки — <имя>[:<схема>[:<аргумент>]], схема определяет, где выполнится джоб:
| Метка | Что происходит |
|---|---|
ubuntu-latest:docker://gitea/runner-images:ubuntu-latest | джоб в контейнере из этого образа |
ubuntu-latest:host | джоб прямо на хосте, без изоляции |
ubuntu-latest (схема опущена) | то же, что :host |
Метка без схемы — частая причина «запустилось и сразу упало»: на хосте нет Node.js, а actions/checkout написан на JS, и шаг умирает с exec: "node": executable file not found in $PATH. Ставьте Node 20+ или возвращайте docker://.
Метки правятся в /etc/act_runner/config.yaml — перерегистрация не нужна, конфиг перекрывает записанное при регистрации:
runner:
capacity: 2
labels:
- "ubuntu-latest:docker://gitea/runner-images:ubuntu-latest"
container:
network: gitea_default
docker_host: "-"
После sudo systemctl restart act_runner метки обновятся в админке. Ещё два сценария:
capacity: 1. Раннер берёт одну задачу за раз: матрица из четырёх job'ов выглядит как «зависло», хотя всё работает. Ставьтеcapacityпо числу vCPU, не выше.- Раннер умер посреди задачи. Статус останется
RunningдоZOMBIE_TASK_TIMEOUT— по умолчанию 10 минут. Параметр живёт в[actions]рядом сENDLESS_TASK_TIMEOUT = 3hиABANDONED_JOB_TIMEOUT = 24h.
Джоб стартовал и упал: checkout, ROOT_URL и docker.sock
Дошло до Running и умерло на первых секундах — проблема в окружении джоба.
Действие не скачивается. actions/checkout@v4 раннер тянет с github.com:
Error: unable to resolve action `actions/checkout@v4`, unable to find version `v4`
Источник задаёт [actions] DEFAULT_ACTIONS_URL: с версии 1.20 у него ровно два значения — github и self (ваш инстанс), произвольный URL не принимается. Обход без правки конфига — полный адрес в uses: https://gitea.com/actions/checkout@v4.
ROOT_URL с localhost. checkout клонирует по адресу, который Gitea сообщает раннеру, — по [server] ROOT_URL. Осталось http://localhost:3000/ — джоб пойдёт в localhost собственного контейнера:
fatal: unable to access 'http://localhost:3000/team/app.git/': Failed to connect to localhost port 3000: Connection refused
Лечение — внешний ROOT_URL = https://git.example.com/ и рестарт Gitea.
Контейнер джоба не видит Gitea. Когда Gitea и раннер живут в одном docker compose, джоб-контейнер поднимается в сети bridge и имя gitea не резолвит: could not resolve host: gitea. Пропишите общую сеть в container.network — её имя покажет docker network ls.
Docker-сокет. Раннеру с меткой docker:// нужен доступ к демону:
permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock
Пользователя раннера — в группу, обязательно с перезапуском: sudo usermod -aG docker act_runner && sudo systemctl restart act_runner. Честно: группа docker равносильна root на хосте, поэтому раннер, собирающий чужой код из pull request'ов, лучше держать на отдельной машине.
Реверс-прокси. Раннер держит длинный опрос задач, и Nginx с дефолтными таймаутами рвёт соединение — в логе context deadline exceeded. Нужны proxy_read_timeout 600s;, proxy_buffering off; и client_max_body_size 512m;: без последнего артефакт падает с 413 Request Entity Too Large. А сам actions/upload-artifact@v4 требует Gitea 1.22+.
Какой сервер под Gitea с Actions брать в MAATRIX
Gitea в покое скромна: 150–250 МБ RSS. Всё меняется рядом с act_runner: демон ест 30–50 МБ, но каждый джоб поднимает контейнер, а образ gitea/runner-images:ubuntu-latest занимает около 3 ГБ распакованным — плюс кэш сборки и растущий /var/lib/docker.
Минимум: 2 vCPU, 4 ГБ RAM, 60 ГБ NVMe. Gitea, PostgreSQL и один раннер с capacity: 1. Честное ограничение: на 1 vCPU и 2 ГБ сама Gitea живёт прекрасно, но первая же сборка Node-проекта упирается в память — и вы получаете не ошибку CI, а Killed от OOM-киллера посреди npm ci.
Комфортный вариант: 4 vCPU, 8 ГБ RAM, 120–160 ГБ NVMe. Помещаются capacity: 2–4, параллельная матрица и еженедельный docker system prune -af --filter "until=168h" вместо аврала «no space left on device». Тяжёлые сборки лучше вынести на отдельную машину, чтобы Gitea не подтормаживала на git push. И следите за хранением: логи задач лежат в /var/lib/gitea/data/actions_log, артефакты — в actions_artifacts, а сроки по умолчанию щедрые — LOG_RETENTION_DAYS = 365.
Локация — UK, Лондон. Причина прикладная: раннеру нужен беспрепятственный доступ к github.com, ghcr.io и Docker Hub, иначе вы получите ровно тот unable to resolve action из предыдущего раздела. Из Лондона реестры отвечают штатно, RTT до Москвы — 45–60 мс, для git push незаметно, а до команды в ЕС пинг минимальный, плюс европейская юрисдикция. Если разработчики только в России и внешние реестры не нужны — берите RU-площадку с пингом 5–15 мс.
Gitea из каталога apps.maatrix.io ставится автоматически при заказе: вставлять команды не нужно, автоустановка работает на Ubuntu и Debian, доступы появляются в личном кабинете, в разделе «Доступ». Остаётся выпустить токен регистрации и поднять act_runner под свои метки — этот шаг осознанно ваш, метки зависят от пайплайнов. Выбрать конфигурацию можно сразу под задачу; оплата — картой российского банка, по СБП, криптой или токеном MAAT.
Если Gitea ещё не стоит — установка и настройка; прочие грабли — в частых ошибках Gitea, а память — в требованиях к серверу.
Развернуть за пару минут
Готовый образ на VPS MAATRIX: NVMe, AMD EPYC, root-доступ. Локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Развернуть GiteaОбсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Частые вопросы
Вкладка Actions есть, раннер Idle, а задача висит в Waiting.
Смотрите метки: откройте раннера в Site Administration → Actions → Runners и сверьте их с runs-on — совпадение должно быть посимвольным. Второй кандидат — capacity: 1, когда предыдущая задача ещё выполняется.
Перенёс репозиторий с GitHub, workflow в .github/workflows не запускаются.
Проверьте, нет ли каталога .gitea/workflows: если он существует и непуст, Gitea читает только его. Либо перенесите все файлы в .gitea/workflows, либо удалите каталог .gitea.
Можно ли обойтись без доступа к github.com с сервера?
Да, но действия придётся зеркалировать: скопируйте actions/checkout и остальные нужные репозитории в организацию actions на своём Gitea и поставьте DEFAULT_ACTIONS_URL = self. Точечный вариант — полный адрес в uses.
Нужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.