# Personal Infrastructure Репозиторий моей личной инфраструктуры: VPN, git-хостинг, автоматизация, реверс-прокси и всё, что будет добавляться дальше. Цель — держать в одном месте всё, что нужно, чтобы развернуть любой узел с нуля. Принципы: - **Docker — предпочтительный способ развёртывания.** Если можно завернуть в compose — заворачиваем. - **Репозиторий — единственный источник правды.** На самих серверах ничего уникального жить не должно: все конфиги, compose-файлы, скрипты, артефакты, `.env` — в git. Сервер тянет нужную папку и поднимает её. - **Секреты тоже в репо.** `.env` с паролями коммитим вместе с остальным (репо приватный). Приватные ключи (`ssh/tunnel_key` и т.п.) — туда же, как файлы рядом с compose. ## Структура репозитория ``` servers/ inventory.yml # источник правды о парке серверов / # одна папка на сервер, имя совпадает с inventory.servers[].name docker-compose.yml # compose этого узла .env # переменные окружения узла (включая пароли) / # конфиги конкретных сервисов (xray, nginx, ...) ssh/ # ключи и прочие чувствительные файлы domains.yml # источник правды о DNS-записях для всех доменов CLAUDE.md # этот файл — обзор и правила README.md ``` `servers/inventory.yml` — реестр узлов: имена, адреса, роли, локации, ssh-настройки, список сервисов. Любые ответы про «какой сервер», «где что крутится», «какой у него IP» берём оттуда. `domains.yml` — реестр DNS-записей. Для каждого домена перечислены все нужные записи (A, CNAME, TXT, MX и т.п.) с указанием либо узла из inventory (`server: ` — IP подтягивается), либо буквального значения (`value: ...`). Состояние DNS у регистратора должно совпадать с этим файлом. Папка `servers//` содержит всё, что нужно для развёртывания этого узла. Имя папки = `name` в inventory. ## Где что прописывать при изменениях **Добавили новый сервер:** 1. Запись в `servers/inventory.yml` (name, host, role, env, location, tags, services). 2. Папка `servers//` с `docker-compose.yml` и `.env`. 3. Если узлу нужен домен — добавить записи в `domains.yml` и прописать их у регистратора. 4. Если узел упоминается смысловой ролью (например, тут есть бэкенд для другого узла) — обновить соответствующие compose/конфиги, ссылаясь на роль, а не IP. **Добавили сервис на существующий сервер:** 1. Сервис в `servers//docker-compose.yml`. Внешние — через traefik-метки (`traefik.http.routers..*`) с хостом из `.env`. Внутренние — только в сети `internal`. 2. Конфиги сервиса — в `servers///`, монтировать в контейнер read-only. 3. Новые переменные — в `.env` узла. В compose использовать `${VAR}`, не хардкодить. 4. Запись `services: [...]` у узла в `inventory.yml`. 5. Если сервис публикуется наружу — DNS-запись в `domains.yml` и у регистратора. **Изменили IP / переехали:** 1. Только `inventory.yml` (поле `host`). Compose-файлы IP не содержат — там ссылки на сервисы по имени или на роли. 2. Проверить `domains.yml`: записи со ссылкой `server: ` подтянут новый IP автоматически — но у регистратора надо обновить вручную. **Добавили / изменили домен:** 1. Запись в `domains.yml`: блок `domains` для домена, нужные `records`. Для записей, указывающих на наш узел — `server: `, иначе `value: <строка>`. 2. Синхронизировать у регистратора. Состояние DNS должно совпадать с файлом. **Добавили секрет:** 1. В `.env` узла либо как файл в `servers//ssh/` (или аналогичной служебной папке). 2. Никогда не хардкодить в compose или конфиг-файлах — только через `${VAR}` или монтируемый файл. **Удалили сервис / сервер:** 1. Убрать запись из `inventory.yml` (или из `services` узла). 2. Удалить соответствующий блок из compose и папку с конфигами. ## Конвенции - Адреса серверов — только в `inventory.yml`. В compose и доках ссылаемся на роли (`core`, `vpn-entry`, `reverse-proxy`, `vpn-exit` и т.п.). - Сети compose: `proxy` для внешнего трафика через traefik, `internal` для межсервисной коммуникации и БД. Сервис в обеих сетях — только если ему правда нужен доступ и снаружи, и к внутренним зависимостям. - Имя папки сервера = `name` в inventory, по роли, не по IP. - Любой артефакт, без которого сервер не поднимется (compose, `.env`, конфиг, ключ) — лежит в `servers//` и коммитится в репо.