# CI/CD (Forgejo / Gitea) и деплой на `pvestandt9` Цель: **пуш тега `v*`** → автоматический деплой на сервер; **откат** — повторный запуск workflow с другим тегом. ## Что в репозитории | Файл | Назначение | |------|------------| | `.gitea/workflows/ci.yml` | `pytest` на `push` в `main`, на `push` тегов `v*`, на PR в `main` (см. чеклист ниже). | | `.gitea/workflows/deploy.yml` | На `push` тега `v*`: SSH на сервер → `git checkout` → `docker compose build/up`. | | `Dockerfile` | Образ Python 3.12, `pip install .`, entrypoint: `alembic upgrade` + `uvicorn`. | | `docker-compose.yml` | Сервис `onguard24`, порт `8080`, `env_file: .env`. | | `deploy/entrypoint.sh` | Перед стартом: `alembic upgrade head` (отключить: `SKIP_ALEMBIC=1` в `.env`). | ## Включить Actions в Forgejo 1. Админка инстанса или репозитория: включить **Actions**. 2. Зарегистрировать **runner** с меткой `ubuntu-latest` (или изменить `runs-on` в YAML на вашу метку, например `self-hosted`). 3. Если образы `actions/checkout` недоступны, в настройках Actions задайте зеркало GitHub или используйте встроенные экшены Forgejo (см. документацию вашей версии). ### Образ act_runner (Docker Hub) Используйте **`gitea/act_runner`** (например тег **`nightly`**), а не `docker.gitea.com/...:latest` — последний часто недоступен. ```bash sudo docker pull gitea/act_runner:nightly sudo docker run -d --restart always --name act_runner \ -e GITEA_INSTANCE_URL="https://forgejo.pvenode.ru" \ -e GITEA_RUNNER_REGISTRATION_TOKEN="ТОКЕН_ИЗ_UI" \ -e GITEA_RUNNER_NAME="pvestandt9" \ -e GITEA_RUNNER_LABELS="ubuntu-latest:docker://catthehacker/ubuntu:act-22.04" \ -v /var/run/docker.sock:/var/run/docker.sock \ -v act_runner_data:/data \ gitea/act_runner:nightly ``` Стабильные теги: [hub.docker.com/r/gitea/act_runner/tags](https://hub.docker.com/r/gitea/act_runner/tags). ## Чеклист: CI и Deploy проходят 1. **Runner** зарегистрирован, метка совпадает с `runs-on: ubuntu-latest` в `ci.yml` / `deploy.yml` (или поменяйте `runs-on` на свою метку, например `self-hosted`). 2. **Сеть:** runner может скачивать образы Docker (для job’ов) и при необходимости — **`github.com`** (экшены `actions/checkout`, `actions/setup-python`, `appleboy/ssh-action`). Если Forgejo без выхода в интернет — в админке задайте **зеркало/прокси для Actions** или подставьте полные URL экшенов с вашего зеркала. 3. **CI:** после `push` в `main` или тега `v*` в разделе **Actions** должен быть успешный workflow **CI** (установка Python 3.12, `pytest`). Локально то же самое: `python -m pip install -e ".[dev]" && python -m pytest tests/ -q`. 4. **Deploy:** заданы секреты `DEPLOY_HOST`, `DEPLOY_USER`, `DEPLOY_SSH_KEY`, `DEPLOY_PATH`; с хоста runner выполняется `ssh` на сервер (см. раздел про секреты). Если SSH падает с **host key** — при первом подключении с runner можно зафиксировать отпечаток и добавить в Forgejo секрет (см. раздел «Устранение неполадок»). 5. **На сервере** в `DEPLOY_PATH`: рабочий `git remote`, `docker compose`, без конфликтов портов. ## Секреты репозитория **Настройки репозитория → Actions → Secrets:** | Секрет | Пример | Описание | |--------|--------|----------| | `DEPLOY_HOST` | `pvestandt9` или IP | Хост SSH. | | `DEPLOY_USER` | `root` | Пользователь SSH. | | `DEPLOY_SSH_KEY` | содержимое `id_rsa` | Приватный ключ (весь PEM, многострочный). | | `DEPLOY_PATH` | `/opt/onGuard24` | Каталог **клона git** на сервере (там же `docker-compose.yml`). | Ключ лучше отдельный **deploy key** только на чтение репозитория или полный доступ, если runner делает только `git fetch`. ## Однократная подготовка сервера (`root@pvestandt9`) ```bash ssh root@pvestandt9 apt-get update && apt-get install -y git docker.io docker-compose-v2 # или Docker CE по инструкции вашей ОС mkdir -p /opt/onGuard24 cd /opt git clone https://forgejo.pvenode.ru/admin/onGuard24.git onGuard24 cd onGuard24 ``` Создайте **`/opt/onGuard24/.env`** (как в `.env.example`): `DATABASE_URL`, `HTTP_ADDR` (в контейнере порт задаёт compose; для приложения можно `0.0.0.0:8080`), секреты Grafana и т.д. Настройте **`git remote`** и доступ (`~/.ssh` deploy key или `git credential`), чтобы **`git fetch` без пароля** работал от пользователя, под которым заходит CI (часто `root`). Проверка вручную: ```bash cd /opt/onGuard24 docker compose build && docker compose up -d curl -s http://127.0.0.1:8080/health ``` При необходимости пробросьте порт наружу (nginx, firewall). ## Релиз (деплой новой версии) 1. Закоммитить код, запушить тег: `git tag v1.6.0 && git push origin v1.6.0`. 2. Workflow **Deploy** запустится сам, на сервере обновится код и пересоберётся контейнер. ## Откат версии (простой процесс) 1. В Forgejo: **Actions → Deploy → Run workflow**. 2. В поле **ref** указать **старый тег** (`v1.4.1` или для удобства просто `1.4.1` — workflow добавит `v`). 3. Запустить. На сервере выполнится `checkout` и `reset` на этот ref, затем `docker compose build && up -d`. Убедитесь, что старый тег есть в `origin` (`git push --tags` не удалялся). ## Миграции БД По умолчанию при каждом старте контейнера выполняется **`alembic upgrade head`**. Если нужно отключить (и гонять миграции вручную), в `.env` на сервере: `SKIP_ALEMBIC=1`. ## Устранение неполадок - **`Error: missing server host` / `cd ""` в логе** — в репозитории **не заданы** (или пустые) секреты **`DEPLOY_HOST`**, **`DEPLOY_USER`**, **`DEPLOY_SSH_KEY`**, **`DEPLOY_PATH`**. Задайте их в **Forgejo → репозиторий → Настройки → Actions → Secrets** (имена **точно** как в таблице выше). Workflow теперь падает раньше с явным сообщением, какой секрет пустой. - **SSH: host key verification failed** — runner впервые видит ключ сервера. Варианты: (а) один раз с машины runner выполнить `ssh-keyscan -H ` и настроить доверие в среде act (зависит от образа); (б) в `appleboy/ssh-action` при необходимости задать входной параметр **`fingerprint`** (SHA256), его можно взять так: `ssh-keyscan -t ed25519 2>/dev/null | ssh-keygen -lf -` (на любой машине, которая видит сервер). Пустой `DEPLOY_SSH_KEY` или ключ с Windows-переводами строк (`\r\n`) тоже даёт ошибки SSH — ключ в секрете должен быть PEM целиком, Unix newlines. - **CI: не качается `actions/checkout@v4`** — настройте зеркало GitHub для Actions в Forgejo или замените `uses:` на URL экшена с доступного вам хоста (см. документацию вашей версии Forgejo). - **Runner не берёт job** — проверьте `runs-on` и метки runner. - **SSH fails** — `ssh -i key root@DEPLOY_HOST` с машины runner; `known_hosts` при необходимости добавьте в экшен (расширение `appleboy/ssh-action` / `ssh-keyscan`). - **`git checkout` fails** — выполните на сервере `git fetch --tags` вручную, проверьте remote URL и ключ. - **`fatal: ambiguous argument 'origin/v1.x.x'`** при ручном деплое — у **тегов** нет ref вида `origin/имя-тега`, только `refs/tags/…`. После `git fetch && git checkout v1.x.x` делайте `git reset --hard v1.x.x`, а не `origin/v1.x.x`. В `.gitea/workflows/deploy.yml` это уже учтено (ветка `origin/` только для **веток**). - **База недоступна из контейнера** — в `DATABASE_URL` укажите хост, доступный **из Docker** (не `127.0.0.1` хоста, если БД на хосте — используйте IP хоста или `host.docker.internal` где поддерживается). См. также [VERSIONING.md](VERSIONING.md) и [IRM.md](IRM.md).