If you want to build a production-ready app quickly, this is the workflow I used to create Smart Debt Planner: a FastAPI app for debt payoff simulations with a clean deployment pipeline.

This guide covers:

  • How I used prompts to build features faster
  • The exact project architecture
  • Docker + VPS deployment
  • GitHub Actions CI/CD
  • Real-world troubleshooting (SSH auth, Docker Compose mismatch, 502 errors)

πŸ”„ Latest Update (March 2026)

New additions were shipped after the initial backend-only deployment:

  • Added a dedicated React frontend module (frontend/) with Vite
  • Added interactive payoff graphs in React using Chart.js
  • Added a two-container deployment model:
    • financial-engine-frontend (Nginx static app)
    • financial-engine-app (FastAPI API)
  • Added frontend Nginx /api proxy to backend for clean same-origin requests
  • Updated GitHub Actions deployment to upload frontend files and print logs for both services

Recommended Nginx Proxy Manager target now:

  • Public web domain -> financial-engine-frontend:80
  • Optional API-only domain -> financial-engine-app:8000

πŸ“¦ Archive: Initial Backend-First Walkthrough

Why this approach works

Prompt-driven development works best when you break problems into small, verifiable steps:

  1. Define one clear requirement
  2. Generate minimal code
  3. Test immediately
  4. Deploy in small increments
  5. Capture and fix production errors fast

That loop helped me ship faster without losing control of code quality.


App overview: Smart Debt Planner

Stack used:

  • Backend: FastAPI (Python)
  • Templating: Jinja2
  • Testing: pytest
  • Containers: Docker + Docker Compose
  • Deployment: VPS + GitHub Actions + appleboy SSH/SCP actions
  • Edge + SSL: Cloudflare + Nginx Proxy Manager

Core features:

  • Debt payoff strategy simulation (/simulate)
  • Accounts + transaction ingestion
  • Category rules and transaction classification
  • UI pages:
    • / (Debt planner)
    • /transactions (transaction management)

Step 1) Bootstrap the project with prompts

I started by prompting for an MVP with explicit constraints.

Prompt example

Build a FastAPI app called Smart Debt Planner.
Requirements:
- Route / for HTML UI
- Route /simulate for debt strategy simulation
- Keep code modular (engine.py, models.py, main.py)
- Add pytest tests for simulation correctness
- Keep implementation minimal and production-friendly

Output I kept

  • Clear module split (engine.py, models.py, main.py)
  • Typed request/response models
  • Test coverage for core simulation behavior

Output I rejected/refined

  • Over-complex abstractions early on
  • Unnecessary UI features before deploying baseline

Step 2) Build the domain logic incrementally

I used prompts for one bounded feature at a time.

Prompt for strategy engine refinement

Implement and compare multiple debt payoff strategies:
- Avalanche
- Snowball
- Baseline minimums
Return months_to_payoff, total_interest_paid, and balance_over_time.

Then I layered additional strategy variants and UI metrics only after tests passed.

Prompt for transactions module

Add in-memory transaction repository with:
- account creation
- CSV ingestion endpoint
- category rules
- list/filter transactions by date and search

This kept the architecture clean while avoiding premature database complexity.


Step 3) Containerize for reproducible deployment

The first production checkpoint was Docker.

Dockerfile pattern

FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt /app/requirements.txt
RUN pip install --no-cache-dir -r /app/requirements.txt
COPY app /app/app
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]

Compose pattern

services:
  app:
    build:
      context: .
    container_name: financial-engine-app
    ports:
      - "8000:8000"
    restart: unless-stopped
    networks:
      - web

networks:
  web:
    external: true
    name: npm_default

This ensured Nginx Proxy Manager could route traffic to the app over a shared Docker network.


Step 4) Add CI/CD pipeline (GitHub Actions)

I deployed on every push to main with a guardrail-first workflow:

  1. Checkout code
  2. Install dependencies
  3. Run tests
  4. Validate deploy secrets
  5. SSH to VPS (ensure deploy dir)
  6. SCP project files
  7. SSH deploy with Docker Compose

Secrets used

  • VPS_HOST
  • VPS_USERNAME (optional, default root)
  • VPS_SSH_KEY (or fallback SSH)
  • VPS_SSH_PASSPHRASE (optional)
  • VPS_PORT (optional, default 22)
  • DEPLOY_PATH (optional, default /opt/financialEngine)

Important hardening detail

I added Compose command fallback for VPS compatibility:

  • Prefer docker compose
  • Fallback to docker-compose
  • Fail clearly if neither exists

That prevents silent environment drift issues across VPS images.


Step 5) Expose publicly with Cloudflare + NPM

Nginx Proxy Manager setup

For finance.anmious.cloud:

  • Scheme: http
  • Forward Hostname/IP: financial-engine-app
  • Forward Port: 8000

Cloudflare setup

  • DNS A record to VPS IP
  • SSL/TLS mode: Full (strict)

Real production issues I hit (and fixes)

1) SSH handshake failed in GitHub Actions

Error: unable to authenticate, attempted methods [none publickey]

Root cause: key not authorized for the target VPS user/port.

Fix:

  • Generate deploy key pair
  • Add public key to correct user’s authorized_keys
  • Store private key in GitHub secret (VPS_SSH_KEY)
  • Verify user and port alignment

2) docker compose not found

Root cause: VPS had older Docker setup.

Fix: command fallback to docker-compose.

3) Docker build failed on missing file

Root cause: file copied in Dockerfile but not uploaded by SCP action.

Fix: include all required files in upload list (e.g., pytest.ini).

4) Cloudflare 502 after container was healthy

Root cause: NPM upstream hostname had a leading space typo.

Fix: corrected proxy destination to financial-engine-app:8000.


Prompting patterns that gave the best results

1) Use strict acceptance criteria

Do not add extra features.
Keep changes minimal.
Add tests only for new logic.

2) Ask for root-cause fixes, not surface patches

Fix the root cause. Avoid temporary workarounds.

3) Force verification

After changes, run tests and report exact outcome.

4) Keep deployment prompts explicit

Update GitHub Actions to support both docker compose and docker-compose.
Fail fast with clear message if neither is available.

Copy this process for your own app

If you want to replicate this exact workflow:

  1. Build MVP routes with strict prompts
  2. Add tests before deployment
  3. Containerize app
  4. Add CI/CD with SSH + SCP actions
  5. Use NPM + Cloudflare for routing and SSL
  6. Log every production error and patch workflow/docs immediately

This gives you a fast shipping loop without sacrificing reliability.


Final takeaway

Prompt-driven development is not β€œauto-build and pray.” It works when you pair prompts with:

  • small scoped changes,
  • automated checks,
  • deterministic deployment,
  • and disciplined debugging.

That combination is how Smart Debt Planner moved from local prototype to publicly deployed app quickly and safely.

If you want, I can publish a follow-up post with a full production checklist and reusable GitHub Actions template you can copy for any FastAPI project.