From 064daf47f762c89e19b44b05a10f6ea463b3d6a6 Mon Sep 17 00:00:00 2001 From: tanyar09 Date: Fri, 20 Mar 2026 15:46:00 +0000 Subject: [PATCH] documentation --- docs/DEPLOY_CPANEL_STEP_BY_STEP.md | 1152 ++++++++++++++++++++ docs/DEPLOY_FROM_SCRATCH.md | 2 + docs/FIX_ADMIN_LOGIN_WORDPRESS_REDIRECT.md | 140 +++ docs/FIX_LOGIN_REDIRECT_BUG.md | 124 +++ docs/INSTALL_PREREQUISITES_CPANEL.md | 1049 ++++++++++++++++++ 5 files changed, 2467 insertions(+) create mode 100644 docs/DEPLOY_CPANEL_STEP_BY_STEP.md create mode 100644 docs/FIX_ADMIN_LOGIN_WORDPRESS_REDIRECT.md create mode 100644 docs/FIX_LOGIN_REDIRECT_BUG.md create mode 100644 docs/INSTALL_PREREQUISITES_CPANEL.md diff --git a/docs/DEPLOY_CPANEL_STEP_BY_STEP.md b/docs/DEPLOY_CPANEL_STEP_BY_STEP.md new file mode 100644 index 0000000..e365346 --- /dev/null +++ b/docs/DEPLOY_CPANEL_STEP_BY_STEP.md @@ -0,0 +1,1152 @@ +# PunimTag cPanel Deployment - Complete Step-by-Step Guide + +This guide provides detailed, step-by-step instructions for deploying PunimTag to a cPanel hosting environment. + +--- + +## 📋 Prerequisites Checklist + +Before starting, ensure you have: + +- ✅ **cPanel access** with Terminal/SSH capabilities +- ✅ **PostgreSQL database** (NOT MySQL - PunimTag requires PostgreSQL) +- ✅ **Python 3.11.2+ or 3.12+** (3.11.2+ matches dev environment; check via CPanel Terminal) +- ✅ **Node.js 18+** (check via CPanel Terminal or contact hosting provider) +- ✅ **Redis** (for background jobs - may need hosting provider to enable) +- ✅ **Domain name** configured in cPanel +- ✅ **File Manager** access in cPanel +- ✅ **Database management** access in cPanel + +**⚠️ CRITICAL:** If PostgreSQL is not available, contact your hosting provider immediately. PunimTag **cannot** work with MySQL. + +--- + +## Step 1: Access Terminal/SSH + +### Option A: Use cPanel Web Terminal (Easiest) + +1. Log into cPanel +2. Use the search box at the top and type: `terminal` +3. Click on **"Terminal"** or **"Web Terminal"** +4. You should see a command-line interface + +### Option B: Use External SSH Client + +If cPanel doesn't have a web terminal: + +1. **Generate SSH Key** (on your local computer): + ```bash + ssh-keygen -t rsa -b 4096 + ``` + - Press Enter to accept default location + - Optionally set a passphrase + +2. **Copy your public key**: + ```bash + # Windows PowerShell: + cat C:\Users\YourName\.ssh\id_rsa.pub + + # Mac/Linux: + cat ~/.ssh/id_rsa.pub + ``` + +3. **Add SSH Key to cPanel**: + - Go to **Security** → **SSH Access** → **Manage SSH Keys** + - Click **"Import Key"** + - Paste your public key + - Click **"Import"** then **"Authorize"** + +4. **Find SSH connection details**: + - In cPanel, go to **Server Information** or **Account Information** + - Note: Hostname, Username, SSH Port (often 2222, not 22) + +5. **Connect via SSH**: + ```bash + # Try these ports (most common): + ssh -p 2222 username@your-domain.com + ssh -p 2200 username@your-domain.com + ssh -p 7822 username@your-domain.com + ``` + +**Test your connection:** +```bash +pwd # Should show your home directory +whoami # Should show your username +ls -la # Lists files +``` + +--- + +## Step 2: Check System Requirements + +In your Terminal/SSH session, check if required software is installed: + +```bash +# Check Python version (need 3.11.2+ or 3.12+) +python3 --version + +# Check Node.js version (need 18+) +node --version +npm --version + +# Check PostgreSQL client +psql --version + +# Check Redis +redis-cli ping +``` + +**If any are missing:** + +> **📘 Need to install prerequisites?** See [`INSTALL_PREREQUISITES_CPANEL.md`](./INSTALL_PREREQUISITES_CPANEL.md) for detailed instructions on installing Python 3.11.2+ (or 3.12+), Node.js, npm, PostgreSQL client, and Redis client **without sudo access**. + +- Check cPanel → **Software** → **Python Selector** (if available) +- Check cPanel → **Software** → **Node.js Selector** (if available) +- **PostgreSQL is REQUIRED** - if not available, contact hosting provider immediately +- For user-space installations (without sudo), follow the prerequisites guide above + +--- + +## Step 3: Upload Project Files + +### Option A: Upload via cPanel File Manager (Recommended for beginners) + +1. **Prepare files on your local machine**: + - Zip the entire `punimtag` project folder + - Make sure it includes: `backend/`, `admin-frontend/`, `viewer-frontend/`, `requirements.txt`, etc. + +2. **Upload via cPanel**: + - Go to **Files** → **File Manager** + - Navigate to your home directory (usually `/home/username/`) + - Click **"Upload"** + - Select your ZIP file + - Wait for upload to complete + +3. **Extract files**: + - In File Manager, find your ZIP file + - Right-click → **Extract** or click **"Extract"** button + - Extract to `/home/username/punimtag/` + - Delete the ZIP file after extraction + +### Option B: Upload via SCP (If SSH is working) + +From your local machine: + +```bash +# Navigate to where your punimtag folder is +cd /path/to/punimtag + +# Upload the entire folder +scp -r -P 2222 . username@your-domain.com:~/punimtag +``` + +### Option C: Clone via Git (If Git is available) + +In Terminal/SSH: + +```bash +cd ~ +git clone punimtag +cd punimtag +``` + +--- + +## Step 4: Set Up Databases + +### 4.1 Create Databases in cPanel + +1. Go to **Databases** → **PostgreSQL Databases** (NOT MySQL!) +2. Create **two databases**: + - Database 1: `punimtag` (cPanel may add prefix like `username_punimtag`) + - Database 2: `punimtag_auth` (may become `username_punimtag_auth`) + +3. **Note the exact database names** - cPanel often adds a username prefix! + +### 4.2 Create Database Users + +1. In **PostgreSQL Databases**, create users: + - User 1: `punimtag_user` (may become `username_punimtag_user`) + - User 2: `punimtag_auth_user` (may become `username_punimtag_auth_user`) + +2. **Set strong passwords** for each user (save them securely!) + +3. **Grant privileges**: + - Assign `punimtag_user` to `punimtag` database with **ALL PRIVILEGES** + - Assign `punimtag_auth_user` to `punimtag_auth` database with **ALL PRIVILEGES** + +### 4.3 Write Down Database Details + +Create a note with: +- Database 1 name: `_________________` +- Database 1 user: `_________________` +- Database 1 password: `_________________` +- Database 2 name: `_________________` +- Database 2 user: `_________________` +- Database 2 password: `_________________` +- Database host: Usually `localhost` or `127.0.0.1` +- Database port: Usually `5432` (PostgreSQL) + +### 4.4 Grant Privileges from Terminal (Manual PostgreSQL Install) + +If PostgreSQL was installed manually on the server (not managed via cPanel UI), you +must explicitly grant privileges to the `punimtag_user` so the backend can create +and use tables in the **main** `punimtag` database. + +Run these commands from Terminal/SSH: + +```bash +# Switch to the postgres superuser (or another superuser account) +sudo -u postgres psql +``` + +In the `psql` prompt: + +```sql +-- Give full rights on the main database to punimtag_user +GRANT ALL PRIVILEGES ON DATABASE punimtag TO punimtag_user; + +-- Connect to the main database +\c punimtag + +-- Allow schema usage and table/sequence creation +GRANT USAGE, CREATE ON SCHEMA public TO punimtag_user; + +-- Grant on all existing tables and sequences (safe even if empty) +GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO punimtag_user; +GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO punimtag_user; +``` + +Then exit: + +```sql +\q +``` + +> **Note:** For the auth database (`punimtag_auth`), privileges are granted as part +> of the auth setup scripts you will run in later steps. + +--- + +## Step 5: Configure Environment Files + +### 5.1 Navigate to Project Directory + +In Terminal/SSH: + +```bash +cd ~/punimtag +``` + +### 5.2 Create Environment Files + +```bash +# Root .env +cp .env_example .env + +# Admin frontend .env +cp admin-frontend/.env_example admin-frontend/.env + +# Viewer frontend .env +cp viewer-frontend/.env_example viewer-frontend/.env +``` + +### 5.3 Edit Root .env File + +```bash +nano .env +``` + +Update with your database details (replace ALL placeholders): + +```bash +# PostgreSQL (main database) +# Format: postgresql+psycopg2://USER:PASSWORD@HOST:PORT/DATABASE +# IMPORTANT: Use the EXACT database name from cPanel (may include username prefix!) +DATABASE_URL=postgresql+psycopg2://username_punimtag_user:YOUR_PASSWORD@localhost:5432/username_punimtag + +# PostgreSQL (auth database) +DATABASE_URL_AUTH=postgresql+psycopg2://username_punimtag_auth_user:YOUR_PASSWORD@localhost:5432/username_punimtag_auth + +# JWT Secret (generate a long random string - at least 32 characters) +SECRET_KEY=CHANGE_THIS_TO_A_LONG_RANDOM_STRING_AT_LEAST_32_CHARACTERS_LONG + +# Admin credentials (change these!) +ADMIN_USERNAME=admin +ADMIN_PASSWORD=CHANGE_THIS_TO_A_SECURE_PASSWORD + +# Photo storage (use your home directory path) +PHOTO_STORAGE_DIR=/home/username/punimtag/data/uploads + +# Redis (check if available) +REDIS_URL=redis://127.0.0.1:6379/0 +``` + +**Save:** Press `Ctrl+X`, then `Y`, then `Enter` + +**Generate a secure SECRET_KEY:** +```bash +# In Terminal, generate a random string: +openssl rand -hex 32 +# Copy the output and use it as SECRET_KEY +``` + +### 5.4 Edit Admin Frontend .env + +```bash +nano admin-frontend/.env +``` + +```bash +# Backend API base URL (must be reachable from the browser) +# If using reverse proxy at /punim-api/, use: +VITE_API_URL=/punim-api + +# If using subdomain (api.your-domain.com), use: +# VITE_API_URL=https://api.your-domain.com + +# If direct port access (not recommended for cPanel): +# VITE_API_URL=https://your-domain.com:8000 + +# Leave empty only if using Vite dev server proxy (development only) +# VITE_API_URL= +``` + +**Save:** Press `Ctrl+X`, then `Y`, then `Enter` + +### 5.5 Edit Viewer Frontend .env + +```bash +nano viewer-frontend/.env +``` + +```bash +# Database URLs (same as root .env but without "+psycopg2") +DATABASE_URL=postgresql://username_punimtag_user:YOUR_PASSWORD@localhost:5432/username_punimtag +DATABASE_URL_AUTH=postgresql://username_punimtag_auth_user:YOUR_PASSWORD@localhost:5432/username_punimtag_auth + +# NextAuth (use your actual domain with reverse proxy path if applicable) +# If using reverse proxy at /punim-viewer/, use: +NEXTAUTH_URL=https://your-domain.com/punim-viewer +AUTH_URL=https://your-domain.com/punim-viewer + +# If using subdomain (viewer.your-domain.com), use: +# NEXTAUTH_URL=https://viewer.your-domain.com +# AUTH_URL=https://viewer.your-domain.com + +NEXTAUTH_SECRET=CHANGE_THIS_TO_ANOTHER_LONG_RANDOM_STRING + +# API base URL (must match your reverse proxy path) +# If using reverse proxy at /punim-api/, use: +NEXT_PUBLIC_API_URL=/punim-api + +# Backend base URL for server-side Next.js API routes that call FastAPI +# If using reverse proxy at /punim-api/, use: +BACKEND_BASE_URL=/punim-api + +# If using subdomain (api.your-domain.com), use: +# NEXT_PUBLIC_API_URL=https://api.your-domain.com +# BACKEND_BASE_URL=https://api.your-domain.com + +# If direct port access (development only): +# BACKEND_BASE_URL=http://127.0.0.1:8000 + +# Email (optional - for password reset) +RESEND_API_KEY=your-resend-api-key-if-you-have-one +RESEND_FROM_EMAIL=noreply@your-domain.com + +# Upload directory (same as PHOTO_STORAGE_DIR in root .env) +# If using default location: +UPLOAD_DIR=/home/username/punimtag/data/uploads + +# If using separate data directory: +# UPLOAD_DIR=/home/username/punimtag-data/uploads +``` + +**Save:** Press `Ctrl+X`, then `Y`, then `Enter` + +**Generate NEXTAUTH_SECRET:** +```bash +openssl rand -hex 32 +# Copy the output and use it as NEXTAUTH_SECRET +``` + +--- + +## Step 6: Install Dependencies + +### 6.1 Install Python Dependencies + +```bash +cd ~/punimtag + +# IMPORTANT: Use system Python (not pyenv) if you encounter "_ctypes" errors +# Check which Python you're using: +which python3 +python3 --version + +# If python3 points to ~/.pyenv/shims/python3 and you get ModuleNotFoundError: No module named '_ctypes', +# use system Python instead: +# /usr/bin/python3.12 -m venv venv (or /usr/bin/python3.11, depending on what's available) + +# Create Python virtual environment +python3 -m venv venv + +# Activate virtual environment +source venv/bin/activate + +# Upgrade pip +pip install --upgrade pip + +# Install requirements +pip install -r requirements.txt +``` + +**Note:** If `pip install` fails, you may need to contact your hosting provider to install system dependencies. + +**Troubleshooting:** If you get `ModuleNotFoundError: No module named '_ctypes'` when starting the backend, your Python was compiled without libffi support. Use a system Python (`/usr/bin/python3.12` or `/usr/bin/python3.11`) instead of pyenv Python to create the venv. + +### 6.2 Install Admin Frontend Dependencies + +```bash +cd ~/punimtag/admin-frontend +npm install +``` + +### 6.3 Install Viewer Frontend Dependencies + +```bash +cd ~/punimtag/viewer-frontend +npm install + +# Generate Prisma clients (required!) +npm run prisma:generate:all +``` + +--- + +## Step 7: Set Up Auth Database + +### 7.1 Create Auth Tables + +**Option A: Automatic Setup (if database user has CREATE TABLE permissions)** + +```bash +cd ~/punimtag/viewer-frontend + +# Create auth tables (idempotent - safe to run multiple times) +npx tsx scripts/setup-auth.ts + +# Create admin user (idempotent - safe to run multiple times) +npx tsx scripts/fix-admin-user.ts +``` + +**Expected output:** +- Tables created successfully +- Admin user created/verified + +**Option B: Manual Setup (if you get "permission denied" errors)** + +If `npx tsx scripts/setup-auth.ts` fails with `ERROR: permission denied for schema public`, you need to create the tables manually using PostgreSQL superuser: + +```bash +cd ~/punimtag/viewer-frontend + +# Connect as postgres superuser +sudo -u postgres psql -d punimtag_auth + +# Run the setup script +\i '/home/photos/punimtag/viewer-frontend/setup-auth-database.sql' + +# Grant permissions to your database user +GRANT ALL PRIVILEGES ON DATABASE punimtag_auth TO punimtag_user; +\c punimtag_auth +GRANT USAGE, CREATE ON SCHEMA public TO punimtag_user; +GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO punimtag_user; +GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO punimtag_user; +GRANT SELECT, INSERT, UPDATE, DELETE ON TABLE users TO punimtag_user; +GRANT SELECT, INSERT, UPDATE, DELETE ON TABLE pending_identifications TO punimtag_user; + +# Exit psql +\q + +# Run the migration to add has_write_access column +sudo -u postgres psql -d punimtag_auth -f migrations/add-write-access-column.sql + +# Now create the admin user +cd ~/punimtag/viewer-frontend +npx tsx scripts/fix-admin-user.ts +``` + +**Expected output:** +- Tables created successfully +- Admin user created/verified + +--- + +## Step 8: Create Data Directories + +**Option A: Use default location (inside project directory)** + +```bash +cd ~/punimtag +mkdir -p data/uploads +mkdir -p data/photos +mkdir -p data/thumbnails +mkdir -p logs + +# Set proper permissions +chmod -R 755 data +chmod -R 755 logs +``` + +**Option B: Use separate data directory (recommended for production)** + +If you prefer to keep data separate from code (e.g., `~/punimtag-data/`): + +```bash +# Create data directories outside project +mkdir -p ~/punimtag-data/uploads +mkdir -p ~/punimtag-data/photos +mkdir -p ~/punimtag-data/thumbnails + +# Create logs directory in project +cd ~/punimtag +mkdir -p logs + +# Set proper permissions +chmod -R 755 ~/punimtag-data +chmod -R 755 logs +``` + +**Important:** If you use Option B, make sure to update your `.env` files: +- Root `.env`: `PHOTO_STORAGE_DIR=/home/username/punimtag-data/uploads` +- `viewer-frontend/.env`: `UPLOAD_DIR=/home/username/punimtag-data/uploads` + +--- + +## Step 9: Configure and Build Frontends + +### 9.1 Configure Admin Frontend for Reverse Proxy + +If you're using reverse proxy paths (e.g., `/punim-admin/` instead of subdomains), configure Vite: + +```bash +cd ~/punimtag +nano admin-frontend/vite.config.ts +``` + +Add `base` configuration: + +```ts +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' + +export default defineConfig({ + base: '/punim-admin/', // Match your reverse proxy path + plugins: [react()], + server: { + port: 3000, + proxy: { + '/api': { + target: 'http://127.0.0.1:8000', + changeOrigin: true, + }, + }, + }, +}) +``` + +Also update React Router basename in `admin-frontend/src/App.tsx`: + +```bash +nano admin-frontend/src/App.tsx +``` + +Find the `BrowserRouter` component and add `basename`: + +```tsx + + + +``` + +### 9.2 Configure Viewer Frontend for Reverse Proxy + +If you're using reverse proxy paths (e.g., `/punim-viewer/`), configure Next.js: + +```bash +cd ~/punimtag +nano viewer-frontend/next.config.ts +``` + +Add both `basePath` and `assetPrefix` configuration: + +```ts +import type { NextConfig } from "next"; + +const nextConfig: NextConfig = { + basePath: '/punim-viewer', // Required for API routes (/api/...) + assetPrefix: '/punim-viewer', // Required for static assets (/_next/static/...) + images: { + remotePatterns: [ + { + protocol: 'https', + hostname: '**.sharepoint.com', + }, + ], + unoptimized: process.env.NODE_ENV === 'development', + }, +}; + +export default nextConfig; +``` + +**Important:** +- `basePath` is required so Next.js API routes (`/api/search`, `/api/auth/session`) work correctly at `/punim-viewer/api/...` +- `assetPrefix` ensures static assets (`/_next/static/...`) load from the correct path +- **If your reverse proxy strips `/punim-viewer` before forwarding to Next.js**, you need to ask your hosting provider to configure the proxy to **preserve the path prefix** for Next.js routes (not strip it). The proxy should only strip paths for static file serving if needed, but Next.js needs the full path to route API requests correctly. + +### 9.3 Build Frontends + +```bash +# Build admin frontend +cd ~/punimtag/admin-frontend +npm run build + +# Build viewer frontend +cd ~/punimtag/viewer-frontend +npm run build +``` + +**Expected output:** +- Admin frontend: Creates `dist/` directory +- Viewer frontend: Creates optimized Next.js production build + +--- + +## Step 10: Install and Configure PM2 + +### 10.1 Install PM2 + +```bash +npm install -g pm2 +``` + +### 10.2 Create PM2 Config + +```bash +cd ~/punimtag +cp ecosystem.config.js.example ecosystem.config.js +nano ecosystem.config.js +``` + +**Update ALL paths** to match your deployment directory: + +```javascript +module.exports = { + apps: [ + { + name: 'punimtag-api', + script: 'venv/bin/uvicorn', + args: 'backend.app:app --host 0.0.0.0 --port 8000', + cwd: '/home/username/punimtag', // CHANGE THIS + interpreter: 'none', + env: { + PYTHONPATH: '/home/username/punimtag', // CHANGE THIS + PATH: '/home/username/punimtag/venv/bin:/usr/local/bin:/usr/bin:/bin', // CHANGE THIS + }, + error_file: '/home/username/.pm2/logs/punimtag-api-error.log', // CHANGE THIS + out_file: '/home/username/.pm2/logs/punimtag-api-out.log', // CHANGE THIS + // ... rest stays the same + }, + { + name: 'punimtag-worker', + script: 'venv/bin/python', + args: '-m backend.worker', + cwd: '/home/username/punimtag', // CHANGE THIS + interpreter: 'none', + env: { + PYTHONPATH: '/home/username/punimtag', // CHANGE THIS + PATH: '/home/username/punimtag/venv/bin:/usr/local/bin:/usr/bin:/bin', // CHANGE THIS + }, + error_file: '/home/username/.pm2/logs/punimtag-worker-error.log', // CHANGE THIS + out_file: '/home/username/.pm2/logs/punimtag-worker-out.log', // CHANGE THIS + // ... rest stays the same + }, + { + name: 'punimtag-admin', + script: './serve.sh', + cwd: '/home/username/punimtag/admin-frontend', // CHANGE THIS + interpreter: 'bash', + error_file: '/home/username/.pm2/logs/punimtag-admin-error.log', // CHANGE THIS + out_file: '/home/username/.pm2/logs/punimtag-admin-out.log', // CHANGE THIS + // ... rest stays the same + }, + { + name: 'punimtag-viewer', + script: 'npm', + args: 'run start:3001', + cwd: '/home/username/punimtag/viewer-frontend', // CHANGE THIS + interpreter: 'node', + env: { + PORT: '3001', + }, + error_file: '/home/username/.pm2/logs/punimtag-viewer-error.log', // CHANGE THIS + out_file: '/home/username/.pm2/logs/punimtag-viewer-out.log', // CHANGE THIS + // ... rest stays the same + }, + ], +}; +``` + +**Save:** Press `Ctrl+X`, then `Y`, then `Enter` + +**Important:** Replace `/home/username` with your actual home directory path (found with `echo $HOME`). + +### 10.3 Create PM2 Log Directory + +```bash +mkdir -p ~/.pm2/logs +``` + +--- + +## Step 11: Start Services with PM2 + +```bash +cd ~/punimtag + +# Start all services +pm2 start ecosystem.config.js + +# Save PM2 configuration (so it persists) +pm2 save + +# Check status +pm2 status +``` + +**Expected output:** +``` +┌─────┬─────────────────────┬─────────┬─────────┬──────────┐ +│ id │ name │ status │ restart │ uptime │ +├─────┼─────────────────────┼─────────┼─────────┼──────────┤ +│ 0 │ punimtag-api │ online │ 0 │ 5s │ +│ 1 │ punimtag-worker │ online │ 0 │ 5s │ +│ 2 │ punimtag-admin │ online │ 0 │ 5s │ +│ 3 │ punimtag-viewer │ online │ 0 │ 5s │ +└─────┴─────────────────────┴─────────┴─────────┴──────────┘ +``` + +### 11.1 Set PM2 to Start on Reboot (Optional) + +```bash +pm2 startup +# Follow the instructions shown (may require sudo) +``` + +--- + +## Step 12: Verify Services Are Running + +### 12.1 Check PM2 Status + +```bash +pm2 status +pm2 logs --lines 50 +``` + +### 12.2 Test Backend API + +```bash +curl http://localhost:8000/api/v1/health +``` + +**Expected response:** +```json +{"status":"ok"} +``` + +### 12.3 Test Admin Frontend + +```bash +curl http://localhost:3000 +``` + +**Expected:** HTML content (should return the admin interface HTML) + +### 12.4 Test Viewer Frontend + +```bash +curl http://localhost:3001/api/health +``` + +**Expected response:** +```json +{"status":"ok"} +``` + +--- + +## Step 13: Set Up Reverse Proxy (For Web Access) + +cPanel hosting typically doesn't allow direct port access. You need to set up a reverse proxy. + +### Option A: Contact Hosting Provider (Recommended for cPanel) + +Most cPanel hosts disable `mod_proxy` in user `.htaccess` files for security. Contact your hosting provider to set up reverse proxy rules at the server level. + +**Request the following reverse proxy configuration:** + +``` +- https://your-domain.com/punim-api/* → http://127.0.0.1:8000/api/* +- https://your-domain.com/punim-admin/* → http://127.0.0.1:3000/* +- https://your-domain.com/punim-viewer/* → http://127.0.0.1:3001/* +``` + +**Important notes for your hosting provider:** +- The proxy should preserve the full path when forwarding (especially for `/punim-viewer/_next/...` assets) +- For the API, the proxy maps `/punim-api/` to the root of FastAPI (not `/api/`), since FastAPI serves some routes at root (`/docs`, `/health`) and others under `/api/v1/` +- This means API endpoints will be accessible at `/punim-api/api/v1/...` from the browser + +**After the proxy is configured:** +- Update `admin-frontend/.env`: `VITE_API_URL=/punim-api` +- Update `viewer-frontend/.env`: `NEXT_PUBLIC_API_URL=/punim-api` +- Update `viewer-frontend/.env`: `NEXTAUTH_URL=https://your-domain.com/punim-viewer` and `AUTH_URL=https://your-domain.com/punim-viewer` +- Rebuild frontends (Step 9) and restart PM2 services + +### Option B: Use cPanel Subdomains + +1. **Create subdomains in cPanel**: + - Go to **Domains** → **Create A New Domain** (or **Subdomains** if available) + - Create: + - `admin.your-domain.com` → points to admin frontend + - `viewer.your-domain.com` → points to viewer frontend + - `api.your-domain.com` → points to backend API + +2. **Configure reverse proxy** (contact hosting provider or use `.htaccess`) + +**Note:** Some cPanel versions don't have a "Subdomains" option. Use "Create A New Domain" and enter subdomain names like `admin.your-domain.com`. + +### Option C: Configure Apache .htaccess (May Not Work) + +**⚠️ Warning:** Most cPanel hosts disable `mod_proxy` in user `.htaccess` files. This option will likely fail, but you can try: + +Create/edit `.htaccess` in your main domain's `public_html`: + +```apache +# PunimTag reverse proxy rules +RewriteEngine On + +# Proxy API requests to backend (MUST come first!) +RewriteCond %{REQUEST_URI} ^/punim-api/ +RewriteRule ^punim-api/(.*)$ http://localhost:8000/api/$1 [P,L] + +# Proxy admin frontend +RewriteCond %{REQUEST_URI} ^/punim-admin/ +RewriteRule ^punim-admin/(.*)$ http://localhost:3000/$1 [P,L] + +# Proxy viewer frontend +RewriteCond %{REQUEST_URI} ^/punim-viewer/ +RewriteRule ^punim-viewer/(.*)$ http://localhost:3001/$1 [P,L] +``` + +**Note:** If you get 404 errors or WordPress intercepts these paths, `mod_proxy` is disabled. Contact your hosting provider (Option A). + +--- + +## Step 14: Set Up SSL Certificate + +1. In cPanel → **Security** → **SSL/TLS Status** +2. Install Let's Encrypt certificate for your domain +3. Update environment variables to use `https://` URLs: + - `viewer-frontend/.env`: Change `NEXTAUTH_URL` and `AUTH_URL` to `https://` + +--- + +## Step 15: Test Deployment + +### 15.1 Access Admin Interface + +1. Open browser: `https://your-domain.com/punim-admin/` (or your configured reverse proxy path) +2. Login with credentials from `.env`: + - Username: `admin` (or what you set in `ADMIN_USERNAME`) + - Password: (from `ADMIN_PASSWORD` in `.env`) + +**Expected:** You should see the PunimTag admin dashboard with photo management features. + +### 15.2 Access Viewer Interface + +1. Open browser: `https://your-domain.com/punim-viewer/` (or your configured reverse proxy path) +2. Test registration/login functionality +3. Try uploading a photo (if you have write access) + +**Expected:** You should see the photo viewer interface with search and filter options. + +### 15.3 Access API Documentation + +1. Open browser: `https://your-domain.com/punim-api/docs` (or your configured reverse proxy path) + - If using subdomain: `https://api.your-domain.com/docs` + - If direct port access: `http://your-domain.com:8000/docs` (usually not available on cPanel) + +**Expected:** You should see the FastAPI Swagger UI with all available API endpoints. + +--- + +## Step 16: Running PunimTag (Daily Operations) + +### Start Services + +```bash +cd ~/punimtag +pm2 start ecosystem.config.js +``` + +### Stop Services + +```bash +pm2 stop all +``` + +### Restart Services + +```bash +pm2 restart all +``` + +### View Logs + +```bash +# All services +pm2 logs + +# Specific service +pm2 logs punimtag-api --lines 100 +pm2 logs punimtag-worker --lines 100 +pm2 logs punimtag-admin --lines 100 +pm2 logs punimtag-viewer --lines 100 +``` + +### Check Status + +```bash +pm2 status +pm2 monit # Real-time monitoring +``` + +--- + +## Troubleshooting + +### Services Won't Start + +```bash +# Check PM2 logs +pm2 logs --lines 200 + +# Check specific service +pm2 logs punimtag-api --lines 50 + +# Check PM2 process details +pm2 describe punimtag-api + +# Restart services +pm2 restart all + +# Check if ports are in use +lsof -i :8000 +lsof -i :3000 +lsof -i :3001 +``` + +**Common issues:** +- **PM2 shows "online" but service doesn't respond:** Check that `cwd` in `ecosystem.config.js` matches your actual deployment directory (e.g., `/home/username/punimtag`, not `/opt/punimtag`) +- **API shows "connection refused":** Verify `PYTHONPATH` and `PATH` in PM2 config point to the correct venv location +- **Viewer shows 404 for assets:** Ensure `assetPrefix` is set in `next.config.ts` and matches your reverse proxy path + +### Database Connection Errors + +```bash +# Test database connection +psql -h localhost -U YOUR_DB_USER -d YOUR_DB_NAME + +# Check .env files +cat .env +cat viewer-frontend/.env + +# Verify database credentials match cPanel exactly +``` + +**Common issues:** +- Database name includes username prefix (e.g., `username_punimtag` not `punimtag`) +- Wrong password +- Database user doesn't have privileges + +### Port Already in Use + +```bash +# Find what's using the port +lsof -i :8000 +lsof -i :3000 +lsof -i :3001 + +# Kill process if needed +kill -9 + +# Or restart PM2 +pm2 restart all +``` + +### Permission Errors + +```bash +# Fix permissions +chmod -R 755 ~/punimtag +chmod +x ~/punimtag/scripts/*.sh +chmod +x ~/punimtag/admin-frontend/serve.sh +``` + +### Redis Not Available + +```bash +# Check if Redis is running +redis-cli ping + +# If not available, contact hosting provider +# Or use external Redis service and update REDIS_URL in .env +``` + +### Python/Node Version Issues + +```bash +# Check versions +python3 --version # Need 3.11.2+ or 3.12+ +node --version # Need 18+ + +# Contact hosting provider if versions are too old +``` + +### Python "_ctypes" Module Error + +If you get `ModuleNotFoundError: No module named '_ctypes'` when starting the backend: + +```bash +# Check which Python you're using +which python3 + +# If it points to ~/.pyenv/shims/python3, use system Python instead +# Find available system Pythons: +ls -1 /usr/bin/python3* + +# Recreate venv with system Python (e.g., python3.12) +cd ~/punimtag +mv venv venv-bad # Backup old venv +/usr/bin/python3.12 -m venv venv # Use system Python +source venv/bin/activate +pip install --upgrade pip +pip install -r requirements.txt +``` + +### Frontend Shows Blank Page or 404 Errors + +**Admin frontend blank page:** +1. Verify `base: '/punim-admin/'` is set in `admin-frontend/vite.config.ts` +2. Verify `basename="/punim-admin"` is set in `admin-frontend/src/App.tsx` BrowserRouter +3. Check `VITE_API_URL=/punim-api` in `admin-frontend/.env` +4. Rebuild: `cd ~/punimtag/admin-frontend && npm run build` +5. Restart: `pm2 restart punimtag-admin` + +**Viewer frontend 404 for assets or API routes:** +1. Verify `assetPrefix: '/punim-viewer'` is set in `viewer-frontend/next.config.ts` (NOT `basePath` - proxy strips the path) +2. Check `NEXT_PUBLIC_API_URL=/punim-api` in `viewer-frontend/.env` +3. Check `NEXTAUTH_URL=https://your-domain.com/punim-viewer` and `AUTH_URL=https://your-domain.com/punim-viewer` in `viewer-frontend/.env` +4. **If proxy strips `/punim-viewer` before forwarding:** + - All client-side `fetch('/api/...')` calls must be updated to use `/punim-viewer/api/...` + - A helper function `getApiPath()` is available in `lib/api-path.ts` for this + - NextAuth routes (`/api/auth/session`) may need `basePath: '/punim-viewer'` in NextAuth config +5. Clean rebuild: `cd ~/punimtag/viewer-frontend && rm -rf .next && npm run build` +6. Restart: `pm2 restart punimtag-viewer` + +**Note:** If your reverse proxy strips `/punim-viewer` before forwarding to Next.js, you have two options: +- **Option A (Recommended):** Ask hosting provider to preserve `/punim-viewer` prefix when forwarding to Next.js (only strip for static file serving if needed) +- **Option B:** Update all client-side fetch calls to include `/punim-viewer` prefix manually (helper function provided) + +**API calls return 404:** +- Verify reverse proxy is configured correctly (contact hosting provider) +- Check that `VITE_API_URL` and `NEXT_PUBLIC_API_URL` match your reverse proxy path +- Test API directly: `curl http://localhost:8000/api/v1/health` + +### PM2 Not Persisting After Reboot + +```bash +# Set up PM2 startup +pm2 startup +# Follow instructions (may require sudo or hosting provider assistance) +pm2 save +``` + +--- + +## Quick Reference Commands + +```bash +# Navigate to project +cd ~/punimtag + +# Start all services +pm2 start ecosystem.config.js + +# Stop all services +pm2 stop all + +# Restart all services +pm2 restart all + +# View logs +pm2 logs + +# Check status +pm2 status + +# Monitor resources +pm2 monit + +# Save PM2 config +pm2 save +``` + +--- + +## Next Steps After Deployment + +- [ ] Set up automatic backups (database and photos) +- [ ] Configure monitoring and alerts +- [ ] Set up log rotation +- [ ] Test all features thoroughly +- [ ] Document your specific configuration +- [ ] Set up regular maintenance schedule + +--- + +## Getting Help + +If you encounter issues: + +1. **Check logs**: `pm2 logs` +2. **Verify environment variables**: `cat .env` +3. **Test database connectivity**: `psql -h localhost -U user -d database` +4. **Contact hosting provider** for: + - SSH access issues + - Redis installation + - Port access + - PostgreSQL availability + - Reverse proxy setup +5. **Review other guides**: + - `docs/DEPLOY_CPANEL.md` - General cPanel guide + - `docs/DEPLOY_FROM_SCRATCH.md` - Fresh install guide + +--- + +**Congratulations!** You've successfully deployed PunimTag to cPanel! 🎉 + diff --git a/docs/DEPLOY_FROM_SCRATCH.md b/docs/DEPLOY_FROM_SCRATCH.md index 5a3eae0..69f8e56 100644 --- a/docs/DEPLOY_FROM_SCRATCH.md +++ b/docs/DEPLOY_FROM_SCRATCH.md @@ -1,5 +1,7 @@ # Deploying PunimTag (From Scratch, Simple) +> **Deploying via CPanel?** See [`DEPLOY_CPANEL.md`](./DEPLOY_CPANEL.md) for CPanel-specific instructions. + This guide is for a **fresh install** where the databases do **not** need to be migrated. You will start with **empty PostgreSQL databases** and deploy the app from a copy of the repo (e.g., downloaded from **SharePoint**). diff --git a/docs/FIX_ADMIN_LOGIN_WORDPRESS_REDIRECT.md b/docs/FIX_ADMIN_LOGIN_WORDPRESS_REDIRECT.md new file mode 100644 index 0000000..e13e86b --- /dev/null +++ b/docs/FIX_ADMIN_LOGIN_WORDPRESS_REDIRECT.md @@ -0,0 +1,140 @@ +# Fix Admin Login WordPress Redirect + +## Problem +Login redirects to WordPress (`wp-login.php`) instead of calling FastAPI. + +## Root Cause +The admin frontend is calling `/api/v1/auth/login` (relative path) which WordPress intercepts. It should call `/punim-api/api/v1/auth/login`. + +This happens because **Vite environment variables are injected at BUILD TIME**, not runtime. If you changed `.env` but didn't rebuild, the old code is still running. + +## Solution + +### Step 1: Verify Environment Variable + +```bash +cd ~/punimtag/admin-frontend +cat .env | grep VITE_API_URL +``` + +Should show: +``` +VITE_API_URL=/punim-api +``` + +If missing or wrong: +```bash +nano admin-frontend/.env +# Add: VITE_API_URL=/punim-api +# Save: Ctrl+X, Y, Enter +``` + +### Step 2: REBUILD Admin Frontend (CRITICAL!) + +**This is required!** Vite reads `.env` during build: + +```bash +cd ~/punimtag/admin-frontend +npm run build +``` + +Wait for completion. You should see: +``` +✓ built in X.XXs +``` + +### Step 3: Verify Build Contains Correct URL + +```bash +cd ~/punimtag/admin-frontend +grep -r "punim-api" dist/ | head -3 +``` + +Should show `/punim-api` in JavaScript files. + +### Step 4: Restart Admin Service + +```bash +pm2 restart punimtag-admin +``` + +### Step 5: Clear Browser Cache + +- **Hard refresh:** `Ctrl+Shift+R` (Windows/Linux) or `Cmd+Shift+R` (Mac) +- Or open DevTools → Network tab → check "Disable cache" + +### Step 6: Verify Request URL + +1. Open admin frontend: `https://jrccphotos.org/punim-admin/` +2. Open DevTools → Network tab +3. Try to login +4. Check the POST request URL: + - ✅ **Correct:** `https://jrccphotos.org/punim-api/api/v1/auth/login` + - ❌ **Wrong:** `https://jrccphotos.org/api/v1/auth/login` (means rebuild didn't work) + +## Why This Happens + +Vite environment variables work like this: + +1. **Build time:** Vite reads `VITE_API_URL` from `.env` and replaces `import.meta.env.VITE_API_URL` in code +2. **Runtime:** The built JavaScript has the actual value hardcoded + +If you change `.env` but don't rebuild: +- Old build still has old value +- New `.env` value is ignored +- WordPress intercepts relative paths + +## Troubleshooting + +### Still redirects to WordPress after rebuild? + +1. **Check if dist/ folder was updated:** + ```bash + ls -lt ~/punimtag/admin-frontend/dist/ | head -5 + ``` + Should show recent timestamps. + +2. **Check PM2 is serving from dist/:** + ```bash + pm2 logs punimtag-admin --lines 20 + ``` + Should show it's serving from `dist/` directory. + +3. **Check serve.sh script:** + ```bash + cat ~/punimtag/admin-frontend/serve.sh + ``` + Should serve from `dist/` directory. + +4. **Verify VITE_API_URL in built code:** + ```bash + cd ~/punimtag/admin-frontend + grep -o "punim-api" dist/assets/*.js | head -1 + ``` + Should find `/punim-api` in the built files. + +### Build fails? + +- Check Node.js version: `node --version` (need 18+) +- Check npm install: `cd admin-frontend && npm install` +- Check for errors: `npm run build 2>&1 | tail -20` + +## Quick Checklist + +- [ ] `VITE_API_URL=/punim-api` in `admin-frontend/.env` +- [ ] Ran `npm run build` in `admin-frontend/` directory +- [ ] Build completed successfully (no errors) +- [ ] Verified `/punim-api` appears in `dist/` files +- [ ] Restarted PM2: `pm2 restart punimtag-admin` +- [ ] Cleared browser cache (hard refresh) +- [ ] Checked browser Network tab - request goes to `/punim-api/api/v1/auth/login` + +--- + +**Remember:** Every time you change `VITE_API_URL` in `.env`, you MUST rebuild! + + + + + + diff --git a/docs/FIX_LOGIN_REDIRECT_BUG.md b/docs/FIX_LOGIN_REDIRECT_BUG.md new file mode 100644 index 0000000..92e31e0 --- /dev/null +++ b/docs/FIX_LOGIN_REDIRECT_BUG.md @@ -0,0 +1,124 @@ +# Fix Login Redirect Bug - Client Server + +## Problem +When login fails (401 error), the code redirects to `/login` which WordPress intercepts. It should redirect to `/punim-admin/login`. + +## Root Cause +In `admin-frontend/src/api/client.ts`, the error handler uses: +```typescript +window.location.href = '/login' // ❌ Wrong - goes to domain root +``` + +This should be: +```typescript +window.location.href = '/punim-admin/login' // ✅ Correct +``` + +## Fix on Client Server + +### Option 1: Quick Fix (Edit Built File - Temporary) + +**⚠️ Warning:** This will be overwritten on next rebuild! + +```bash +cd ~/punimtag/admin-frontend/dist/assets + +# Find the JavaScript file +JS_FILE=$(ls index-*.js | head -1) + +# Backup +cp "$JS_FILE" "$JS_FILE.backup" + +# Replace /login with /punim-admin/login (only in redirect contexts) +sed -i 's|window.location.href="/login"|window.location.href="/punim-admin/login"|g' "$JS_FILE" +sed -i "s|window.location.href='/login'|window.location.href='/punim-admin/login'|g" "$JS_FILE" + +# Restart +pm2 restart punimtag-admin +``` + +### Option 2: Fix Source Code (Permanent) + +Edit the source file on client server: + +```bash +cd ~/punimtag/admin-frontend/src/api +nano client.ts +``` + +Find these lines (around lines 44 and 65): +```typescript +window.location.href = '/login' +``` + +Replace with: +```typescript +window.location.href = '/punim-admin/login' +``` + +Then rebuild: +```bash +cd ~/punimtag/admin-frontend +npm run build +pm2 restart punimtag-admin +``` + +## Verification + +After fix: +1. Try to login with wrong credentials +2. Should stay on admin frontend (show error message) +3. Should NOT redirect to WordPress +4. Check browser URL - should be `https://jrccphotos.org/punim-admin/login` + +## What to Change + +In `admin-frontend/src/api/client.ts`, change: + +**Line ~44:** +```typescript +// OLD: +window.location.href = '/login' + +// NEW: +window.location.href = '/punim-admin/login' +``` + +**Line ~65:** +```typescript +// OLD: +window.location.href = '/login' + +// NEW: +window.location.href = '/punim-admin/login' +``` + +**Line ~42 (check):** +```typescript +// OLD: +const isLoginPage = window.location.pathname === '/login' + +// NEW: +const isLoginPage = window.location.pathname === '/punim-admin/login' || window.location.pathname === '/punim-admin/' +``` + +## Better Solution (Future) + +Use a helper function to get the base path dynamically: +```typescript +const getBasePath = () => { + const path = window.location.pathname; + if (path.startsWith('/punim-admin')) return '/punim-admin'; + return ''; +}; + +window.location.href = `${getBasePath()}/login`; +``` + +But for now, the hardcoded `/punim-admin/login` fix will work. + + + + + + diff --git a/docs/INSTALL_PREREQUISITES_CPANEL.md b/docs/INSTALL_PREREQUISITES_CPANEL.md new file mode 100644 index 0000000..750db8e --- /dev/null +++ b/docs/INSTALL_PREREQUISITES_CPANEL.md @@ -0,0 +1,1049 @@ +# Installing Prerequisites in cPanel + +> **⚠️ IMPORTANT:** This guide has two paths: +> - **If you have sudo access:** Follow the [Quick Install with Sudo](#quick-install-with-sudo-access) section below +> - **If you don't have sudo access:** Follow the [Manual Installation Without Sudo](#manual-installation-without-sudo-access) section + +--- + +## Quick Install with Sudo Access + +**If you have sudo/root access, this is the easiest way to install everything!** + +### Detect Your OS + +First, check what Linux distribution you're using: + +```bash +# Check OS +cat /etc/os-release + +# Check package manager +which dnf yum apt-get 2>/dev/null +``` + +### For RHEL/CentOS/AlmaLinux 8+ (dnf/yum) + +```bash +# Update system packages +sudo dnf update -y + +# Install build tools and dependencies +sudo dnf groupinstall -y "Development Tools" +sudo dnf install -y \ + gcc gcc-c++ make \ + openssl-devel zlib-devel readline-devel libffi-devel sqlite-devel \ + redis \ + python3-tkinter + +# Install PostgreSQL 12+ (required - default repos may have older versions) +# Option 1: Install PostgreSQL 12 from official PostgreSQL repository +sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-x86_64/pgdg-redhat-repo-latest.noarch.rpm +sudo dnf -qy module disable postgresql +sudo dnf install -y postgresql12 postgresql12-server postgresql12-contrib + +# Option 2: If PostgreSQL 16 is preferred (latest stable) +# sudo dnf install -y postgresql16 postgresql16-server postgresql16-contrib + +# Install Python 3.11+ (if not already installed) +sudo dnf install -y python3.11 python3.11-devel python3.11-pip +# Or for Python 3.12: +# sudo dnf install -y python3.12 python3.12-devel python3.12-pip + +# Install Node.js 20 (using NodeSource repository) +curl -fsSL https://rpm.nodesource.com/setup_20.x | sudo bash - +sudo dnf install -y nodejs + +# Initialize and start PostgreSQL 12 +# IMPORTANT: Use sudo and specify version if using PostgreSQL 12 +sudo /usr/pgsql-12/bin/postgresql-12-setup initdb +sudo systemctl enable postgresql-12 +sudo systemctl start postgresql-12 + +# If using PostgreSQL 16, use: +# sudo /usr/pgsql-16/bin/postgresql-16-setup initdb +# sudo systemctl enable postgresql-16 +# sudo systemctl start postgresql-16 + +# Add PostgreSQL binaries to PATH (for PostgreSQL 12) +echo 'export PATH="/usr/pgsql-12/bin:$PATH"' >> ~/.bashrc +source ~/.bashrc + +# Start Redis +sudo systemctl enable redis +sudo systemctl start redis + +# Verify installations +python3 --version +node --version +npm --version +psql --version +redis-cli --version + +# Test Redis +redis-cli ping +# Should respond: PONG +``` + +### For Ubuntu/Debian (apt) + +```bash +# Update system packages +sudo apt update +sudo apt upgrade -y + +# Install build tools and dependencies +sudo apt install -y \ + build-essential \ + gcc g++ make \ + libssl-dev zlib1g-dev libreadline-dev libffi-dev libsqlite3-dev \ + postgresql postgresql-contrib \ + redis-server \ + python3 python3-pip python3-venv python3-dev python3-tk + +# Install Python 3.11+ (if not already installed) +sudo apt install -y python3.11 python3.11-venv python3.11-dev +# Or for Python 3.12: +# sudo apt install -y python3.12 python3.12-venv python3.12-dev + +# Install Node.js 20 (using NodeSource repository) +curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - +sudo apt install -y nodejs + +# Start PostgreSQL +sudo systemctl enable postgresql +sudo systemctl start postgresql + +# Start Redis +sudo systemctl enable redis-server +sudo systemctl start redis-server + +# Verify installations +python3 --version +node --version +npm --version +psql --version +redis-cli --version + +# Test Redis +redis-cli ping +# Should respond: PONG +``` + +### Set Up PostgreSQL Databases + +After PostgreSQL is installed and running, create the databases: + +```bash +# Switch to postgres user +sudo -u postgres psql + +# In PostgreSQL prompt, run: +CREATE DATABASE punimtag; +CREATE DATABASE punimtag_auth; +CREATE USER punimtag_user WITH PASSWORD 'your_secure_password_here'; +GRANT ALL PRIVILEGES ON DATABASE punimtag TO punimtag_user; +GRANT ALL PRIVILEGES ON DATABASE punimtag_auth TO punimtag_user; +\q + +# Test connection +psql -U punimtag_user -d punimtag -h localhost +# Enter password when prompted +``` + +**Note:** Replace `'your_secure_password_here'` with a strong password. You'll use this in your `.env` file. + +### Install PM2 (Process Manager) - Optional but Recommended + +```bash +sudo npm install -g pm2 +pm2 --version +``` + +### Verify Everything is Working + +```bash +# Python +python3 --version +pip3 --version + +# Node.js +node --version +npm --version + +# PostgreSQL +psql --version +psql -U punimtag_user -d punimtag -h localhost -c "SELECT version();" + +# Redis +redis-cli ping +# Should respond: PONG + +# PM2 (if installed) +pm2 --version +``` + +**✅ You're done!** All prerequisites are installed. Continue with the deployment guide. + +--- + +## Manual Installation Without Sudo Access + +This guide shows how to install Python 3.11.2+ (or 3.12+), Node.js, npm, PostgreSQL client, and Redis client in a cPanel environment **without sudo/root access**. + +--- + +## Python Version Requirements + +**Important:** Your dev environment uses **Python 3.11.2**, which is perfectly fine! + +- ✅ **Python 3.11.2+** - Works great (matches your dev environment) +- ✅ **Python 3.12+** - Recommended for latest features, but not required +- ❌ **Python 3.6.8** - Too old, needs upgrade + +**Recommendation:** Install **Python 3.11.9** (latest 3.11.x) to match your dev environment, or **Python 3.12.7** if you want the latest version. + +**Note:** The `install.sh` script checks for Python 3.12+, but the code itself works fine with Python 3.11.2+. If you use Python 3.11, you can either: +- Skip the `install.sh` script and install dependencies manually +- Or temporarily modify the version check in `install.sh` (change line 35 from `< 12` to `< 11`) + +--- + +## Current Status Check + +First, check what you currently have: + +```bash +# Check Python version +python3 --version +# Output: Python 3.6.8 (too old - need 3.11.2+ or 3.12+) + +# Check Node.js +node --version +# Output: command not found + +# Check npm +npm --version +# Output: command not found + +# Check PostgreSQL client +psql --version +# Output: command not found + +# Check Redis client +redis-cli --version +# Output: command not found +``` + +--- + +## Step 1: Install Python 3.11.2+ or 3.12+ Using pyenv (Recommended) + +**pyenv** allows you to install Python versions in your home directory without sudo. + +**Choose your version:** +- **Python 3.11.9** (recommended to match dev environment) +- **Python 3.12.7** (latest version, also works) + +### 1.1 Install Required Build Dependencies + +First, check if you have build tools. If not, you may need to contact your hosting provider: + +```bash +# Check if gcc is available +gcc --version + +# Check if make is available +make --version + +# Check if openssl-devel is available (needed for Python) +openssl version +``` + +**Possible Issues:** + +**If you get "Permission denied" on gcc:** +- This means gcc exists but you don't have permission to execute it +- **Solution 1:** Contact your hosting provider to grant you access to gcc +- **Solution 2:** Skip pyenv compilation and use pre-built Python binaries (see Alternative method below) +- **Solution 3:** Ask hosting provider to install Python 3.11+ system-wide + +**If you get "command not found":** +- Build tools are not installed +- Contact your hosting provider to install: + - `gcc` (C compiler) + - `make` (build tool) + - `openssl-devel` or `libssl-dev` (for SSL support) + - `zlib-devel` or `zlib1g-dev` (for compression) + - `readline-devel` or `libreadline-dev` (for better Python REPL) + +**If build tools are not available, you have these options:** +1. **Contact hosting provider** - Ask them to install Python 3.11+ system-wide (easiest!) +2. **Use pre-built binaries** - Download portable Python (see Alternative method below) +3. **Use cPanel Python Selector** - Check if cPanel has a Python version selector + +### 1.2 Install pyenv + +**⚠️ IMPORTANT:** If you got "Permission denied" on gcc, pyenv won't be able to compile Python. Skip to the "Alternative: Pre-built Python Binary" section below, or contact your hosting provider first. + +```bash +# Navigate to home directory +cd ~ + +# Install pyenv +curl https://pyenv.run | bash + +# Add pyenv to your shell profile +echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc +echo 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc +echo 'eval "$(pyenv init -)"' >> ~/.bashrc + +# Reload shell configuration +source ~/.bashrc + +# Verify pyenv is installed +pyenv --version +``` + +**If pyenv install fails due to missing gcc/make:** +- You'll need build tools or use the alternative method below +- Contact hosting provider to enable gcc access or install Python system-wide + +### 1.3 Install Python Using pyenv + +**Option A: Install Python 3.11.9 (matches dev environment - recommended)** + +```bash +# List available Python 3.11 versions +pyenv install --list | grep " 3.11" + +# Install Python 3.11.9 (latest 3.11.x) +pyenv install 3.11.9 + +# This will take 5-10 minutes. Be patient! + +# Set Python 3.11.9 as global default +pyenv global 3.11.9 + +# Verify installation +python3 --version +# Should show: Python 3.11.9 + +# Verify pip is available +pip3 --version +``` + +**Option B: Install Python 3.12.7 (latest version)** + +```bash +# List available Python 3.12 versions +pyenv install --list | grep " 3.12" + +# Install Python 3.12.7 (latest 3.12.x) +pyenv install 3.12.7 + +# This will take 5-10 minutes. Be patient! + +# Set Python 3.12.7 as global default +pyenv global 3.12.7 + +# Verify installation +python3 --version +# Should show: Python 3.12.7 + +# Verify pip is available +pip3 --version +``` + +**If pyenv install fails**, you may need to: +1. Contact hosting provider to install build dependencies +2. Or try alternative method below (portable Python) + +--- + +## Alternative: Solutions When Build Tools Are Not Available + +If you can't use gcc/make (permission denied or not installed), try these options: + +### Option 1: Contact Hosting Provider (EASIEST - Recommended) + +**Ask your hosting provider to:** +1. Install Python 3.11+ system-wide +2. Or grant you access to gcc/make +3. Or check if cPanel has a "Python Selector" feature + +**This is the easiest solution!** Most hosting providers can do this quickly. + +### Option 2: Use cPanel Python Selector (If Available) + +Some cPanel installations have a Python version selector: + +1. In cPanel, go to **Software** → **Python Selector** (or search for "Python") +2. If available, select Python 3.11+ or 3.12+ +3. Create a virtual environment using the selected Python version + +### Option 3: Download Pre-compiled Python Binary (Advanced) + +**⚠️ Note:** This still requires compilation, so it won't work if gcc has permission issues. + +If you have gcc access but pyenv failed, you can compile from source: + +**Python 3.11.9 (matches dev environment)** + +```bash +cd ~ + +# Check your architecture first: +uname -m +# If x86_64, use: +wget https://www.python.org/ftp/python/3.11.9/Python-3.11.9.tgz + +# Extract +tar -xzf Python-3.11.9.tgz +cd Python-3.11.9 + +# Configure for user installation +./configure --prefix=$HOME/python3.11 --enable-optimizations + +# Compile (this takes time and requires gcc!) +make -j$(nproc) + +# Install to home directory +make install + +# Add to PATH +echo 'export PATH="$HOME/python3.11/bin:$PATH"' >> ~/.bashrc +source ~/.bashrc + +# Verify +python3 --version +``` + +**Python 3.12.7 (latest version)** + +```bash +cd ~ + +# Check your architecture first: +uname -m +# If x86_64, use: +wget https://www.python.org/ftp/python/3.12.7/Python-3.12.7.tgz + +# Extract +tar -xzf Python-3.12.7.tgz +cd Python-3.12.7 + +# Configure for user installation +./configure --prefix=$HOME/python3.12 --enable-optimizations + +# Compile (this takes time and requires gcc!) +make -j$(nproc) + +# Install to home directory +make install + +# Add to PATH +echo 'export PATH="$HOME/python3.12/bin:$PATH"' >> ~/.bashrc +source ~/.bashrc + +# Verify +python3 --version +``` + +**⚠️ This won't work if gcc has permission denied!** Contact your hosting provider instead. + +**Note:** This requires build tools. If compilation fails, contact hosting provider or use pyenv method above. + +--- + +## Step 2: Install Node.js and npm Using nvm (Recommended) + +**nvm** (Node Version Manager) is the easiest way to install Node.js without sudo. + +### 2.1 Install nvm + +```bash +# Navigate to home directory +cd ~ + +# Install nvm +curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash + +# Add nvm to your shell profile +echo 'export NVM_DIR="$HOME/.nvm"' >> ~/.bashrc +echo '[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"' >> ~/.bashrc +echo '[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"' >> ~/.bashrc + +# Reload shell configuration +source ~/.bashrc + +# Verify nvm is installed +nvm --version +``` + +### 2.2 Install Node.js 18+ Using nvm + +```bash +# List available Node.js versions +nvm list-remote | grep "v18\|v20\|v22" + +# Install Node.js 20 LTS (recommended) +nvm install 20 + +# Or install latest Node.js 18: +# nvm install 18 + +# Set as default +nvm use 20 +nvm alias default 20 + +# Verify installation +node --version +# Should show: v20.x.x + +npm --version +# Should show: 10.x.x or 9.x.x +``` + +**If nvm install fails**, try: +```bash +# Try installing with specific version +nvm install 20.11.0 + +# Or try Node.js 18 +nvm install 18.19.0 +``` + +--- + +## Alternative: Install Portable Node.js Binary (If nvm Fails) + +If nvm doesn't work, download a pre-built Node.js binary: + +```bash +cd ~ + +# Check your architecture +uname -m +# If x86_64, use: + +# Download Node.js 20 LTS (Linux x64) +wget https://nodejs.org/dist/v20.11.0/node-v20.11.0-linux-x64.tar.xz + +# Extract +tar -xJf node-v20.11.0-linux-x64.tar.xz + +# Rename for easier access +mv node-v20.11.0-linux-x64 nodejs + +# Add to PATH +echo 'export PATH="$HOME/nodejs/bin:$PATH"' >> ~/.bashrc +source ~/.bashrc + +# Verify +node --version +npm --version + +# Clean up +rm node-v20.11.0-linux-x64.tar.xz +``` + +--- + +## Step 3: Install PostgreSQL Client (psql) + +### Option A: Download PostgreSQL Client Binary (Recommended) + +```bash +cd ~ + +# Check your architecture +uname -m +# If x86_64: + +# Download PostgreSQL 16 client (Linux x64) +# Find latest at: https://www.postgresql.org/download/linux/ +wget https://get.enterprisedb.com/postgresql/postgresql-16.1-1-linux-x64-binaries.tar.gz + +# Extract +tar -xzf postgresql-16.1-1-linux-x64-binaries.tar.gz + +# Move to a permanent location +mv pgsql ~/postgresql-client + +# Add to PATH +echo 'export PATH="$HOME/postgresql-client/bin:$PATH"' >> ~/.bashrc +source ~/.bashrc + +# Verify +psql --version +``` + +### Option B: Contact Hosting Provider + +If downloading binaries doesn't work, **contact your hosting provider** to install PostgreSQL client tools. They can install it system-wide. + +### Option C: Use cPanel PostgreSQL (If Available) + +If cPanel has PostgreSQL databases, the client tools might already be installed but not in PATH: + +```bash +# Search for psql +find /usr -name psql 2>/dev/null +find /opt -name psql 2>/dev/null +find /usr/local -name psql 2>/dev/null + +# If found, add to PATH +# For example, if found at /usr/local/pgsql/bin/psql: +echo 'export PATH="/usr/local/pgsql/bin:$PATH"' >> ~/.bashrc +source ~/.bashrc +``` + +--- + +## Step 4: Set Up Redis Server + +**Important:** PunimTag requires a **Redis server** running (not just the client). The Redis server is used for background job processing (RQ worker). + +### Option 1: Contact Hosting Provider (RECOMMENDED) + +**Ask your hosting provider to:** +1. Install and start Redis server +2. Make it start automatically on boot +3. Provide you with the Redis connection details (host, port, password if any) + +**Verify Redis is running:** +```bash +# Check if Redis server is accessible +redis-cli ping +# Should respond with: PONG + +# If redis-cli is not available, check if Redis is running: +ps aux | grep redis-server +# Or check if port 6379 is listening: +netstat -tuln | grep 6379 +``` + +### Option 2: Use External Redis Service + +If your hosting provider cannot install Redis, use an external Redis service: + +**Free/Paid Options:** +- **Redis Cloud** (free tier: 30MB, https://redis.com/try-free/) +- **Upstash Redis** (free tier: 10K commands/day, https://upstash.com/) +- **AWS ElastiCache** (paid) +- **DigitalOcean Managed Redis** (paid) + +**After setting up external Redis:** +1. Get connection details (host, port, password) +2. Update `REDIS_URL` in your `.env` file: + ``` + REDIS_URL=redis://:password@hostname:port + # Or with password: + REDIS_URL=redis://:yourpassword@redis.example.com:6379 + ``` + +### Option 3: Install Redis Client (Optional - For Testing Only) + +The Redis **client** (`redis-cli`) is optional and only needed for testing. The application will work fine without it if the Redis server is running. + +**If you want redis-cli for testing:** + +```bash +cd ~ + +# Check your architecture +uname -m +# If x86_64: + +# Download Redis 7.x (latest stable) +wget https://download.redis.io/redis-stable.tar.gz + +# Extract +tar -xzf redis-stable.tar.gz +cd redis-stable + +# Compile (only the client, not the server) +make redis-cli + +# Copy redis-cli to your home directory +mkdir -p ~/redis-client/bin +cp src/redis-cli ~/redis-client/bin/ + +# Add to PATH +echo 'export PATH="$HOME/redis-client/bin:$PATH"' >> ~/.bashrc +source ~/.bashrc + +# Verify +redis-cli --version + +# Test connection to Redis server +redis-cli ping +# Should respond with: PONG + +# Clean up +cd ~ +rm -rf redis-stable redis-stable.tar.gz +``` + +**Note:** This requires `make` and `gcc`. If compilation fails, you can skip redis-cli - it's not required for the application to work. + +### Verify Redis Server is Running + +**Before deploying PunimTag, verify Redis is accessible:** + +```bash +# Method 1: Using redis-cli (if installed) +redis-cli ping +# Should respond: PONG + +# Method 2: Check if Redis port is listening +netstat -tuln | grep 6379 +# Or +ss -tuln | grep 6379 + +# Method 3: Test connection with Python (if Python is installed) +python3 -c "import redis; r = redis.Redis(host='localhost', port=6379, decode_responses=True); print(r.ping())" +# Should print: True +``` + +**If Redis is not running or accessible, contact your hosting provider.** + +--- + +## Step 5: Verify All Installations + +Run these commands to verify everything is installed: + +```bash +# Python (need 3.11.2+ or 3.12+) +python3 --version +# Expected: Python 3.11.x or 3.12.x + +pip3 --version +# Expected: pip 24.x.x or similar + +# Node.js (need 18+) +node --version +# Expected: v18.x.x or v20.x.x + +npm --version +# Expected: 9.x.x or 10.x.x + +# PostgreSQL client +psql --version +# Expected: psql (PostgreSQL) 12.x or higher + +# Redis client (optional - for testing) +redis-cli --version +# Expected: redis-cli 6.x or higher +``` + +--- + +## Step 6: Update Your PATH Permanently + +Make sure all tools are in your PATH. Add these lines to `~/.bashrc`: + +```bash +# Edit bashrc +nano ~/.bashrc + +# Add these lines at the end (if not already added): +export PATH="$HOME/.pyenv/bin:$PATH" +export PATH="$HOME/.nvm:$PATH" +export PATH="$HOME/python3.11/bin:$PATH" # Only if using portable Python 3.11 +export PATH="$HOME/python3.12/bin:$PATH" # Only if using portable Python 3.12 +export PATH="$HOME/nodejs/bin:$PATH" # Only if using portable Node.js +export PATH="$HOME/postgresql-client/bin:$PATH" # Only if using portable PostgreSQL +export PATH="$HOME/redis-client/bin:$PATH" # Only if using portable Redis + +# Initialize pyenv +eval "$(pyenv init -)" + +# Initialize nvm +export NVM_DIR="$HOME/.nvm" +[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" + +# Reload +source ~/.bashrc +``` + +--- + +## Troubleshooting + +### Python Installation Fails + +**Error: "bash: /bin/gcc: Permission denied"** +```bash +# This means gcc exists but you don't have permission to use it +# Solutions (in order of preference): + +# 1. Contact hosting provider (EASIEST) +# Ask them to: +# - Install Python 3.11+ system-wide, OR +# - Grant you access to gcc/make, OR +# - Enable cPanel Python Selector + +# 2. Check if cPanel has Python Selector +# Go to: Software → Python Selector +# If available, use that instead + +# 3. Skip Python installation for now +# Continue with Node.js installation +# Ask hosting provider to install Python separately +``` + +**Error: "No module named '_ssl'"** +```bash +# Contact hosting provider to install openssl-devel +# Or try installing with pyenv which handles dependencies better +``` + +**Error: "gcc: command not found"** +```bash +# Contact hosting provider to install build tools: +# - gcc +# - make +# - openssl-devel +# - zlib-devel +``` + +**Solution:** Contact hosting provider or use portable Python binary. + +### Node.js Installation Fails + +**nvm install fails:** +```bash +# Try downloading portable Node.js binary instead (see Step 2 Alternative) +``` + +**npm not found after installing Node.js:** +```bash +# npm comes with Node.js. If missing, reinstall Node.js: +nvm uninstall 20 +nvm install 20 +``` + +### PostgreSQL Client Not Found + +**psql command not found:** +```bash +# Try finding it: +find /usr -name psql 2>/dev/null +find /opt -name psql 2>/dev/null + +# If found, add to PATH +# If not found, contact hosting provider +``` + +### Redis Server Not Running + +**Redis server is required for PunimTag to work!** + +**Check if Redis server is running:** +```bash +# Method 1: Test connection +redis-cli ping +# Should respond: PONG + +# Method 2: Check if port 6379 is listening +netstat -tuln | grep 6379 + +# Method 3: Check Redis process +ps aux | grep redis-server +``` + +**If Redis is not running:** +1. **Contact hosting provider** to install and start Redis server +2. **Or use external Redis service** (Redis Cloud, Upstash, etc.) +3. Update `REDIS_URL` in your `.env` file with connection details + +**Note:** `redis-cli` (client) is optional and only needed for testing. The application will work without it if the Redis server is running. + +--- + +## Quick Reference: Installation Commands Summary + +```bash +# 1. Install Python 3.11.9 or 3.12.7 with pyenv +curl https://pyenv.run | bash +echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc +echo 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc +echo 'eval "$(pyenv init -)"' >> ~/.bashrc +source ~/.bashrc + +# Fix for /tmp noexec issue (common on cPanel/shared hosting) +# Create a temp directory in your home folder and set TMPDIR +mkdir -p ~/tmp +export TMPDIR="$HOME/tmp" + +# Choose one: +pyenv install 3.11.9 # Matches dev environment +# OR +pyenv install 3.12.7 # Latest version +pyenv global 3.11.9 # or 3.12.7 + +# 2. Install Node.js with nvm +curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash +echo 'export NVM_DIR="$HOME/.nvm"' >> ~/.bashrc +echo '[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"' >> ~/.bashrc +source ~/.bashrc +nvm install 20 +nvm use 20 +nvm alias default 20 + +# 3. Install PostgreSQL client (download binary or contact provider) +# See Step 3 above + +# 4. Install Redis client (optional - download binary or contact provider) +# See Step 4 above + +# 5. Verify all installations +python3 --version # Should be 3.11.2+ or 3.12+ +node --version # Should be 18+ +npm --version # Should be 9+ +psql --version # Should work +redis-cli --version # Optional +``` + +--- + +## Next Steps + +After installing all prerequisites: + +1. **Continue with deployment guide**: `docs/DEPLOY_CPANEL_STEP_BY_STEP.md` +2. **Start at Step 3**: Upload Project Files +3. **Skip Step 2**: Check System Requirements (you've already done this!) + +--- + +## Troubleshooting Common Issues + +### pyenv: `/tmp` cannot hold executables (noexec) + +**Error:** +``` +python-build: TMPDIR=/tmp cannot hold executables (partition possibly mounted with `noexec`) +``` + +**Solution:** +This happens when `/tmp` is mounted with the `noexec` flag (common on cPanel/shared hosting). Use a temp directory in your home folder: + +```bash +# Create temp directory in home folder +mkdir -p ~/tmp + +# Set TMPDIR environment variable +export TMPDIR="$HOME/tmp" + +# Now try pyenv install again +pyenv install 3.11.9 +``` + +**Make it permanent:** +Add to your `~/.bashrc` to persist across sessions: +```bash +export TMPDIR="$HOME/tmp" +``` + +### pyenv: "no acceptable C compiler found in $PATH" + +**Error:** +``` +configure: error: no acceptable C compiler found in $PATH +See `config.log' for more details +``` + +**Solution:** +This means `gcc` (the C compiler) is not available or not in your PATH. You have several options: + +**Option 1: Contact Hosting Provider (RECOMMENDED - Easiest)** +Ask your hosting provider to: +- Install Python 3.11+ system-wide (easiest solution!) +- Or install build tools: `gcc`, `make`, `openssl-devel`, `zlib-devel`, `readline-devel` +- Or grant you access to existing build tools + +**Option 2: Check if gcc exists but isn't in PATH or lacks permissions** + +**If gcc exists but isn't in PATH:** +```bash +# Check if gcc exists somewhere +which gcc +whereis gcc +ls -la /usr/bin/gcc* + +# If found, add to PATH temporarily +export PATH="/usr/bin:$PATH" + +# Try pyenv install again +pyenv install 3.11.9 +``` + +**If gcc exists but you get "Permission denied" (common on cPanel):** +```bash +# Check gcc permissions +ls -la /usr/bin/gcc +# If output shows: -rwxr-x--- (only root and compiler group can execute) + +# Check your groups +groups +id + +# Solution 1: Ask hosting provider to add you to 'compiler' group +sudo usermod -a -G compiler $USER + +# After adding to group, activate it in current session (choose one): +# Option A: Start new shell with compiler group +newgrp compiler + +# Option B: Execute command with compiler group +sg compiler -c "gcc --version" + +# Option C: Log out and log back in (group changes take effect automatically) + +# Verify you can now use gcc +gcc --version +which gcc + +# Solution 2: Ask hosting provider to install Python 3.11+ system-wide (easier!) +``` + +**Option 3: Use cPanel Python Selector (If Available)** +1. Log into cPanel +2. Go to **Software** → **Python Selector** +3. If available, select Python 3.11+ or 3.12+ +4. Create a virtual environment + +**Option 4: Check System Python** +Some servers have Python 3.11+ already installed but not in PATH: +```bash +# Check for system Python +/usr/bin/python3.11 --version +/usr/bin/python3.12 --version +/usr/local/bin/python3.11 --version + +# If found, you can use it directly or add to PATH +export PATH="/usr/bin:$PATH" +python3.11 --version +``` + +**Note:** Without gcc, you cannot compile Python from source. Your best bet is to contact your hosting provider to install Python 3.11+ system-wide. + +--- + +## Getting Help + +If installation fails: + +1. **Check error messages** - they often tell you what's missing +2. **Contact hosting provider** - they can install system packages +3. **Try alternative methods** - portable binaries, different versions +4. **Check architecture** - `uname -m` to ensure binaries match your system + +--- + +**Once all prerequisites are installed, you're ready to deploy PunimTag!** 🚀 +