Deployment

Run the app on your machine (host locally) or on a VPS for a public URL. This guide covers both paths, then security (secrets, HTTPS, firewall, rate limiting).

Overview

Host locally: run backend and frontend on your laptop or desktop for development and testing. Host on VPS: rent a cloud server (VPS), install the stack, and expose it via a domain with HTTPS. Both paths use the same app; the VPS path adds a reverse proxy (Nginx) and SSL.

Host locally

For local development and testing, follow the Get started guide: clone the repo, set up a Python venv and the model in the backend, run python app.py, then in another terminal run npm run dev in web/. Open http://localhost:3000. No Nginx or SSL required.

Host on VPS

To serve the app from a public URL you need a server. Rent a VPS (virtual private server), then run the FastAPI backend (ideally via Docker with built-in Nginx) and the Next.js frontend, and terminate HTTPS with Nginx.

Docker backend (FastAPI + Nginx, production-ready)

The fast-api-server/ folder ships a production stack: FastAPI + Gunicorn behind Nginx, ready to run in a single container. This is the recommended way to deploy the detection backend.

cd fast-api-server

# 1) Build image
docker build -t vcs-deepfake-fastapi .

# 2) Run container locally
docker run --rm -p 10000:10000 \
  -e PORT=10000 \
  -e ARTIFACTS_DIR=/app/artifacts \
  -e APP_WORKERS=1 \
  vcs-deepfake-fastapi

# FastAPI + Gunicorn + Nginx now listen on http://localhost:10000
# Health:  curl http://localhost:10000/health

In the frontend, set BACKEND_URL to this base URL (e.g. http://127.0.0.1:10000 locally, or https://api.your-domain.com in production).

On platforms like Render, you can deploy this same image using the provided render.yaml; Render handles HTTPS and health checks while the container's Nginx proxies to Gunicorn.

Get a VPS

Choose a provider and create a server (e.g. Ubuntu 22.04 LTS). A small instance (1 CPU, 1–2 GB RAM) is enough for light traffic; scale up if you need more. Point a domain (or subdomain) to the server’s IP via an A record.

Where to get a VPS

Sign up, create a droplet/instance, and note the IP. Use SSH to connect (e.g. ssh root@your-ip).

Prepare the server

Update the system, install Python 3, Node.js (e.g. via nvm or NodeSource), and Nginx.

apt update && apt upgrade -y
apt install -y python3 python3-pip python3-venv nginx
# Install Node.js 18+ (e.g. nvm or NodeSource)

Deploy backend (manual, non-Docker)

As an alternative to Docker, you can run the backend directly on the host. Clone the repo (or copy files), create a venv, install dependencies in fast-api-server/, and run Uvicorn or Gunicorn on a local port. Use systemd to keep it running.

cd /opt/your-app/fast-api-server
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt gunicorn

# Point ARTIFACTS_DIR at your saved model artifacts (see fast-api-server README)
export ARTIFACTS_DIR=/opt/your-app/fast-api-server/artifacts

# Run FastAPI via Gunicorn + Uvicorn workers
gunicorn -w 1 -k uvicorn.workers.UvicornWorker -b 127.0.0.1:8000 app.main:app

Create a systemd unit for gunicorn so it restarts on reboot (search for “gunicorn systemd” for a template).

Deploy frontend

In web/, set BACKEND_URL to your backend (e.g. http://127.0.0.1:8000 for a manual FastAPI deploy, or http://127.0.0.1:10000 when using the Docker + Nginx stack), then build and run with Node.

cd web
echo "BACKEND_URL=http://127.0.0.1:10000" > .env.local
npm install && npm run build
npm start   # or use a process manager (pm2)

Nginx & SSL

If you use the Docker backend, Nginx already runs inside the container and proxies to Gunicorn; you typically only need an external load balancer or your provider's TLS termination in front. For a manual host-based setup, configure Nginx as a reverse proxy: forward / to the Next.js app (e.g. port 3000) and /api to the FastAPI backend (port 8000). Use Certbot (Let’s Encrypt) for free HTTPS.

# Example: proxy to Next.js on 3000
# server_name your-domain.com;
# location / { proxy_pass http://127.0.0.1:3000; }
apt install certbot python3-certbot-nginx
certbot --nginx -d your-domain.com

Security

Harden the server and protect secrets, use HTTPS, and optionally add rate limiting.

Secrets & environment variables

Never commit API keys or secrets to the repo. Use environment variables (e.g. .env on the server, or your provider’s secret manager). Set BACKEND_URL, MODEL_ROOT, and any future API keys via env. Restrict file permissions on .env (e.g. chmod 600).

HTTPS

Always serve the app over HTTPS in production. Use Let’s Encrypt (Certbot) with Nginx. Redirect HTTP to HTTPS in the Nginx config. Set secure headers (e.g. HSTS) if needed.

Firewall

Allow only required ports: 22 (SSH), 80 (HTTP), 443 (HTTPS). Block direct access to backend (5000) and frontend (3000) from the internet; only Nginx should talk to them. Use ufw (e.g. ufw allow 22,80,443; ufw enable).

Rate limiting

Protect the API from abuse. Nginx can rate-limit by IP (e.g. limit_req_zone and limit_req). Alternatively add rate limiting in the Flask app or behind an API gateway. Document limits in the API reference when you enforce them.