diff --git a/.gitignore b/.gitignore
index d75f0f0..00b8815 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,6 +6,7 @@
!install.sh
!scripts/**
!config/**
+!assets/**
*.sql.gz
*.tar.gz
.env
diff --git a/README.md b/README.md
index dec9a65..573e125 100644
--- a/README.md
+++ b/README.md
@@ -25,28 +25,21 @@ MySQL слушает TCP и ловит сканеры портянкой aborted
## Архитектура
-```mermaid
-flowchart TB
- U["Браузер"] -->|"HTTPS :443"| NG
+
+
+
- subgraph VPS["Ubuntu 24.04, без Docker"]
- NG["nginx
TLS · статика · urlrewrite
limit_req zones"]
+
+Текстовая версия схемы
- NG -->|"fastcgi, unix-сокет
/run/php/bitrix-fpm.sock"| PHP["php-fpm pool 'bitrix'
dynamic, max 30, max_requests 500"]
- PHP -->|"localhost = сокет"| DB[("Percona MySQL 8.0
bind 127.0.0.1 only")]
- PHP --> MC1[("memcached cache
127.0.0.1:11211")]
- PHP --> MC2[("memcached sessions
127.0.0.1:11212")]
+- Браузер → HTTPS :443 → nginx (TLS, статика, urlrewrite, limit_req)
+- nginx → fastcgi unix-сокет → php-fpm pool «bitrix» (dynamic, max 30)
+- php-fpm → `localhost` = сокет → Percona MySQL 8.0; TCP :3306/:33060 закрыты
+- php-fpm → memcached :11211 (кэш) и :11212 (сессии)
+- cron CLI php → агенты каждую минуту, обмен 1С каждые 5 минут, бэкапы в `/var/backups/bitrix`
+- nginx access.log → CrowdSec + firewall-bouncer; sshd → fail2ban; оба банят источники атак
- CRON["cron (CLI php)
agents · exchange · backup"]
- CRON --> PHP
- CRON --> DB
- end
-
- LOGS["nginx access.log (combined)"] -.->|parse| CS["CrowdSec + firewall-bouncer"]
- SSHD["sshd journal"] -.-> F2B["fail2ban"]
- CRON --> BAK["backups:
mysqldump + code tarball
retention 14 дней"]
- CS -.->|"блокирует"| U
-```
+
Ключевые отличия от «Bitrix VM по умолчанию»:
diff --git a/assets/readme/architecture.svg b/assets/readme/architecture.svg
new file mode 100644
index 0000000..fb15449
--- /dev/null
+++ b/assets/readme/architecture.svg
@@ -0,0 +1,140 @@
+
diff --git a/scripts/validate_readme_assets.py b/scripts/validate_readme_assets.py
new file mode 100644
index 0000000..9ddfd10
--- /dev/null
+++ b/scripts/validate_readme_assets.py
@@ -0,0 +1,17 @@
+import io, collections, re
+import xml.etree.ElementTree as ET
+
+t = io.open('assets/readme/architecture.svg', encoding='utf-8').read()
+ET.fromstring(t)
+for bad in ('