# 🏗️ Архитектура приложения ## Как работает автоматическое определение API URL ### ❌ Старый подход (проблемный): ``` .env файл: FRONTEND_API_URL=http://185.56.162.170:8080/api └─ Нужно обновлять для каждого окружения (dev, staging, prod) └─ Нужно пересобирать контейнер при смене IP/домена └─ Хранит хардкод конфигурации ``` ### ✅ Новый подход (умный): ``` ┌─────────────────────────────────────────────────────────────────┐ │ БРАУЗЕР ПОЛЬЗОВАТЕЛЯ │ │ http://185.56.162.170:80 или http://my-domain.com │ └────────────────────────┬────────────────────────────────────────┘ │ (window.location = текущий адрес) │ ┌────▼─────┐ │ NGINX │ (Gate для всех запросов) │ :80 │ └────┬─────┘ │ ┌────────────┬────────────┐ │ │ │ GET / │ GET /api/* GET /static/* │ │ │ ┌──▼──┐ ┌────▼──┐ ┌──▼──────┐ │FRONT│ │ BACK │ │ STATIC │ │END │ │ END │ │ CACHE │ └─────┘ └───────┘ └─────────┘ Фронтенд код: - ✅ Использует window.location.origin для определения хоста - ✅ Обращается к /api (относительный путь, не айпи) - ✅ Nginx проксирует /api на backend контейнер - ✅ Работает везде без переконфигурирования! ``` ## Как это использовать в коде ### В App.js или любом React компоненте: ```javascript import API_CONFIG from './api/config'; function MyComponent() { useEffect(() => { // Автоматически определится правильный API URL // Локально: http://localhost:3000/api/users // На VPS: http://185.56.162.170:80/api/users // С доменом: http://my-domain.com/api/users API_CONFIG.fetch('users') .then(data => console.log(data)); }, []); } ``` ## Преимущества | Параметр | Старый подход | Новый подход | |----------|---------------|-------------| | Нужно менять .env | ✅ Да | ❌ Нет | | Нужно пересобирать образ | ✅ Да | ❌ Нет | | Работает на localhost | ✅ Да | ✅ Да | | Работает на IP адресе | ✅ Да | ✅ Да | | Работает на домене | ✅ Да | ✅ Да | | CORS проблемы | ✅ Иногда | ❌ Нет | | Безопасность | ⚠️ Хардкод | ✅ Динамично | ## Docker сетевая архитектура ``` ┌─────────────────────────────────────────────────────────────┐ │ Docker Network: pg-admin-network (bridge) │ │ │ │ ┌──────────────┐ ┌──────────────┐ │ │ │ pg-admin-db │ │pg-admin-cache│ │ │ │ Port: 5432 │ │ Port: 6379 │ │ │ │ (internal) │ │ (internal) │ │ │ └──────────────┘ └──────────────┘ │ │ △ △ │ │ │ │ │ │ └──────┬─────────────┘ │ │ │ │ │ ┌──────▼──────────┐ │ │ │ pg-admin-api │ │ │ │ Port: 3000 │ │ │ │ (internal) │ │ │ └────────┬────────┘ │ │ │ │ │ ┌─────────────┼──────────────┐ │ │ │ │ │ │ │ ▼ ▼ ▼ │ │ ┌──────────┐ ┌────────────┐ ┌───────────┐ │ │ │frontend │ │pg-admin-ui │ │ DATABASE │ │ │ │ │ │ Port: 3000 │ │ Postgres │ │ │ │Port: 80 │ │(internal) │ │ 15-alpine │ │ │ └────┬─────┘ └────────────┘ └───────────┘ │ │ │ │ └──────┼──────────────────────────────────────────────────────┘ │ ▼ ┌──────────────┐ │ pg-admin-proxy (Nginx) │ Listen: 80 (EXTERNAL) └──────────────┘ │ ├─ GET / → frontend:3000 ├─ GET /api/* → backend:3000 └─ GET /static/* → cache 365 дней Все контейнеры видят друг друга по имени (DNS): - backend может подключиться к postgres:5432 - backend может подключиться к redis:6379 - Nginx может подключиться к frontend:3000 и backend:3000 ``` ## Переменные окружения (только на VPS) Теперь в .env нужны ТОЛЬКО: ```env # Development / Production NODE_ENV=production # Пароли (генерируются openssl) DB_PASSWORD=... JWT_SECRET=... REDIS_PASSWORD=... # Остальное опционально LOG_LEVEL=info RATE_LIMIT_MAX_REQUESTS=100 ``` **НЕ нужны больше:** - ❌ FRONTEND_API_URL - ❌ CORS_ORIGIN (используется * по умолчанию) - ❌ FRONTEND_PORT - ❌ API_PORT (внутренние порты) - ❌ DB_PORT (внутренние порты) ## Примеры использования ### Локальная разработка: ```bash docker compose up --build # Открой http://localhost:80 # Фронтенд будет обращаться к http://localhost:80/api # Nginx проксирует на backend контейнер ``` ### На VPS: ```bash docker compose up -d --build # Открой http://185.56.162.170:80 # Фронтенд будет обращаться к http://185.56.162.170:80/api # Nginx проксирует на backend контейнер ``` ### С доменом: ```bash # Просто открой https://my-domain.com # Фронтенд будет обращаться к https://my-domain.com/api # Все работает автоматически! ``` ## Безопасность ✅ **Защищено:** - ✅ БД не открыта наружу - ✅ Redis не открыт наружу - ✅ API не открыт напрямую (только через Nginx) - ✅ Все запросы проходят через Nginx (централизованный контроль) - ✅ Нет хардкода IP адресов в коде - ✅ Пароли не в git ⚠️ **Нужно настроить:** - SSH ключи (вместо пароля) - UFW файрвол (только необходимые порты) - SSL/HTTPS (Let's Encrypt) - Rate limiting (уже включен) - Логирование (уже включено) --- **Готово к production! 🚀**