ДОКУМЕНТАЦИЯ
УСТАНОВКА · § 010
Поднимем backend, admin-панель, магазин, PostgreSQL и Redis одной командой. В конце у тебя будет работающий магазин и панель по доменам.
§ 010.01
Минимальные требования для production
СЕРВЕР
VPS с Linux
от 1 vCPU / 1 GB RAM / 10 GB SSD
DOCKER
Docker Engine + Compose
24.x+ / v2.20+
ДОМЕН
Доменное имя
3 поддомена: api, panel, shop
ПЛАТЕЖИ
Аккаунт YooKassa, Heleket или другой платёжной системы
нужно для приёма оплаты
§ 010.02
Если Docker уже стоит - пропускай
Самый простой способ на Ubuntu/Debian — официальный скрипт от Docker:
SHELL
curl -fsSL https://get.docker.com | sh
※ Проверка установки: docker --version
§ 010.03
Один файл на все 5 сервисов: backend, panel, shop, PostgreSQL и Redis
Создай пустую папку под проект и положи в неё файл docker-compose.yml со следующим содержимым:
docker-compose.yml
services: backend: image: ghcr.io/fresh-donate/backend:latest pull_policy: always restart: unless-stopped env_file: [.env] volumes: - uploads_data:/app/uploads depends_on: postgres: { condition: service_healthy } redis: { condition: service_healthy } networks: [fresh-network] panel: image: ghcr.io/fresh-donate/panel:latest pull_policy: always restart: unless-stopped env_file: [.env] depends_on: [backend] networks: [fresh-network] shop: image: ghcr.io/fresh-donate/shop:latest pull_policy: always restart: unless-stopped env_file: [.env] depends_on: [backend] networks: [fresh-network] postgres: image: postgres:17-alpine restart: unless-stopped environment: POSTGRES_DB: ${DB_NAME:-fresh_donate} POSTGRES_USER: ${DB_USER:-postgres} POSTGRES_PASSWORD: ${DB_PASSWORD:-postgres} volumes: - postgres_data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-postgres} -d ${DB_NAME:-fresh_donate}"] interval: 5s timeout: 5s retries: 5 networks: [fresh-network] redis: image: redis:7-alpine restart: unless-stopped command: redis-server --requirepass ${REDIS_PASSWORD:-redis} volumes: - redis_data:/data healthcheck: test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD:-redis}", "ping"] interval: 5s timeout: 5s retries: 5 networks: [fresh-network] volumes: postgres_data: redis_data: uploads_data: networks: fresh-network: driver: bridge
※ Образы ghcr.io/fresh-donate/* публикуются автоматически из main-ветки каждого репозитория. pull_policy: always заставит Compose качать свежий образ при каждом up.
§ 010.04
Все секреты и публичные URL — здесь
Рядом с docker-compose.yml создай файл .env со следующим содержимым. Это полный набор переменных — закомментированные значения можно оставить как есть, секреты обязательно заменить.
.env
# === Frontend (panel + shop) === # Куда фронтенды ходят за API. Домен на котором стоит бекенд. NUXT_PUBLIC_API_BASE=https://api.your-domain.com # === Backend Server === HOST=0.0.0.0 PORT=3001 SERVER_PORT=3001 # === Database === DB_HOST=postgres DB_PORT=5432 DB_NAME=fresh_donate DB_USER=postgres DB_PASSWORD=сложный-пароль-postgres # === Redis === REDIS_HOST=redis REDIS_PORT=6379 REDIS_PASSWORD=сложный-пароль-redis # === Admin Panel Credentials === ADMIN_LOGIN=admin ADMIN_PASSWORD=сильный-пароль-минимум-16-символов # === JWT === # Любая случайная строка ≥32 символов. Сгенерировать: openssl rand -hex 32 JWT_SECRET=замени-на-длинную-случайную-строку JWT_EXPIRES_IN=7d # === Rate Limiting === RATE_LIMIT_MAX=100 RATE_LIMIT_TIMEWINDOW=60000 # === Payment === # Куда возвращается игрок после оплаты (фронтенд магазина) PAYMENT_RETURN_URL=https://shop.your-domain.com # Публичный URL backend для вебхуков платёжных шлюзов WEBHOOK_BASE_URL=https://api.your-domain.com # Раскомментируй, если backend за прокси без x-forwarded-for или в тестовом режиме # YOOKASSA_SKIP_IP_CHECK=true # === CORS (через запятую) === CORS_ORIGIN=https://panel.your-domain.com,https://shop.your-domain.com
Важно
Не оставляй на проде дефолтные пароли БД/Redis, admin/admin и пустой JWT_SECRET. Любой, кто угадает JWT_SECRET, сможет выпустить себе токен админа.
DB_HOST=postgres и REDIS_HOST=redis — это имена сервисов из docker-compose.yml. Внутри docker-сети контейнеры обращаются друг к другу по этим именам, а не по localhost.
§ 010.05
Одной командой
SHELL
docker compose up -d
Compose:
Проверь, что контейнеры живы:
SHELL
docker compose ps
docker compose logs -f backend
§ 010.06
Compose поднимает сервисы во внутренней docker-сети. Наружу их выводит nginx (или любой другой reverse proxy)
Сервисы внутри сети:
backend
:3001
REST API, вебхуки
panel
:3000
Админ-панель
shop
:3002
Витрина для игроков
postgres
:5432
База данных (внутри docker-сети)
redis
:6379
Кэш и rate-limit (внутри docker-сети)
Пример конфига для nginx — три server-блока, по одному на поддомен:
/etc/nginx/sites-available/fresh-donate.conf
# API server { listen 80; server_name api.your-domain.com; location / { proxy_pass http://backend:3001; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } # Админ-панель server { listen 80; server_name panel.your-domain.com; location / { proxy_pass http://panel:3000; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } # Магазин server { listen 80; server_name shop.your-domain.com; location / { proxy_pass http://shop:3002; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }
Активируй конфиг и проверь синтаксис:
SHELL
ln -s /etc/nginx/sites-available/fresh-donate.conf /etc/nginx/sites-enabled/
nginx -t # проверка конфига
systemctl reload nginx
HTTPS-сертификаты — через certbot, он сам пропишет 443 и редирект 80→443:
SHELL
certbot --nginx -d api.your-domain.com -d panel.your-domain.com -d shop.your-domain.com
※ Если nginx стоит на хосте (а не в compose), proxy_pass должен указывать на пробросы портов, например http://127.0.0.1:3001. Для этого добавь ports: ["3001:3001"] в нужный сервис compose. Если nginx в compose и в той же сети fresh-network — используй имена сервисов как в примере.
§ 010.07
Полный набор того, что можно настроить через .env
NUXT_PUBLIC_API_BASE
http://localhost:3001
URL backend для фронтендов panel и shop. Подставляется в Nuxt на этапе сборки.
HOST / PORT
0.0.0.0 / 3001
На каком интерфейсе и порту слушает backend внутри контейнера.
SERVER_PORT
3001
Внешний порт хоста, на который пробрасывается backend (если используешь ports вместо reverse-proxy).
DB_HOST / DB_PORT
postgres / 5432
Где живёт PostgreSQL. Внутри compose-сети — имя сервиса postgres.
DB_NAME / DB_USER / DB_PASSWORD
fresh_donate / postgres / postgres
Подключение к БД. Пароль на проде обязательно сменить.
REDIS_HOST / REDIS_PORT
redis / 6379
Где живёт Redis. Внутри compose-сети — имя сервиса redis.
REDIS_PASSWORD
redis
Пароль Redis. На проде обязательно сменить.
ADMIN_LOGIN / ADMIN_PASSWORD
admin / admin
Учётные данные администратора панели. На проде сменить.
JWT_SECRET
change-me…
Случайная строка ≥32 символов. Используется для подписи токенов. Утечка = доступ админа.
JWT_EXPIRES_IN
7d
Сколько живёт токен админа (7d, 30d, 24h, …).
RATE_LIMIT_MAX
100
Сколько запросов в окно разрешено с одного IP. Окно — RATE_LIMIT_TIMEWINDOW (мс).
RATE_LIMIT_TIMEWINDOW
60000
Длительность окна rate-limit в миллисекундах.
PAYMENT_RETURN_URL
http://localhost:3002
Куда возвращается игрок после оплаты. Должно указывать на shop.
WEBHOOK_BASE_URL
http://localhost:3001
Публичный адрес бекенда — на него платёжные шлюзы шлют вебхуки. На проде обязательно HTTPS.
YOOKASSA_SKIP_IP_CHECK
false
Отключить проверку IP YooKassa. Включать только если backend за прокси без x-forwarded-for или в тестовом режиме.
CORS_ORIGIN
http://localhost:3000,http://localhost:3002
Через запятую — адреса панели и магазина. На проде укажи свои домены.
※ Полный список — в backend/src/config/index.ts и в .env.example.
§ 010.08
Убедимся, что всё работает
Открой https://api.your-domain.com/health — должен ответить 200 OK.
Зайди в https://panel.your-domain.com, войди под ADMIN_LOGIN / ADMIN_PASSWORD. Создай первый товар.
Открой https://shop.your-domain.com — товар должен появиться в каталоге.
§ 010.09
Сервер поднят — осталось подключить деньги и доставку