8.7 KiB
8.7 KiB
Trade-In MVP — деплой в gendesign репо
Архитектура
lekss361/-gendesign/
├── backend/ ← gendesign Python backend (НЕ ТРОГАЕМ)
├── frontend/ ← gendesign Next.js (НЕ ТРОГАЕМ)
├── docker-compose.prod.yml ← gendesign-стек
├── Caddyfile ← основной Caddy → ВКЛЮЧАЕТ tradein-mvp/deploy/Caddyfile.tradein-fragment
├── .github/workflows/
│ ├── deploy.yml ← существующий gendesign deploy
│ └── deploy-tradein.yml ← НАШ новый, триггерится только на tradein-mvp/**
└── tradein-mvp/ ← НАША подпапка (изолированный subproject)
├── backend/
├── frontend/
├── deploy/
│ ├── Caddyfile.tradein-fragment ← импортится в основной Caddyfile
│ └── cron-scrape.sh
├── docker-compose.yml ← локальный dev
├── docker-compose.prod.yml ← production overlay (использует GHCR images)
└── .github/workflows/deploy-tradein.yml
Прод URL routes
| URL | Сервис |
|---|---|
gendsgn.ru/trade-in/ |
tradein-frontend:3000 |
gendsgn.ru/trade-in/api/v1/... |
tradein-backend:8000 |
Caddy в gendesign-стеке проксирует через handle_path /trade-in/api/* (вырезает префикс) и handle /trade-in/* (Next.js basePath).
Прод docker stacks
docker compose -p gendesign— основной gendesign (postgres + backend + frontend + caddy + couchdb)docker compose -p gendesign-tradein— наш (tradein-postgres + tradein-backend + tradein-frontend)
Оба подключены к gendesign_shared external network — туда смотрит Caddy.
Что нужно положить в основной Caddyfile gendesign
В блок gendsgn.ru { ... } ПЕРЕД универсальным handle { reverse_proxy frontend:3000 }:
import /opt/gendesign/tradein-mvp/deploy/Caddyfile.tradein-fragment
Или вставить содержимое фрагмента inline.
Что нужно положить в .env.runtime (на сервере, НЕ в git)
Два файла:
/opt/gendesign/tradein-mvp/.env.runtime— переменные для docker compose substitution (${TRADEIN_POSTGRES_PASSWORD}и т.п. в compose-файле). Читается shell-скриптом deploy черезsource .env.runtimeпередcompose up./opt/gendesign/tradein-mvp/backend/.env.runtime— переменные внутри контейнераtradein-backend(читаются черезenv_file:в compose). Сюда попадаютYANDEX_GEOCODER_API_KEY,ADMIN_TOKEN,COOKIE_ENCRYPTION_KEY— всё, что нужно scripts/backfill_house_coords.py и application code внутри контейнера.
# /opt/gendesign/tradein-mvp/.env.runtime
TRADEIN_POSTGRES_USER=tradein
TRADEIN_POSTGRES_PASSWORD=<сгенерировать openssl rand -hex 32>
TRADEIN_CONTACT_EMAIL=tradein@gendsgn.ru
YANDEX_GEOCODER_API_KEY= # пусто пока, Nominatim fallback работает
# Encryption key for Cian session cookies (pgp_sym_encrypt / Stage 9 Calculator).
# Empty = Valuation Calculator scraper disabled + /api/v1/cookies/upload returns 503.
# Generate once on VPS:
# openssl rand -hex 32
COOKIE_ENCRYPTION_KEY=<64-char hex>
# /opt/gendesign/tradein-mvp/backend/.env.runtime — те же ключи которые
# читаются ВНУТРИ container'а (scripts/backfill_house_coords.py, app/*).
# Может быть симлинком на ../.env.runtime если переменные совпадают:
# ln -s ../.env.runtime /opt/gendesign/tradein-mvp/backend/.env.runtime
YANDEX_GEOCODER_API_KEY=<key или пусто>
ADMIN_TOKEN=<token или пусто>
COOKIE_ENCRYPTION_KEY=<64-char hex>
GENDESIGN_FDW_PASSWORD=<password или пусто>
GLITCHTIP_DSN=<dsn или пусто>
Оба файла создаются вручную при первом деплое.
После изменения backend/.env.runtime
# .env.runtime читается на старте container — `compose restart` НЕ перечитывает.
docker compose -p gendesign-tradein -f docker-compose.prod.yml \
up -d --force-recreate --no-deps backend
См. .claude/rules/deploy.md — main backend pattern идентичный.
Обновление COOKIE_ENCRYPTION_KEY на существующем VPS
# На VPS, если COOKIE_ENCRYPTION_KEY ещё не задан:
echo "COOKIE_ENCRYPTION_KEY=$(openssl rand -hex 32)" >> /opt/gendesign/tradein-mvp/.env.runtime
# Применить без полного рестарта стека:
cd /opt/gendesign/tradein-mvp
docker compose -p gendesign-tradein -f docker-compose.prod.yml up -d --force-recreate --no-deps backend
GitHub Secrets (уже должны быть от gendesign deploy)
DEPLOY_HOST— IP сервера (94.228.121.73)DEPLOY_USER— rootDEPLOY_SSH_KEY— приватный SSH ключDEPLOY_PORT— 22 (или другой если меняли)
Первый деплой — пошагово
1. На анто́новой машине: подготовить tradein-mvp/ к слиянию
# clone gendesign репо (с PAT)
git clone https://<PAT>@github.com/lekss361/-gendesign.git
cd -gendesign
# скопировать tradein-mvp/ как подпапку
cp -r /Users/anton/Птица/tradein-mvp ./tradein-mvp
rm -rf ./tradein-mvp/postgres-data # на всякий
rm -rf ./tradein-mvp/.git # не нужен внутри monorepo
# скопировать workflow в правильное место
mkdir -p .github/workflows
cp ./tradein-mvp/.github/workflows/deploy-tradein.yml .github/workflows/
git add tradein-mvp/ .github/workflows/deploy-tradein.yml
git commit -m "feat: add tradein-mvp subproject + deploy workflow"
git push origin main
2. На сервере: первый раз вручную добавить Caddy include
ssh -i ~/.ssh/id_bot_server root@94.228.121.73
cd /opt/gendesign
# git reset --hard origin/main подтянет tradein-mvp/ автоматически
# Добавить в Caddyfile (ровно одну строку в блок gendsgn.ru { ... })
nano Caddyfile
# вставить ПЕРЕД последним handle { ... }:
# import /opt/gendesign/tradein-mvp/deploy/Caddyfile.tradein-fragment
# Создать .env.runtime — два файла:
# 1. tradein-mvp/.env.runtime — для compose substitution на host'е
cat > tradein-mvp/.env.runtime <<EOF
TRADEIN_POSTGRES_USER=tradein
TRADEIN_POSTGRES_PASSWORD=$(openssl rand -hex 32)
TRADEIN_CONTACT_EMAIL=tradein@gendsgn.ru
YANDEX_GEOCODER_API_KEY=
EOF
chmod 600 tradein-mvp/.env.runtime
# 2. tradein-mvp/backend/.env.runtime — для env_file внутри container'а.
# Симлинк работает если переменные одни и те же; иначе создать отдельный файл.
ln -sf ../.env.runtime tradein-mvp/backend/.env.runtime
# Запустить stack первый раз вручную (после этого GitHub Actions сам)
docker network inspect gendesign_shared >/dev/null 2>&1 || docker network create gendesign_shared
cd tradein-mvp
set -a; source .env.runtime; set +a
docker compose -p gendesign-tradein -f docker-compose.prod.yml pull
docker compose -p gendesign-tradein -f docker-compose.prod.yml up -d
# Reload Caddy
cd /opt/gendesign
docker compose -p gendesign -f docker-compose.prod.yml exec -T caddy caddy reload --config /etc/caddy/Caddyfile
# Проверить
curl -sS https://gendsgn.ru/trade-in/api/health
curl -sI https://gendsgn.ru/trade-in/
3. Дальше — автодеплой
После первого ручного запуска все следующие git push origin main с изменениями в tradein-mvp/** будут:
- Триггерить
.github/workflows/deploy-tradein.yml - Билдить и пушить новые образы в
ghcr.io/lekss361/gendesign-tradein-* - SSH в сервер →
docker compose pull→up -d→ Caddy reload - Health check
Откат
ssh root@94.228.121.73
cd /opt/gendesign/tradein-mvp
# Откатиться на предыдущий SHA-тег
docker compose -p gendesign-tradein -f docker-compose.prod.yml down
IMAGE_TAG=<previous-sha> docker compose -p gendesign-tradein -f docker-compose.prod.yml up -d