This commit replaces hardcoded sensitive information, such as database passwords and secret keys, in the README and deployment documentation with placeholders and instructions to use environment variables. This change enhances security by preventing exposure of sensitive data in the codebase. Additionally, it updates the database session management to raise an error if the DATABASE_URL environment variable is not set, ensuring proper configuration for development environments.
11 KiB
PunimTag Deployment Guide
Last Updated: January 6, 2026
This guide covers deployment of PunimTag to development and production environments.
Table of Contents
- Prerequisites
- Development Server Deployment
- Production Deployment
- Environment Configuration
- Service Management
- 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:
# 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
# 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:
ssh appuser@10.0.10.121
cd /opt/punimtag
Install System Dependencies
# 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:
nano .env
Set the following variables:
# 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:
VITE_API_URL=http://10.0.10.121:8000
Viewer Frontend:
Create viewer-frontend/.env:
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:
cd viewer-frontend
npx prisma generate
cd ..
Step 4: Set Up Systemd Services
Create systemd service files for automatic startup:
Backend API Service
sudo nano /etc/systemd/system/punimtag-api.service
[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
sudo nano /etc/systemd/system/punimtag-worker.service
[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:
npm install -g pm2
cd /opt/punimtag/admin-frontend
pm2 serve dist 3000 --name punimtag-admin
pm2 save
pm2 startup
Viewer Frontend Service
cd /opt/punimtag/viewer-frontend
pm2 start npm --name punimtag-viewer -- start
pm2 save
Step 5: Start Services
# 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
-
Check API Health:
curl http://10.0.10.121:8000/api/v1/health -
Check API Documentation: Open browser:
http://10.0.10.121:8000/docs -
Access Admin Frontend: Open browser:
http://10.0.10.121:3000 -
Access Viewer Frontend: Open browser:
http://10.0.10.121:3001
Production Deployment
Additional Production Considerations
-
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
-
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
-
Monitoring:
- Set up log aggregation
- Configure health check endpoints
- Set up alerting for service failures
- Monitor database performance
- Track API response times
-
Backup:
- Automated database backups
- Photo storage backups
- Configuration file backups
- Disaster recovery plan
Nginx Configuration Example
# /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):
# 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):
VITE_API_URL=http://your-api-url:8000
Viewer Frontend (viewer-frontend/.env):
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
# 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
# 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
-
Database Connection Errors:
- Verify PostgreSQL is running
- Check connection string in
.env - Verify database exists and user has permissions
- Check firewall rules
-
Redis Connection Errors:
- Verify Redis is running:
redis-cli ping - Check Redis URL in
.env - Verify Redis is accessible
- Verify Redis is running:
-
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
- Check logs:
-
Frontend Build Errors:
- Clear node_modules and reinstall
- Check Node.js version (18+)
- Verify all environment variables are set
-
Worker Not Processing Jobs:
- Check worker logs:
sudo journalctl -u punimtag-worker -f - Verify Redis connection
- Check job queue:
redis-cli - Restart worker service
- Check worker logs:
Log Locations
- Systemd logs:
sudo journalctl -u <service-name> - PM2 logs:
pm2 logs - Application logs:
/opt/punimtag/logs/(if configured)
Health Checks
# 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 documentationdocs/ARCHITECTURE.md- System architecturedocs/USER_GUIDE.md- User guide