Skip to content

Deployment Plan — Market Pulse (Shared Access)

Target architecture: Supabase (PostgreSQL) + Railway (FastAPI + React) + Laptop (scheduler/jobs)


Status

Phase Status
Supabase provisioning ✅ Done — market-pulse project, Northeast Asia (Tokyo)
Data migration SQLite → Supabase ✅ Done — all tables migrated
Scheduler pointing to Supabase ✅ Done — DATABASE_URL set in .env
API /api prefix + React static serving ✅ Done — Dockerfile ready
Railway deploy (API + frontend) ⏳ Blocked — needs Docker Desktop (VPN/Tailscale setup pending)

Architecture

Supabase (PostgreSQL, ap-northeast-1)
      ↑                    ↑
Laptop scheduler      Railway (FastAPI + React static)
(writes data)         (serves dashboard to users)

The scheduler runs locally on the laptop and writes to Supabase continuously. The API and React frontend will be deployed to Railway and read from the same Supabase instance. If the laptop is off, data stops updating but the dashboard stays accessible showing the last known state.


Phase 1 — Supabase ✅

Project: market-pulse, region: Northeast Asia (Tokyo), compute: Nano (free).

Connection uses the Session Pooler URL (IPv4-compatible) on port 5432:

postgresql://postgres.[ref]:[password]@aws-1-ap-northeast-1.pooler.supabase.com:5432/postgres?sslmode=require

sslmode=require is set — traffic is encrypted in transit, safe on public networks.


Phase 2 — Data Migration ✅

Migration script copies all tables from local SQLite to Supabase:

python scripts/migrate_to_postgres.py

Tables migrated (in dependency order): users, user_sessions, stock_prices, news_articles, sentiment_scores, predictions, trending_topics.

Safe to re-run — uses ON CONFLICT DO NOTHING so existing rows are skipped.

psycopg2-binary is already in requirements.txt.


Phase 3 — Deploy to Railway ⏳

Blocked on Docker Desktop working with current VPN/Tailscale setup.

Prerequisites

  • Docker Desktop installed and running
  • Railway account (railway.app)
  • Railway CLI: npm install -g @railway/cli (or use the web UI)

What to deploy

The Dockerfile at project root is a multi-stage build: 1. Node 20 builds the React frontend (frontend/dist/) 2. Python 3.11 runs uvicorn; React dist/ is copied in and served as static files 3. Single container, single port (8080)

FastAPI serves both the API (at /api/...) and the React SPA (catch-all to index.html).

Deploy via Railway web UI

  1. Go to railway.appNew project → Deploy from GitHub repo
  2. Select the repo
  3. Railway auto-detects the Dockerfile
  4. Set environment variables in Railway dashboard: DATABASE_URL=postgresql://postgres.[ref]:[password]@aws-1-ap-northeast-1.pooler.supabase.com:5432/postgres?sslmode=require FINNHUB_API_KEY=... AZURE_TRANSLATOR_KEY=... AZURE_TRANSLATOR_REGION=eastus PORT=8080
  5. Deploy — Railway gives a public URL like https://market-pulse-production.up.railway.app

Redeploy after code changes

Push to main — Railway auto-deploys on every push if GitHub integration is enabled.

Local vs production DB

Once Railway is live, the intended workflow is:

  • Local dev — omit DATABASE_URL from .env (or point it at a local Postgres). The app falls back to sqlite:///fintech.db, giving a sandboxed dev database that never touches Supabase.
  • Production (Railway)DATABASE_URL is set as an environment secret in the Railway dashboard (see step 4 above). No .env file on the server.
  • Laptop scheduler — keeps DATABASE_URL set in .env so it continues writing live data to Supabase.

This means local changes are always tested against a throwaway SQLite DB, and only the scheduler and Railway touch the shared Supabase instance.


Phase 4 — Keep Scheduler Running on Laptop

No changes needed — the scheduler already writes to Supabase via DATABASE_URL in .env.

make up           # starts scheduler + frontend dev server
python main.py --skip-initial   # scheduler only, skip initial data reload

Cost Summary

Service Free tier When you'd pay
Supabase 500 MB PostgreSQL If DB exceeds 500 MB (currently ~7 MB)
Railway $5 credit/month If usage exceeds credit (unlikely for small team)
Laptop scheduler $0 Electricity only

Expected monthly cost: $0–$5