Deployment¶
Jak deployovat backend, worker, frontend, dokumentaci.
Backend + Worker (Sliplane)¶
Auto-deploy z GitHub main¶
Sliplane má GitHub integration enabled per service:
https://sliplane.io → service settings → Repository
url: https://github.com/Algawebbusiness/nemoreport-ai-backend-v2
branch: main
autoDeploy: true
Kdykoliv někdo pushne na main:
1. Sliplane build agent (Hetzner-based) cloneuje repo
2. Build Docker image z Dockerfile
3. Push do registry-01.nbg1.ger.sliplane.io/...
4. Pull + restart container
5. Health check /health
Build čas typicky 60-90s (cached layers).
Dockerfile¶
FROM docker.io/library/python:3.12-slim
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
WORKDIR /app
RUN apt-get update \
&& apt-get install -y --no-install-recommends libmagic1 \
&& rm -rf /var/lib/apt/lists/*
COPY pyproject.toml uv.lock* README.md ./
RUN uv sync --frozen --no-install-project --no-dev || uv sync --no-install-project --no-dev
COPY app ./app
COPY prompts ./prompts
COPY skills ./skills
COPY fixtures ./fixtures
RUN uv sync --frozen --no-dev || uv sync --no-dev
Stejný image pro backend i worker — liší se jen cmd:
| Service | CMD |
|---|---|
nemoreport-ai-backend-v2 |
uv run uvicorn app.main:app --host 0.0.0.0 --port 8000 |
nemoreport-ai-worker-v2 |
uv run python -m app.worker_entry |
Environment variables¶
ENV se nastavuje per service v Sliplane UI nebo via API. Strict-validated v app/config.py (fail-fast on missing).
Required pro backend + worker (oba mají stejný set):
| ENV | Příklad | Secret? |
|---|---|---|
SUPABASE_URL |
https://cubdrgjdkatyecrgckwp.supabase.co |
ne |
SUPABASE_ANON_KEY |
sb_publishable_... |
ne |
SUPABASE_SERVICE_ROLE_KEY |
eyJ... |
ano |
GEMINI_API_KEY |
AIza... |
ano |
MISTRAL_API_KEY |
... |
ano |
COHERE_API_KEY |
... |
ano |
ADMIN_HASH |
3bddbafdec... (sha1 of secret) |
ano |
NETTE_HMAC_SECRET |
... |
ano (jen backend) |
EMBEDDING_MODEL |
gemini-embedding-2 |
ne |
EMBEDDING_MODEL_VERSION |
ga-2026-04 |
ne |
COHERE_RERANK_MODEL |
rerank-v4.0-pro |
ne |
COHERE_RERANK_ENABLED |
true |
ne |
LLM_MODEL |
google-gla:gemini-3-flash-preview |
ne |
ALLOWED_ORIGINS |
https://nemoreport-ai-frontend-v2.algaweb.workers.dev,http://localhost:3000 |
ne |
RATE_LIMIT_STORAGE_URI |
redis://nemoreport-redis.internal:6379/0 |
ne |
REDIS_URL |
redis://nemoreport-redis.internal:6379/1 |
ne |
LOG_LEVEL |
INFO |
ne |
APP_ENV |
production |
ne |
Update env vars¶
Per Sliplane API quirk (app/CLAUDE.md note):
- updateService PUT s value="" smaže ENV var
- Pro secret keys vždy passnout konkrétní hodnotu, ne ""
- secret=true v getService response zobrazí jako value="" (masking, ne reálná empty)
Aktualizace přes MCP: mcp__sliplane__updateService s celým env arrayí (full replace).
Manual restart¶
# Restart backend
sliplane services restart nemoreport-ai-backend-v2
# Or via UI: Services → Click service → Restart
Logs¶
# Tail logs
sliplane services logs nemoreport-ai-backend-v2 --follow
# Or via MCP:
# mcp__sliplane__getServiceLogs(projectId, serviceId, from=<unix_ts>)
Resource scaling¶
Sliplane pricing: per-service CPU + RAM. Aktuálně každý service 1 CPU × 1 GB RAM (default).
Pro scale-up:
Rollback¶
Sliplane drží předchozí Docker images v registry. Rollback:
1. Find předchozí commit hash v Sliplane events log
2. git revert na předchozí commit
3. git push origin main → auto-deploy
Redis (Sliplane)¶
service: nemoreport-redis
image: redis:7-alpine
internal_dns: nemoreport-redis.internal:6379
persistence: AOF (append-only file)
Žádné public exposure. Backend + worker komunikují přes internal Sliplane network.
Backup strategy: Redis AOF persistuje na disk volume. Pro DR je potřeba volume snapshot (Sliplane managed).
Frontend (Cloudflare Workers)¶
Manual deploy¶
CF Pages auto-deploy nepoužíváme. Frontend deploy je manual přes wrangler:
cd /home/jiri/Nextcloud/vibecode/Nemoreport_v2/nemoreport-ai-frontend-v2
# Build (Next.js + OpenNext adapter)
npm run build # → .next/ + .open-next/
# Deploy na CF Workers
npm run deploy # = wrangler deploy
# Output:
# Total Upload: 6458.55 KiB / gzip: 1348.60 KiB
# Worker Startup Time: 35 ms
# Uploaded nemoreport-ai-frontend-v2 (22.44 sec)
# Deployed: https://nemoreport-ai-frontend-v2.algaweb.workers.dev
# Current Version ID: <uuid>
Konfigurace¶
wrangler.jsonc:
{
"name": "nemoreport-ai-frontend-v2",
"main": ".open-next/worker.js",
"compatibility_date": "2025-09-23",
"compatibility_flags": ["nodejs_compat"],
"assets": {
"directory": ".open-next/assets",
"binding": "ASSETS"
}
}
open-next.config.ts:
import { defineCloudflareConfig } from "@opennextjs/cloudflare";
export default defineCloudflareConfig({
// Default config
});
Environment variables¶
Setup v wrangler.jsonc (vars, not secrets):
{
"vars": {
"NEXT_PUBLIC_SUPABASE_URL": "https://cubdrgjdkatyecrgckwp.supabase.co",
"NEXT_PUBLIC_SUPABASE_ANON_KEY": "sb_publishable_...",
"NEXT_PUBLIC_BACKEND_URL": "https://nemoreport-ai-backend-v2.sliplane.app"
}
}
Žádné secrets na FE — SUPABASE_SERVICE_ROLE_KEY zůstává jen na BE.
Rollback¶
Cloudflare drží versions:
Nebo přes CF Workers Dashboard: Workers > nemoreport-ai-frontend-v2 > Deployments > Rollback.
Supabase¶
Migrace¶
# Local dev
cd /home/jiri/Nextcloud/vibecode/Nemoreport_v2/nemoreport-ai-backend-v2
supabase link --project-ref cubdrgjdkatyecrgckwp
supabase db push
# Or inline via MCP:
# mcp__claude_ai_Supabase__apply_migration(project_id, name, query)
Config (auth, redirect URLs, SMTP)¶
supabase/config.toml je source of truth. Push:
Změní:
- api.schemas (PostgREST exposed schemas)
- auth.hooks (custom JWT hook function)
- auth.email.template (custom magic link template)
- SMTP config s RESEND_API_KEY env substituci
- auth.redirect_urls (allowed redirect destinations)
Backups¶
Supabase Pro plán: - PITR (Point-in-time recovery) — 7 dní default - Daily backups — týden retention
Pro produkci doporučeno upgrade Free → Pro ($25/mo) — PITR essential pro disaster recovery.
Edge Functions (NEPOUŽÍVÁME zatím)¶
Phase B+ jsme se rozhodli use Sliplane worker místo Supabase Edge Functions kvůli: - Lepší debugging (full Python ekosystém) - Žádné cold starts - Lépe handle long-running OCR (15 min timeouty)
Dokumentace¶
Lokální dev¶
cd /home/jiri/Nextcloud/vibecode/Nemoreport_v2
# Install (jednorazově)
uv tool install mkdocs-material
# Dev server s live reload
mkdocs serve # http://127.0.0.1:8000
# Static build
mkdocs build # → site/
Hosting options¶
Option 1: Cloudflare Pages (recommended)
Option 2: GitHub Pages
Option 3: Sliplane static
Add new service s nginx serving site/ directory.
Doporučeno: Cloudflare Pages, custom doména docs.nemoreport.algaweb.cz.
Lokální development¶
Backend¶
cd /home/jiri/Nextcloud/vibecode/Nemoreport_v2/nemoreport-ai-backend-v2
# Install deps
uv sync
# Setup .env.local s minimum:
cat > .env.local <<EOF
SUPABASE_URL=https://cubdrgjdkatyecrgckwp.supabase.co
SUPABASE_ANON_KEY=...
SUPABASE_SERVICE_ROLE_KEY=...
GEMINI_API_KEY=...
ADMIN_HASH=test_local
RATE_LIMIT_STORAGE_URI=memory://
APP_ENV=development
EOF
# Run dev server
uv run uvicorn app.main:app --reload --port 8000
# Run worker (separate terminal)
uv run python -m app.worker_entry
# Note: needs Redis. Use Sliplane internal nebo lokální docker run redis.
Frontend¶
cd /home/jiri/Nextcloud/vibecode/Nemoreport_v2/nemoreport-ai-frontend-v2
npm install
npm run dev # http://localhost:3000
# Setup .env.local:
cat > .env.local <<EOF
NEXT_PUBLIC_SUPABASE_URL=https://cubdrgjdkatyecrgckwp.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=sb_publishable_...
NEXT_PUBLIC_BACKEND_URL=http://localhost:8000
EOF
Deploy checklist (production go-live)¶
Před production:
- Supabase upgrade Free → Pro ($25/mo) pro PITR
- Resend domain verification (mimo sandbox owner-only)
- Cohere production key (mimo trial 1000/mo limit)
- Vertex AI tier místo
google-glaDeveloper API (data privacy) - DNS cutover:
nemoreport-ai-frontend-v2.algaweb.workers.dev→ custom doména - HTTPS certs (CF managed automaticky)
- Monitoring + alerts (Sentry / Datadog?)
- Backup strategy (Supabase PITR + týdenní DB dump do CF R2)
- Cost alerts (Stripe / billing thresholds)
- Pen test (Phase A+B+C má pgTAP suite + smoke tests, ale dedicated security audit doporučen)
- GDPR compliance review (data retention, right to erasure →
nemoreport.handle_delete_usertrigger) - Terms of Service + Privacy Policy hosted
Disaster recovery¶
Scenario 1: Sliplane outage¶
- Backend + worker down → app nefunguje
- Mitigation: deploy na backup provider (Render / Fly.io) — 2 dny prep
- RTO: 4 hodiny (manual restore from Docker images)
- RPO: 0 (Postgres je nezávislé na Sliplane)
Scenario 2: Supabase outage¶
- DB + Auth down → app nefunguje
- Mitigation: vendor's responsibility (status page); Pro plán má SLA
- RTO: depends on Supabase
- Recovery: PITR pokud DB corruption
Scenario 3: Cloudflare outage¶
- Frontend down (FE Worker)
- Mitigation: rare (Cloudflare tier-1 reliability)
- RTO: depends on CF
- Backup: Vercel deploy ready (
@opennextjsworks na Vercel)
Scenario 4: Vendor data loss¶
- Supabase delete project / corruption
- Mitigation: PITR (7d), týdenní DB dump do CF R2 (offsite)
- Implementation: cron job na týdenní
pg_dump→ upload na R2
Scenario 5: Code repo loss¶
- GitHub + GitLab oba lost (extremely unlikely)
- Mitigation: dual-push remote (
git push origin main→ oba simultaneously) - Local clones na dev machines + Nextcloud sync (
/home/jiri/Nextcloud/vibecode/)