Skip to content

Deployment Architecture

Subscribe Flow follows a modern cloud-native architecture with a clear separation of frontend (static SPA) and backend (API).

Deployment Diagram

graph TB
    subgraph "Client Layer"
        Browser[Browser]
        Mobile[Mobile App]
        SDK[SDK Client]
    end

    subgraph "CDN / Static Hosting"
        CF[Cloudflare Pages]
        PC[Preference Center SPA]
        AD[Admin Dashboard SPA]
        CF --> PC
        CF --> AD
    end

    subgraph "API Layer - Railway/Fly.io"
        LB[Load Balancer]
        API1[FastAPI Instance 1]
        API2[FastAPI Instance 2]
        Worker[Celery Worker]
        Beat[Celery-Beat Scheduler]
        LB --> API1
        LB --> API2
    end

    subgraph "Data Layer - Managed Services"
        PG[(PostgreSQL 15)]
        Redis[(Redis 7)]
    end

    subgraph "External Services"
        Resend[Resend API]
        Stripe[Stripe API]
        Webhooks[Customer Webhooks]
    end

    Browser --> CF
    Mobile --> CF
    SDK --> LB

    PC --> LB
    AD --> LB

    API1 --> PG
    API2 --> PG
    API1 --> Redis
    API2 --> Redis

    Worker --> PG
    Worker --> Redis
    Worker --> Resend

    Beat --> Redis

    API1 --> Resend
    API2 --> Resend
    API1 --> Stripe
    API2 --> Stripe

    API1 --> Webhooks
    API2 --> Webhooks

    Resend -.Webhook.-> LB
    Stripe -.Webhook.-> LB

    style CF fill:#f97316
    style LB fill:#3b82f6
    style PG fill:#8b5cf6
    style Redis fill:#ef4444
    style Resend fill:#10b981
    style Stripe fill:#6366f1
    style Worker fill:#f59e0b
    style Beat fill:#f59e0b

Components

Frontend (Cloudflare Pages / Netlify)

Technology: React 19 SPA with Vite 6+ (Bun runtime)

Deployment: - Static build (bun run build) - Automatic deployment on Git push (main branch) - Global CDN distribution - HTTPS by default - Custom domain support

Environment Variables:

Bash
VITE_API_URL=https://api.subscribeflow.com
VITE_SENTRY_DSN=https://...

Build Command:

Bash
cd apps/web && bun run build

Output Directory: apps/web/dist

Backend (Railway / Fly.io)

Technology: Python FastAPI with Uvicorn

Deployment: - Docker container - Auto-scaling (2-10 instances) - Health checks (/health) - Zero-downtime deployments

Dockerfile:

Docker
1
2
3
4
5
FROM python:3.13-slim
WORKDIR /app
COPY . .
RUN pip install uv && uv sync
CMD ["uv", "run", "uvicorn", "subscribeflow.main:app", "--host", "0.0.0.0", "--port", "8000"]

Environment Variables:

Bash
# Database & Cache
DATABASE_URL=postgresql://...
REDIS_URL=redis://...

# Authentication
JWT_SECRET_KEY=...
API_KEY_SALT=...

# Resend (Email)
RESEND_API_KEY=re_...
DEFAULT_SEND_DOMAIN=mail.subscribeflow.net

# Session Cookie
SESSION_COOKIE_DOMAIN=.subscribeflow.net

# Stripe (Billing)
STRIPE_SECRET_KEY=sk_live_...
STRIPE_WEBHOOK_SECRET=whsec_...
STRIPE_PRICE_STARTER=price_...
STRIPE_PRICE_PROFESSIONAL=price_...

Celery Worker (Railway / Fly.io)

Technology: Celery with Redis backend

Tasks: - Resend API synchronization - Webhook delivery - Data retention cleanup - Email sending - Magic link email delivery

Deployment: - Separate container (same codebase) - Auto-scaling based on queue length

