Уеб AI · 5 мин четене

Цялата инфраструктура в едно GitHub repo, с AI

Три сървъра, десетки приложения, secrets и production deploy в едно git репо, написано предимно от Claude Code. Какво има вътре, кой какво прави и какво ми струва.

Преди около месец преместих всичките си сайтове от Google Cloud на Hetzner. Сметката падна от около 100 € на 34 € на месец, но по-интересното не е цената, а как стана и как го управлявам оттогава: целият сървърен живот е в едно GitHub repo, наречено просто infra, и по-голямата част от него е написана от AI (Claude Code), като аз казвам какво искам, проверявам и давам „да“.

Това е първият пост от поредица. Тук е общата картина; за тайните (SOPS) и за самата инфраструктура ще има отделни постове.

Какво има вътре

Три сървъра в Германия (фронтенд с Docker и Traefik, Postgres, и един за Docker registry, Redis и мониторинга) и десетки приложения: магазини, този блог, OAuth портал, няколко услуги. Всичко, което ги засяга, е в репото:

  • compose файловете на всяко приложение и конфигурацията на Traefik;
  • конфигурацията на Postgres, бекъпите и таймерите им;
  • регистърът, Redis, GlitchTip (грешки и uptime), Grafana с логове и метрики;
  • скриптовете: създаване на сървъри, правилата на защитната стена, смяна на IP, деплой, почистване на стари образи, седмично сканиране на образите за уязвимости;
  • тайните на всеки сървър, криптирани;
  • AGENTS.md: бележките, които AI чете в началото на всяка сесия и допълва в края ѝ, с дати;
  • TODO.md: какво предстои.

Ако утре един сървър изчезне, от репото и от бекъпите той се построява наново по бележките, не по памет.

Ролята на AI

Опитвал съм и преди да си водя документация. Издържа две седмици. Разликата сега е, че документацията се пише от този, който върши работата: след всяка промяна AI записва в AGENTS.md какво е направено, кога и защо, и при следващата сесия тръгва от там. Файлът вече е около 1500 реда и е най-полезното нещо в репото: „защо порт 465 не работи“ (Hetzner блокира изходящите 25 и 465, пращаме през 587), „как се връща приложение назад“, „кой ключ къде е“.

Правилата са прости и са записани в същия файл:

  • нищо в продукция без изрично „да“ от мен: сървъри, firewall, DNS, деплой;
  • никакви тайни в git, освен криптираните;
  • всяка промяна се описва.

Аз чета какво прави и защо. Това е частта, която не може да се делегира: AI пише уверено и когато греши. Но разликата между „да напиша скрипт за ротация на бекъпи“ и „да проверя скрипта, който вече е написан и тестван“ е голяма, и точно тя ми остава.

Тайните: SOPS + age

.env файловете на всеки сървър живеят в репото, криптирани със SOPS и age. Имената на променливите се виждат, стойностите не. Ключове за разкриптиране имам само аз, на сигурно място; сървърите никога не получават ключ. Една команда разкриптира файла на компютъра и го праща по SSH на сървъра му. Git hook и CI отказват да приемат некриптиран .env.

Резултатът: история на всеки secret, бекъп по подразбиране и нулев шанс да комитна парола по погрешка. Заслужава отделен пост, ще го има.

Деплоят: опашка за релийзи

Преди деплоят беше „build на лаптопа, push, ssh, docker compose up“. Сега е една команда:

rel blog 0.2.1

Тя прави подписан git tag и го праща. На сървъра с регистъра един малък Go сервиз следи таговете, проверява подписа (само моите ключове минават), пуска тестовете, прави docker build, сканира образа за уязвимости, качва го в регистъра, деплойва по SSH, проверява сайта и две минути гледа за нови грешки в GlitchTip. Ако нещо се счупи, сам връща предишната версия. Някои приложения имат прозорец (един магазин се деплойва само след 22:00); job-ът чака.

Без GitHub Actions: релийзите не зависят от чужд CI, а подписаният таг е моето „да“. Питах и за готовите инструменти: Komodo, Dockhand и Ansible. Отговорът, който ме убеди: Komodo и Dockhand биха заменили скриптове, които вече работят, и носят свой агент с достъп до Docker socket на всеки сървър плюс уеб интерфейс, който трябва да се пази и обновява. Ansible запълва истинска дупка (да построиш сървър от нулата с една команда), но при три сървъра bootstrap скрипт на сървър върши същото. Всичко, което исках, е около хиляда реда Go и ми е ясно какво прави всеки ред.

Какво получавам

Едно място за всичко. История: git log казва кога и защо е сменен порт, ключ или версия. Спокойствие: бекъпи на три нива, аларми по имейл за пълен диск, спрял бекъп, изтичащ сертификат, паднал сайт. И време: неща, които отлагах с години (мониторинг, сканиране на образи, ротация на тайни), станаха за вечер.

Какво ми струва: трябва да чета. Всеки ден. И трябва да държа бележките чисти, защото AI тръгва от тях и ако там има грешка, тя се повтаря.

Следващият пост: SOPS, с примери.