infra/CLAUDE.md
jack 66b70827df
Some checks failed
CI/CD / syntax-check (push) Successful in 1m31s
CI/CD / deploy (push) Has been cancelled
chore: full project cleanup + documentation
Syncthing removal (was already decided, now fully removed):
- roles/base/tasks/firewall.yml: remove 3 UFW rules (ports 22000/21027)
- inventory/group_vars/all/main.yml: remove domain_sync, domain_mon, syncthing_basic_auth_htpasswd
- roles/services/templates/env.j2: remove DOMAIN_SYNC
- roles/services/templates/authelia/configuration.yml.j2: remove Syncthing 2FA rule
- roles/services/tasks/directories.yml: remove syncthing/config and syncthing/data dirs
- roles/services/defaults/main.yml: remove syncthing_image
- roles/services/tasks/main.yml: remove syncthing image pull

Security hardening:
- inventory/group_vars/all/main.yml: move cloudflare_zone_id to vault
- inventory/group_vars/all/vault.yml: add vault_cloudflare_zone_id

.gitignore improvements:
- add *.env, acme.json, *.log, editor dirs, venv, temp files

Documentation (new):
- docs/STATUS.md: all services, servers, known issues
- docs/BACKLOG.md: prioritized task list, done/todo
- docs/DECISIONS.md: architecture decisions and rationale
- CLAUDE.md: rewritten with read-first docs, rules, full arch reference

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-22 19:58:12 +07:00

111 lines
4.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## ⚠️ ЧИТАЙ СНАЧАЛА
Перед любой работой прочитай эти файлы:
- **`docs/STATUS.md`** — текущее состояние всех сервисов, известные проблемы
- **`docs/BACKLOG.md`** — что нужно сделать (приоритеты), что уже сделано
- **`docs/DECISIONS.md`** — почему всё устроено именно так
После завершения работы **обнови** соответствующий документ.
---
## Правила работы
1. **Только через CI/CD** — никогда не фикси что-либо вручную на сервере. Внеси изменение, закоммить, запуши → CI/CD сам задеплоит. Потом проверь результат.
2. **Syncthing удалён** — не предлагай его вернуть, не упоминай как отсутствующий сервис.
3. **Секреты** — все в `inventory/group_vars/all/vault.yml` с префиксом `vault_`. В `main.yml` только алиасы `"{{ vault_* }}"`. Никаких plaintext секретов.
4. **Синтаксис-чек перед коммитом**`ansible-playbook playbooks/deploy.yml --syntax-check`.
---
## Команды
```bash
# Prerequisites (один раз, на машине оператора)
ansible-galaxy collection install community.general community.docker ansible.posix
echo "yourpassword" > ~/.vault-password-file && chmod 600 ~/.vault-password-file
# Первичная настройка сервера (от root)
ansible-playbook playbooks/bootstrap.yml -u root
# Деплой основного сервера
ansible-playbook playbooks/deploy.yml
# Деплой tools-сервера
ansible-playbook playbooks/tools.yml
# Деплой всего сразу
ansible-playbook playbooks/site.yml
# Редактировать секреты
ansible-vault edit inventory/group_vars/all/vault.yml
# Проверка синтаксиса (без подключения к серверу)
ansible-playbook playbooks/deploy.yml --syntax-check
ansible-playbook playbooks/tools.yml --syntax-check
# Dry run
ansible-playbook playbooks/deploy.yml --check
# Только конкретная роль
ansible-playbook playbooks/deploy.yml --tags base
ansible-playbook playbooks/deploy.yml --tags docker
ansible-playbook playbooks/deploy.yml --tags services
ansible-playbook playbooks/deploy.yml --tags backup
```
---
## Архитектура
**Серверы:**
- `main` (87.249.49.32) — Traefik, Forgejo, Plane, Vaultwarden, Мониторинг, CI/CD runner
- `tools` (85.193.83.9) — Outline wiki, n8n, docker-mailserver, SnappyMail
**Трафик:** Internet → Cloudflare proxy → Traefik (80/443) → сервисы.
Порты 80/443 открыты только для IP-адресов Cloudflare (UFW whitelist).
**Секреты:** `inventory/group_vars/all/vault.yml` (Ansible Vault AES-256).
Пароль vault: `~/.vault-password-file``.gitignore`, никогда не коммитить).
**TLS:** Wildcard сертификат `*.csrx.ru` через Cloudflare DNS-01 (Traefik certresolver).
**Роли:**
- `base` — UFW, fail2ban, sshd, deploy user
- `docker` — Docker CE + Compose plugin
- `services` — основной стек (templates → `/opt/services/`, docker compose up)
- `tools` — tools-стек (templates → `/opt/tools/`, docker compose up)
- `backup` — hourly backup script → S3 cold (`visual-backup/data/`)
**Шаблоны → файлы на сервере:**
- `roles/services/templates/docker-compose.yml.j2``/opt/services/docker-compose.yml`
- `roles/services/templates/env.j2``/opt/services/.env` (mode 0600)
- `roles/services/templates/traefik/traefik.yml.j2``/opt/services/traefik/traefik.yml`
- `roles/services/templates/traefik/dynamic/routes.yml.j2``/opt/services/traefik/dynamic/routes.yml`
**Добавление нового сервиса на main:**
1. Добавить контейнер в `docker-compose.yml.j2` в сеть `backend`
2. Добавить роутер в `routes.yml.j2` (НЕ docker labels — используется file provider)
3. Добавить домен в `inventory/group_vars/all/main.yml`
4. Добавить DNS A-запись в Cloudflare
**Добавление сервиса на tools:**
1. Добавить контейнер в `roles/tools/templates/docker-compose.yml.j2`
2. Добавить роутер в `routes.yml.j2` с `url: "http://{{ ip_tools }}:PORT"`
3. Открыть порт в UFW (задача в `roles/tools/tasks/main.yml`)
---
## CI/CD
Push в `master` → Forgejo Actions запускает:
```
ansible-playbook playbooks/deploy.yml
ansible-playbook playbooks/tools.yml
```
Workflow: `.forgejo/workflows/deploy.yml`