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 install the backend and frontend, and put Nginx in front with SSL.
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
- DigitalOceanDroplets from $4/mo
- Linode (Akamai)Shared CPU from $5/mo
- VultrCloud compute worldwide
- AWS LightsailSimple VPS on AWS
- HetznerGood value in EU/US
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
Clone the repo (or copy files), create a venv, install dependencies, place the model and RawNetLite.py. Run with Gunicorn behind a socket or local port. Use systemd to keep it running.
cd /opt/your-app/backend python3 -m venv venv source venv/bin/activate pip install -r requirements.txt gunicorn # Place .pt in models/, RawNetLite.py in backend/ gunicorn -w 1 -b 127.0.0.1:5000 app: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:5000), then build and run with Node.
cd web echo "BACKEND_URL=http://127.0.0.1:5000" > .env.local npm install && npm run build npm start # or use a process manager (pm2)
Nginx & SSL
Configure Nginx as a reverse proxy: forward / to the Next.js app (e.g. port 3000) and /api to the backend (port 5000), or proxy only /api and serve the Next.js app separately. 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.comSecurity
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.