# PunimTag Deployment Guide **Last Updated:** January 6, 2026 This guide covers deployment of PunimTag to development and production environments. --- ## Table of Contents 1. [Prerequisites](#prerequisites) 2. [Development Server Deployment](#development-server-deployment) 3. [Production Deployment](#production-deployment) 4. [Environment Configuration](#environment-configuration) 5. [Service Management](#service-management) 6. [Troubleshooting](#troubleshooting) --- ## Prerequisites ### Server Requirements - **Operating System**: Linux (Ubuntu 20.04+ recommended) - **Python**: 3.12 or higher - **Node.js**: 18+ and npm 9+ - **PostgreSQL**: 12+ (required) - **Redis**: 6+ (required for background jobs) - **System Memory**: Minimum 4GB RAM (8GB+ recommended for large photo collections) - **Disk Space**: Sufficient space for photos and database ### Development Server Information **Development Server:** - **Host**: 10.0.10.121 - **User**: appuser - **Password**: [Contact administrator for password] **Development Database:** - **Host**: 10.0.10.181 - **Port**: 5432 - **User**: ladmin - **Password**: [Contact administrator for password] --- ## Development Server Deployment ### Step 1: Build Applications On your local machine or CI/CD pipeline: ```bash # Install dependencies (if not already done) npm run install:all # Build all frontends npm run build:all # Or use the deployment script npm run deploy:dev ``` This will: - Build admin-frontend for production - Build viewer-frontend for production - Prepare deployment package ### Step 2: Transfer Files to Server ```bash # Create deployment directory structure ssh appuser@10.0.10.121 "mkdir -p /opt/punimtag/{backend,admin-frontend,viewer-frontend,data/uploads,logs}" # Transfer backend scp -r backend/* appuser@10.0.10.121:/opt/punimtag/backend/ scp requirements.txt appuser@10.0.10.121:/opt/punimtag/ # Transfer built frontends scp -r admin-frontend/dist/* appuser@10.0.10.121:/opt/punimtag/admin-frontend/ scp -r viewer-frontend/.next/* appuser@10.0.10.121:/opt/punimtag/viewer-frontend/ # Transfer configuration files scp .env.example appuser@10.0.10.121:/opt/punimtag/.env ``` ### Step 3: Server Setup SSH into the development server: ```bash ssh appuser@10.0.10.121 cd /opt/punimtag ``` #### Install System Dependencies ```bash # Update package list sudo apt update # Install PostgreSQL client (if not already installed) sudo apt install -y postgresql-client # Install Redis (if not already installed) sudo apt install -y redis-server sudo systemctl start redis-server sudo systemctl enable redis-server # Install Python dependencies python3 -m venv venv source venv/bin/activate pip install -r requirements.txt ``` #### Configure Environment Edit `.env` file: ```bash nano .env ``` Set the following variables: ```bash # Development Database DATABASE_URL=postgresql+psycopg2://ladmin:[PASSWORD]@10.0.10.181:5432/punimtag DATABASE_URL_AUTH=postgresql+psycopg2://ladmin:[PASSWORD]@10.0.10.181:5432/punimtag_auth # JWT Secrets (change in production!) SECRET_KEY=dev-secret-key-change-in-production ADMIN_USERNAME=admin ADMIN_PASSWORD=admin # Photo storage PHOTO_STORAGE_DIR=/opt/punimtag/data/uploads # Redis REDIS_URL=redis://localhost:6379/0 # API Configuration API_HOST=0.0.0.0 API_PORT=8000 ``` #### Configure Frontend Environment **Admin Frontend:** Create `admin-frontend/.env`: ```bash VITE_API_URL=http://10.0.10.121:8000 ``` **Viewer Frontend:** Create `viewer-frontend/.env`: ```bash DATABASE_URL=postgresql://ladmin:[PASSWORD]@10.0.10.181:5432/punimtag DATABASE_URL_AUTH=postgresql://ladmin:[PASSWORD]@10.0.10.181:5432/punimtag_auth NEXTAUTH_URL=http://10.0.10.121:3001 NEXTAUTH_SECRET=dev-secret-key-change-in-production ``` Generate Prisma client: ```bash cd viewer-frontend npx prisma generate cd .. ``` ### Step 4: Set Up Systemd Services Create systemd service files for automatic startup: #### Backend API Service ```bash sudo nano /etc/systemd/system/punimtag-api.service ``` ```ini [Unit] Description=PunimTag API Server After=network.target postgresql.service redis.service [Service] Type=simple User=appuser WorkingDirectory=/opt/punimtag Environment="PATH=/opt/punimtag/venv/bin" Environment="PYTHONPATH=/opt/punimtag" ExecStart=/opt/punimtag/venv/bin/uvicorn backend.app:app --host 0.0.0.0 --port 8000 Restart=always RestartSec=10 [Install] WantedBy=multi-user.target ``` #### RQ Worker Service ```bash sudo nano /etc/systemd/system/punimtag-worker.service ``` ```ini [Unit] Description=PunimTag RQ Worker After=network.target postgresql.service redis.service [Service] Type=simple User=appuser WorkingDirectory=/opt/punimtag Environment="PATH=/opt/punimtag/venv/bin" Environment="PYTHONPATH=/opt/punimtag" ExecStart=/opt/punimtag/venv/bin/python -m rq worker --url redis://localhost:6379/0 Restart=always RestartSec=10 [Install] WantedBy=multi-user.target ``` #### Admin Frontend Service (using PM2 or nginx) For production, use nginx to serve the built frontend. Alternatively, use PM2: ```bash npm install -g pm2 cd /opt/punimtag/admin-frontend pm2 serve dist 3000 --name punimtag-admin pm2 save pm2 startup ``` #### Viewer Frontend Service ```bash cd /opt/punimtag/viewer-frontend pm2 start npm --name punimtag-viewer -- start pm2 save ``` ### Step 5: Start Services ```bash # Enable and start services sudo systemctl enable punimtag-api sudo systemctl enable punimtag-worker sudo systemctl start punimtag-api sudo systemctl start punimtag-worker # Check status sudo systemctl status punimtag-api sudo systemctl status punimtag-worker ``` ### Step 6: Verify Deployment 1. **Check API Health:** ```bash curl http://10.0.10.121:8000/api/v1/health ``` 2. **Check API Documentation:** Open browser: `http://10.0.10.121:8000/docs` 3. **Access Admin Frontend:** Open browser: `http://10.0.10.121:3000` 4. **Access Viewer Frontend:** Open browser: `http://10.0.10.121:3001` --- ## Production Deployment ### Additional Production Considerations 1. **Security:** - Change all default passwords - Use strong JWT secrets - Enable HTTPS with SSL certificates - Configure firewall rules - Restrict database access - Use read-only database users where possible 2. **Performance:** - Use nginx as reverse proxy - Enable gzip compression - Configure caching headers - Use CDN for static assets (optional) - Set up database connection pooling - Configure Redis persistence 3. **Monitoring:** - Set up log aggregation - Configure health check endpoints - Set up alerting for service failures - Monitor database performance - Track API response times 4. **Backup:** - Automated database backups - Photo storage backups - Configuration file backups - Disaster recovery plan ### Nginx Configuration Example ```nginx # /etc/nginx/sites-available/punimtag # Admin Frontend server { listen 80; server_name admin.punimtag.example.com; root /opt/punimtag/admin-frontend/dist; index index.html; location / { try_files $uri $uri/ /index.html; } location /api { proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } # Viewer Frontend server { listen 80; server_name viewer.punimtag.example.com; location / { proxy_pass http://127.0.0.1:3001; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } # API (optional, if exposing directly) server { listen 80; server_name api.punimtag.example.com; location / { proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } ``` --- ## Environment Configuration ### Required Environment Variables **Backend (.env):** ```bash # Database (PostgreSQL - required) DATABASE_URL=postgresql+psycopg2://user:password@host:5432/punimtag DATABASE_URL_AUTH=postgresql+psycopg2://user:password@host:5432/punimtag_auth # JWT Configuration SECRET_KEY=your-secret-key-here ADMIN_USERNAME=admin ADMIN_PASSWORD=secure-password # Photo Storage PHOTO_STORAGE_DIR=/path/to/photos # Redis REDIS_URL=redis://localhost:6379/0 # API Configuration API_HOST=0.0.0.0 API_PORT=8000 ``` **Admin Frontend (admin-frontend/.env):** ```bash VITE_API_URL=http://your-api-url:8000 ``` **Viewer Frontend (viewer-frontend/.env):** ```bash DATABASE_URL=postgresql://user:password@host:5432/punimtag DATABASE_URL_AUTH=postgresql://user:password@host:5432/punimtag_auth NEXTAUTH_URL=http://your-viewer-url:3001 NEXTAUTH_SECRET=your-nextauth-secret ``` --- ## Service Management ### Systemd Commands ```bash # Start services sudo systemctl start punimtag-api sudo systemctl start punimtag-worker # Stop services sudo systemctl stop punimtag-api sudo systemctl stop punimtag-worker # Restart services sudo systemctl restart punimtag-api sudo systemctl restart punimtag-worker # Check status sudo systemctl status punimtag-api sudo systemctl status punimtag-worker # View logs sudo journalctl -u punimtag-api -f sudo journalctl -u punimtag-worker -f ``` ### PM2 Commands ```bash # Start services pm2 start punimtag-admin pm2 start punimtag-viewer # Stop services pm2 stop punimtag-admin pm2 stop punimtag-viewer # Restart services pm2 restart punimtag-admin pm2 restart punimtag-viewer # View logs pm2 logs punimtag-admin pm2 logs punimtag-viewer # Monitor pm2 monit ``` --- ## Troubleshooting ### Common Issues 1. **Database Connection Errors:** - Verify PostgreSQL is running - Check connection string in `.env` - Verify database exists and user has permissions - Check firewall rules 2. **Redis Connection Errors:** - Verify Redis is running: `redis-cli ping` - Check Redis URL in `.env` - Verify Redis is accessible 3. **API Not Starting:** - Check logs: `sudo journalctl -u punimtag-api -n 50` - Verify Python virtual environment is activated - Check PYTHONPATH is set correctly - Verify all dependencies are installed 4. **Frontend Build Errors:** - Clear node_modules and reinstall - Check Node.js version (18+) - Verify all environment variables are set 5. **Worker Not Processing Jobs:** - Check worker logs: `sudo journalctl -u punimtag-worker -f` - Verify Redis connection - Check job queue: `redis-cli` - Restart worker service ### Log Locations - **Systemd logs**: `sudo journalctl -u ` - **PM2 logs**: `pm2 logs` - **Application logs**: `/opt/punimtag/logs/` (if configured) ### Health Checks ```bash # API Health curl http://localhost:8000/api/v1/health # Redis redis-cli ping # PostgreSQL psql -h 10.0.10.181 -U ladmin -d punimtag -c "SELECT 1;" ``` --- ## Deployment Checklist - [ ] Build all frontends - [ ] Transfer files to server - [ ] Install system dependencies - [ ] Set up Python virtual environment - [ ] Configure environment variables - [ ] Set up systemd services - [ ] Configure nginx (production) - [ ] Set up SSL certificates (production) - [ ] Configure firewall rules - [ ] Test all services - [ ] Set up monitoring - [ ] Configure backups - [ ] Document deployment process --- **For additional help, see:** - `README.md` - Main documentation - `docs/ARCHITECTURE.md` - System architecture - `docs/USER_GUIDE.md` - User guide