Command:

Bash
uv run celery -A subscribeflow.worker worker --loglevel=info

Celery-Beat Scheduler (Railway / Fly.io)

Technology: Celery-Beat with Redis backend

Scheduled Tasks:

Task Schedule Description
reset_monthly_email_counters 1st of month, 00:00 UTC Resets emails_sent_this_month to 0 for all organizations

Command:

Bash
uv run celery -A subscribeflow.worker beat --loglevel=info

Deployment: - Single instance only (no horizontal scaling for Beat) - Runs alongside worker or as dedicated container

Database (Supabase / Railway Postgres)

Technology: PostgreSQL 15+

Configuration: - Connection pooling (PgBouncer) - Automated backups (daily) - Point-in-time recovery - Read replicas (post-MVP)

Scaling: - Vertical scaling (CPU/RAM) - Read replicas for analytics - Connection pooling (max 100 connections)

Cache (Upstash Redis / Railway Redis)

Technology: Redis 7+

Use Cases: - Session storage (Magic Link tokens, JWT sessions) - API response caching - Celery message queue + Beat schedule store - Per-organization rate limiting counters

Configuration: - Maxmemory policy: allkeys-lru - Persistence: RDB + AOF - Eviction: Automatic

Custom Domain DNS Configuration

Professional-tier organizations can configure custom email domains. The following DNS records must be set by the customer:

Record Type Name Value Purpose
TXT _resend.custom-domain.com (provided by Resend) Domain verification
MX custom-domain.com (provided by Resend) Inbound email routing
TXT custom-domain.com v=spf1 include:... SPF authentication
CNAME resend._domainkey.custom-domain.com (provided by Resend) DKIM signing

Domain verification is handled via the DomainService, which calls the Resend API to register and verify domains.

Deployment Pipeline

CI/CD (GitHub Actions)

YAML
# .github/workflows/deploy.yml
name: Deploy

on:
  push:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: astral-sh/setup-uv@v5
      - run: uv sync
      - run: uv run pytest

  deploy-backend:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: superfly/flyctl-actions/setup-flyctl@master
      - run: flyctl deploy --remote-only

  deploy-frontend:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: cloudflare/wrangler-action@v3
        with:
          apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}

Documentation Deployment

Subscribe Flow betreibt zwei separate Dokumentations-Pipelines:

Dokumentation Ziel URL Workflow
Intern (vollständig) GitHub Pages talent-factory.github.io/subscribe-flow/ Standard MkDocs Deploy
Kunden (öffentlich) Cloudflare Pages docs.subscribeflow.net .github/workflows/docs-public.yml

Die Kunden-Dokumentation wird über Cloudflare Pages deployt und enthält nur die öffentlich relevanten Seiten (Guides, API-Referenz, SDK). Die interne Dokumentation auf GitHub Pages umfasst zusätzlich Architektur-Details, Entwickler-Guides und ADRs.

Monitoring & Observability

Sentry (Error Tracking)

  • Backend: Python SDK
  • Frontend: JavaScript SDK
  • Performance monitoring
  • Release tracking

Metrics (Prometheus + Grafana)

  • API response time
  • Database query performance
  • Celery queue length
  • Resend API rate limits
  • Stripe webhook processing time

Logs (Structured Logging)

  • JSON format
  • Correlation IDs
  • Log levels (DEBUG, INFO, WARNING, ERROR)

Disaster Recovery

Backup Strategy

  • Database: Daily automated backups (7-day retention)
  • Redis: Not critical (can be rebuilt)
  • Code: Git repository (GitHub)

Recovery Time Objective (RTO)

  • Database: < 1 hour
  • Backend: < 15 minutes (redeploy)
  • Frontend: < 5 minutes (CDN cache invalidation)

Recovery Point Objective (RPO)

  • Database: < 24 hours (daily backup)
  • Redis: Acceptable data loss (cache)