From ea04e042dffc2206b5e962b5b7137f4237543cd6 Mon Sep 17 00:00:00 2001 From: wasrusgen Date: Mon, 18 May 2026 14:22:01 +0300 Subject: [PATCH] =?UTF-8?q?feat:=20staging-=D0=BE=D0=BA=D1=80=D1=83=D0=B6?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20(Docker=20Compose=20+=20Caddy=20+=20?= =?UTF-8?q?deploy-script)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit docker-compose.staging.yml — backend-staging на порту 8001. .env.staging.example — шаблон с отдельным SHEET_ID. Caddyfile.staging.snippet — staging.api.wasrusgen1.pro. scripts/deploy-staging.sh — один скрипт для деплоя staging. app.js: BACKEND_URL читается из ?backend= параметра URL. Co-Authored-By: Claude Sonnet 4.6 --- deploy/.env.staging.example | 36 +++++++++++++++++++++++ deploy/Caddyfile.staging.snippet | 24 ++++++++++++++++ deploy/docker-compose.staging.yml | 41 ++++++++++++++++++++++++++ miniapp/assets/app.js | 4 ++- scripts/deploy-staging.sh | 48 +++++++++++++++++++++++++++++++ 5 files changed, 152 insertions(+), 1 deletion(-) create mode 100644 deploy/.env.staging.example create mode 100644 deploy/Caddyfile.staging.snippet create mode 100644 deploy/docker-compose.staging.yml create mode 100644 scripts/deploy-staging.sh diff --git a/deploy/.env.staging.example b/deploy/.env.staging.example new file mode 100644 index 0000000..cd81e41 --- /dev/null +++ b/deploy/.env.staging.example @@ -0,0 +1,36 @@ +# ============================================================ +# Staging-окружение. Скопируйте в .env.staging и заполните. +# Используется только docker-compose.staging.yml. +# Не коммитить! +# ============================================================ + +# Telegram bot — тот же (бот не запускается в staging, токен нужен для валидации initData) +BOT_TOKEN=8281503057:AAEXmOepY8quH8E3RqOjFbgn7owV1ngnbGA +ADMIN_TG_ID=5937498515 + +# GigaChat — те же ключи +GIGACHAT_AUTH_KEY=ЗАМЕНИТЕ +GIGACHAT_MODEL=GigaChat-Pro +GIGACHAT_SCOPE=GIGACHAT_API_PERS + +# STAGING Google Sheet — ОТДЕЛЬНАЯ копия продакшн-таблицы! +# Создать: открыть продакшн таблицу → Файл → Создать копию +SHEET_ID=ЗАМЕНИТЕ_ID_ТЕСТОВОЙ_ТАБЛИЦЫ +GOOGLE_CREDENTIALS_PATH=/app/credentials.json + +# MiniApp — staging URL с параметром backend +MINIAPP_URL=https://wasrusgen.github.io/zov-tech/?backend=https://staging.api.wasrusgen1.pro + +# Внутренний URL бэкенда (только в staging compose, без бота) +BACKEND_URL=http://backend-staging:8000 + +# Бизнес-правила (можно оставить как в prod) +ACTIVE_PERIOD_DAYS=90 +GRACE_PERIOD_DAYS=14 + +# Внутренний секрет +INTERNAL_SECRET=ЗАМЕНИТЕ_ИЛИ_ОСТАВЬТЕ_КАК_В_PROD + +# Google Drive — можно оставить prod файлы (только чтение) +SHIPMENTS_FILE_ID=1fER4NmEgSznvPKJWXOqLDDkTxH6wm78E +ARRIVALS_FILE_ID=1kgrDEIGcVMFnSdZs1Y_QHVhjqsXFQk2h diff --git a/deploy/Caddyfile.staging.snippet b/deploy/Caddyfile.staging.snippet new file mode 100644 index 0000000..da1e0e4 --- /dev/null +++ b/deploy/Caddyfile.staging.snippet @@ -0,0 +1,24 @@ +# Staging backend — добавить в основной Caddyfile. +# После добавления: sudo systemctl reload caddy +# +# Убедиться что DNS: staging.api.wasrusgen1.pro → IP этого VPS + +staging.api.wasrusgen1.pro { + reverse_proxy localhost:8001 + + encode zstd gzip + header { + Strict-Transport-Security "max-age=31536000; includeSubDomains" + X-Content-Type-Options "nosniff" + Referrer-Policy "strict-origin-when-cross-origin" + -Server + # Помечаем staging-ответы + X-Environment "staging" + } + log { + output file /data/zov-staging-access.log { + roll_size 5mb + roll_keep 3 + } + } +} diff --git a/deploy/docker-compose.staging.yml b/deploy/docker-compose.staging.yml new file mode 100644 index 0000000..33204f7 --- /dev/null +++ b/deploy/docker-compose.staging.yml @@ -0,0 +1,41 @@ +# Staging-окружение — только backend, без бота и тоннеля. +# Использует отдельный .env.staging с тестовым SHEET_ID. +# +# Запуск: +# docker compose -f docker-compose.staging.yml --env-file .env.staging up -d --build +# Остановка: +# docker compose -f docker-compose.staging.yml down + +services: + backend-staging: + build: + context: ../backend-py + dockerfile: Dockerfile + image: zov-tech-backend:staging + container_name: zov-backend-staging + restart: unless-stopped + env_file: + - .env.staging + environment: + - STAGING=true + volumes: + - ./credentials.json:/app/credentials.json:ro + - ./photos-staging:/app/photos + networks: + - web + - internal-staging + ports: + - "127.0.0.1:8001:8000" + healthcheck: + test: ["CMD", "python", "-c", "import urllib.request,sys; r=urllib.request.urlopen('http://127.0.0.1:8000/healthz', timeout=3); sys.exit(0 if r.status==200 else 1)"] + interval: 30s + timeout: 5s + retries: 3 + start_period: 15s + +networks: + web: + name: deploy_web + external: true + internal-staging: + driver: bridge diff --git a/miniapp/assets/app.js b/miniapp/assets/app.js index 7400c1c..e3c25bc 100644 --- a/miniapp/assets/app.js +++ b/miniapp/assets/app.js @@ -5,7 +5,9 @@ const tg = window.Telegram?.WebApp; // Cloudflare Quick Tunnel → VPS FastAPI backend (GigaChat). // Временный URL — пока wasrusgen1.pro в verification-hold; затем переключим на https://api.wasrusgen1.pro -const BACKEND_URL = "https://api.wasrusgen1.pro"; +// Позволяет переключить бэкенд через ?backend=https://staging.api.wasrusgen1.pro +const BACKEND_URL = new URLSearchParams(window.location.search).get("backend") + || "https://api.wasrusgen1.pro"; const app = document.getElementById("app"); diff --git a/scripts/deploy-staging.sh b/scripts/deploy-staging.sh new file mode 100644 index 0000000..5715e72 --- /dev/null +++ b/scripts/deploy-staging.sh @@ -0,0 +1,48 @@ +#!/bin/bash +# Деплой staging-бэкенда на VPS. +# Использует docker-compose.staging.yml + .env.staging +# +# Запуск: bash scripts/deploy-staging.sh +# Требует: SSH-ключ ~/.ssh/zov_vps_ed25519, .env.staging на VPS + +set -e + +VPS="root@94.241.170.144" +SSH="ssh -i $HOME/.ssh/zov_vps_ed25519" +REMOTE_DIR="/opt/zov-tech" + +echo "🚀 Деплой STAGING → $VPS" + +# 1. Синхронизируем код +echo " [1/3] git pull на VPS..." +$SSH $VPS "cd $REMOTE_DIR && git pull origin master" + +# 2. Проверяем .env.staging +echo " [2/3] Проверка .env.staging..." +$SSH $VPS " + if [ ! -f $REMOTE_DIR/deploy/.env.staging ]; then + echo 'ERROR: .env.staging не найден!' + echo 'Скопируйте deploy/.env.staging.example → deploy/.env.staging и заполните.' + exit 1 + fi + if grep -q 'ЗАМЕНИТЕ' $REMOTE_DIR/deploy/.env.staging; then + echo 'ERROR: .env.staging содержит незаполненные поля (ЗАМЕНИТЕ)!' + exit 1 + fi + echo 'OK' +" + +# 3. Пересобираем и запускаем +echo " [3/3] docker compose up --build..." +$SSH $VPS " + cd $REMOTE_DIR/deploy + docker compose -f docker-compose.staging.yml --env-file .env.staging up -d --build +" + +echo "" +echo "✅ Staging задеплоен!" +echo " Backend: https://staging.api.wasrusgen1.pro/healthz" +echo " MiniApp: https://wasrusgen.github.io/zov-tech/?backend=https://staging.api.wasrusgen1.pro" +echo "" +echo "🧪 Запуск smoke-тестов против staging:" +echo " SMOKE_URL='https://wasrusgen.github.io/zov-tech/?backend=https://staging.api.wasrusgen1.pro' node tests/ui_smoke.js"