Documentation Index
Fetch the complete documentation index at: https://mintlify.com/teofilobetancourt/Restaurant-Equis/llms.txt
Use this file to discover all available pages before exploring further.
Production deployment of Restaurant Equis targets a Linux VPS (Ubuntu/Debian). The React SPA is compiled to a static dist/ bundle and served directly by Nginx, which also reverse-proxies every /api/* request to the FastAPI backend running on port 5000. A systemd service ensures the backend process starts on boot and automatically restarts if it crashes.
Architecture Overview
Browser
│
▼
Nginx : 80
├── / → serves /var/www/restaurantequis (compiled React SPA)
├── /assets/ → static assets with 1-year cache
├── /api/ → reverse proxy → FastAPI : 5000
├── /api/docs → reverse proxy → FastAPI /docs
└── /docs → reverse proxy → FastAPI /docs
FastAPI (Uvicorn) : 5000 ←── managed by systemd
│
▼
PostgreSQL : 5432
- Nginx listens on port 80, serves the pre-built React bundle for all non-API paths, and proxies
/api/* to 127.0.0.1:5000.
- systemd runs the Uvicorn process under the
www-data user, restarts it automatically on failure (RestartSec=3s), and loads environment variables from backend/.env.
- nip.io provides zero-configuration DNS — the VPS IP address becomes a resolvable hostname in the form
restauranteequis.<IP>.nip.io with no domain registrar required.
Step-by-step Deployment
Install system dependencies
Update the package index and install Node.js 18+, Python 3.11+, Nginx, and PostgreSQL:apt update && apt upgrade -y
# Node.js 18 (via NodeSource)
curl -fsSL https://deb.nodesource.com/setup_18.x | bash -
apt install -y nodejs
# Python 3.11+, venv, pip
apt install -y python3.11 python3.11-venv python3-pip
# Nginx
apt install -y nginx
# PostgreSQL
apt install -y postgresql postgresql-contrib
systemctl start postgresql
systemctl enable postgresql
Create the database and user
sudo -u postgres psql << 'EOF'
CREATE DATABASE restaurant_equis;
CREATE USER equis_user WITH PASSWORD 'STRONG_PASSWORD_HERE';
GRANT ALL PRIVILEGES ON DATABASE restaurant_equis TO equis_user;
\c restaurant_equis
GRANT ALL ON SCHEMA public TO equis_user;
EOF
Clone the repository
mkdir -p /opt/restaurant-equis
git clone https://github.com/teofilobetancourt/Restaurant-Equis.git /opt/restaurant-equis
cd /opt/restaurant-equis
Build the React frontend
Install Node.js dependencies and compile the production bundle:npm install
npm run build
This generates a dist/ folder containing the compiled SPA. Copy it to the Nginx web root:mkdir -p /var/www/restaurantequis
cp -r dist/* /var/www/restaurantequis/
chown -R www-data:www-data /var/www/restaurantequis
chmod -R 755 /var/www/restaurantequis
Configure the backend environment
cp /opt/restaurant-equis/backend/.env.example /opt/restaurant-equis/backend/.env
nano /opt/restaurant-equis/backend/.env
Fill in production values:DB_HOST=localhost
DB_PORT=5432
DB_NAME=restaurant_equis
DB_USER=equis_user
DB_PASSWORD=STRONG_PASSWORD_HERE
API_PORT=5000
CORS_ORIGINS=http://<your-vps-ip>,http://restauranteequis.<your-vps-ip>.nip.io
Install Python dependencies
Create a virtual environment and install all backend packages:cd /opt/restaurant-equis/backend
python3.11 -m venv venv
venv/bin/pip install --upgrade pip setuptools
venv/bin/pip install -r requirements.txt psycopg2-binary
Install and enable the systemd service
Copy the provided service unit file to the systemd directory, then enable and start it:cp /opt/restaurant-equis/backend/restaurant-equis-api.service \
/etc/systemd/system/restaurant-equis-api.service
chown -R www-data:www-data /opt/restaurant-equis
systemctl daemon-reload
systemctl enable restaurant-equis-api
systemctl start restaurant-equis-api
Verify the service is running:systemctl status restaurant-equis-api
Configure Nginx
Copy the provided Nginx configuration and activate it:cp /opt/restaurant-equis/nginx.conf \
/etc/nginx/sites-available/restaurant-equis
# Remove any conflicting default site
rm -f /etc/nginx/sites-enabled/*
ln -sf /etc/nginx/sites-available/restaurant-equis \
/etc/nginx/sites-enabled/restaurant-equis
nginx -t # verify the config is valid
Reload Nginx
Apply the new configuration:The application is now live. Visit http://restauranteequis.<your-vps-ip>.nip.io to confirm.
Nginx Configuration
The nginx.conf at the project root is the production web server configuration. It serves the React SPA, proxies all API traffic, and applies gzip compression and security headers.
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
# ── Frontend estático (React/Vite compilado) ───────────────
root /var/www/restaurantequis;
index index.html;
# ── Swagger UI / Docs de FastAPI ──────────────────────────
location /docs {
proxy_pass http://127.0.0.1:5000/docs;
proxy_http_version 1.1;
proxy_set_header Host $host;
}
location /api/docs {
proxy_pass http://127.0.0.1:5000/docs;
proxy_http_version 1.1;
proxy_set_header Host $host;
}
location /openapi.json {
proxy_pass http://127.0.0.1:5000/openapi.json;
proxy_http_version 1.1;
proxy_set_header Host $host;
}
location /api/openapi.json {
proxy_pass http://127.0.0.1:5000/openapi.json;
proxy_http_version 1.1;
proxy_set_header Host $host;
}
# ── Reverse Proxy → FastAPI en :5000 ──────────────────────
location /api/ {
proxy_pass http://127.0.0.1:5000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 60s;
proxy_connect_timeout 10s;
}
# ── SPA fallback ──────────────────────────────────────────
location / {
try_files $uri $uri/ /index.html;
}
# ── Assets con caché agresivo ─────────────────────────────
location /assets/ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# ── Compresión ────────────────────────────────────────────
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css application/javascript application/json image/svg+xml;
# ── Seguridad ─────────────────────────────────────────────
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
}
Key points:
- The
root directive must point to the directory where you copied the dist/ build output (/var/www/restaurantequis).
- The
try_files $uri $uri/ /index.html fallback ensures client-side routing in the React SPA works correctly for deep links.
- Static assets under
/assets/ are cached for one year with the immutable directive — Vite’s content-hashed filenames make this safe.
systemd Service
The backend/restaurant-equis-api.service file defines how systemd manages the Uvicorn process. It runs under the www-data user, loads environment variables from backend/.env, and restarts the process automatically if it exits unexpectedly.
[Unit]
Description=Restaurant Equis — FastAPI Backend
Documentation=https://github.com/equis/restaurant-equis
After=network.target postgresql.service
[Service]
Type=simple
User=www-data
Group=www-data
WorkingDirectory=/opt/restaurant-equis/backend
EnvironmentFile=/opt/restaurant-equis/backend/.env
ExecStart=/opt/restaurant-equis/backend/venv/bin/uvicorn main:app --host 0.0.0.0 --port 5000 --workers 1 --log-level info
Restart=always
RestartSec=3s
StandardOutput=journal
StandardError=journal
SyslogIdentifier=restaurant-equis-api
[Install]
WantedBy=multi-user.target
Useful service management commands:
# View live logs
sudo journalctl -u restaurant-equis-api -f
# View last 50 log lines
sudo journalctl -u restaurant-equis-api -n 50
# Restart after a code update
sudo systemctl restart restaurant-equis-api
# Check current status
sudo systemctl status restaurant-equis-api
Automated Deployment
The repository includes deploy_vps.py, a Python script that automates the full upload-and-restart cycle over SSH using paramiko. It:
- Uploads the compiled
dist/ frontend to /var/www/restaurantequis on the VPS
- Uploads the
backend/ directory to /opt/restaurant-equis/backend
- Uploads
nginx.conf to /etc/nginx/sites-available/restaurant-equis
- Creates a Python virtualenv if one does not exist, then installs all pip dependencies
- Copies the systemd service file and runs
systemctl daemon-reload && systemctl restart restaurant-equis-api
- Activates the Nginx site symlink and reloads Nginx
- Runs a quick
curl health-check against both the local backend and the Nginx proxy
Run the script locally after building the frontend:
npm run build
python deploy_vps.py
Before going to production, take two critical steps:
- Set a strong
DB_PASSWORD in backend/.env — the placeholder CAMBIA_ESTA_CONTRASENA must never reach a live server.
- Restrict
CORS_ORIGINS to only the exact origins your frontend is served from. Leaving it open to * or to development hostnames exposes your API to cross-origin requests from any site.
Restaurant Equis uses nip.io for DNS, which converts an IP address into a resolvable hostname without requiring a registered domain. For a VPS at 158.220.100.226, the URL becomes http://restauranteequis.158.220.100.226.nip.io. This is useful for demos, staging environments, and projects where purchasing a domain name is not yet warranted.