fix: configure PostgreSQL for production and clean up deployment

- Fix database configuration to use PostgreSQL in production
- Add knexfile.js to support both SQLite (dev) and PostgreSQL (prod)
- Create admin user creation script (scripts/create-admin.js)
- Clean up docker-compose files:
  - Remove redundant docker-compose.yml and docker-compose.local.yml
  - Create docker-compose.dev.yml for development
  - Update docker-compose.prod.yml with proper DB configuration
- Clean up environment files:
  - Update .env.example for development
  - Update .env.production.example with proper settings
  - Remove redundant .env.local
- Update backend .env.example with database configuration options
- Create comprehensive DEPLOYMENT.md with admin setup instructions
- Fix production database name consistency (picpeak instead of photoapp)
This commit is contained in:
2025-07-13 21:24:07 +02:00
parent 66940c2f5b
commit 1c7fa781ad
11 changed files with 577 additions and 691 deletions
+287 -424
View File
@@ -1,483 +1,346 @@
# Photo Sharing Platform - Production Deployment Guide
# PicPeak Deployment Guide
This guide covers deploying the photo sharing platform using Docker Swarm, Traefik, and Drone CI/CD.
This guide covers deploying PicPeak for development and production environments.
## Table of Contents
- [Prerequisites](#prerequisites)
- [Infrastructure Setup](#infrastructure-setup)
- [Docker Swarm Setup](#docker-swarm-setup)
- [Traefik Setup](#traefik-setup)
- [Application Deployment](#application-deployment)
- [CI/CD with Drone](#cicd-with-drone)
- [Monitoring](#monitoring)
- [Backup and Recovery](#backup-and-recovery)
- [Quick Start (Development)](#quick-start-development)
- [Production Deployment](#production-deployment)
- [Admin User Setup](#admin-user-setup)
- [Configuration Reference](#configuration-reference)
- [Troubleshooting](#troubleshooting)
## Prerequisites
## Quick Start (Development)
### Hardware Requirements
- **Manager Node**: 2 CPU cores, 4GB RAM, 50GB storage
- **Worker Nodes**: 2 CPU cores, 2GB RAM, 20GB storage
- **Storage**: SSD recommended for database and photo storage
### Software Requirements
- Ubuntu 20.04+ or similar Linux distribution
- Docker Engine 20.10+
- Docker Compose 2.0+
- Git
- SSL certificates (automated with Let's Encrypt)
### Network Requirements
- Ports 80, 443 open for web traffic
- Port 2377 for Swarm management
- Ports 7946, 4789 for Swarm networking
- Static IP or reliable dynamic DNS
## Infrastructure Setup
### 1. Install Docker
### 1. Clone and Setup
```bash
# Install Docker
curl -fsSL https://get.docker.com | sh
git clone https://github.com/yourusername/picpeak.git
cd picpeak
# Add user to docker group
sudo usermod -aG docker $USER
# Enable Docker service
sudo systemctl enable docker
sudo systemctl start docker
```
### 2. Configure Firewall
```bash
# Allow Docker Swarm ports
sudo ufw allow 2377/tcp
sudo ufw allow 7946/tcp
sudo ufw allow 7946/udp
sudo ufw allow 4789/udp
# Allow web traffic
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
```
## Docker Swarm Setup
### 1. Initialize Swarm
On the manager node:
```bash
cd deploy/scripts
sudo ./init-swarm.sh
```
This script will:
- Initialize Docker Swarm
- Create overlay networks
- Label nodes for service placement
- Create required directories
### 2. Join Worker Nodes
On each worker node, run the join command displayed by the init script:
```bash
docker swarm join --token SWMTKN-1-xxx... manager-ip:2377
```
### 3. Verify Swarm
```bash
docker node ls
```
## Application Configuration
### 1. Environment Setup
```bash
# Copy environment template
cp .env.production.example .env.production
cp .env.example .env
# Edit with your values
nano .env.production
```
Required configurations:
- Domain names for frontend, backend, and services
- SMTP credentials for email
- Database passwords
- JWT secrets
### 2. Create Docker Secrets
```bash
cd deploy/scripts
./create-secrets.sh
```
This will create all required secrets in Docker Swarm. Save the generated passwords!
## Traefik Setup
### 1. Deploy Traefik
```bash
cd deploy/traefik
# Create traefik network
docker network create --driver overlay traefik-public
# Deploy Traefik stack
docker stack deploy -c docker-compose.traefik.yml traefik
```
### 2. Verify Traefik
```bash
# Check service status
docker service ls | grep traefik
# View logs
docker service logs traefik_traefik
```
Access Traefik dashboard at: `https://traefik.yourdomain.com/dashboard/`
## Application Deployment
### 1. Build Images (if using local registry)
```bash
# Build frontend
cd frontend
docker build -t photo-sharing-frontend:latest .
# Build backend
cd ../backend
docker build -t photo-sharing-backend:latest .
```
### 2. Deploy Application Stack
```bash
cd deploy/scripts
./deploy.sh
```
Options:
- `--env FILE`: Specify environment file
- `--registry URL`: Docker registry URL
- `--version VERSION`: Image version to deploy
### 3. Verify Deployment
```bash
# Check all services
docker service ls
# Check specific service
docker service ps photo-sharing_backend
# View logs
docker service logs photo-sharing_backend -f
```
### 4. Run Database Migrations
The deploy script automatically runs migrations, but you can run manually:
```bash
docker exec $(docker ps -q -f name=photo-sharing_backend) npm run migrate
```
## CI/CD with Drone
### 1. Drone Server Setup
Deploy Drone server on your CI infrastructure:
```bash
docker run \
--volume=/var/lib/drone:/data \
--env=DRONE_GITHUB_CLIENT_ID=your-id \
--env=DRONE_GITHUB_CLIENT_SECRET=your-secret \
--env=DRONE_RPC_SECRET=your-rpc-secret \
--env=DRONE_SERVER_HOST=drone.yourdomain.com \
--env=DRONE_SERVER_PROTO=https \
--publish=80:80 \
--publish=443:443 \
--restart=always \
--detach=true \
--name=drone \
drone/drone:2
```
### 2. Drone Runner Setup
On build servers:
```bash
docker run -d \
-v /var/run/docker.sock:/var/run/docker.sock \
-e DRONE_RPC_PROTO=https \
-e DRONE_RPC_HOST=drone.yourdomain.com \
-e DRONE_RPC_SECRET=your-rpc-secret \
-e DRONE_RUNNER_CAPACITY=2 \
-e DRONE_RUNNER_NAME=runner-1 \
-p 3000:3000 \
--restart always \
--name runner \
drone/drone-runner-docker:1
```
### 3. Repository Setup
1. Enable repository in Drone UI
2. Add secrets in Drone:
- `docker_username`
- `docker_password`
- `docker_registry`
- `staging_swarm_host`
- `staging_swarm_user`
- `staging_swarm_key`
- `prod_swarm_host`
- `prod_swarm_user`
- `prod_swarm_key`
- `slack_webhook`
### 4. Deployment Workflow
- Push to `develop` → Deploy to staging
- Create tag → Deploy to production
- Automatic rollback on failure
## Monitoring
### 1. Deploy Monitoring Stack
```bash
cd deploy/monitoring
# Deploy monitoring services
docker stack deploy -c docker-compose.monitoring.yml monitoring
# Start development environment
docker-compose -f docker-compose.dev.yml up -d
```
### 2. Access Services
- Grafana: `https://grafana.yourdomain.com`
- Prometheus: `https://prometheus.yourdomain.com`
- Alertmanager: `https://alerts.yourdomain.com`
- Frontend: http://localhost:3005
- Backend API: http://localhost:3001
- MailHog (email testing): http://localhost:8025
### 3. Configure Alerts
### 3. Create Admin User
Create alert rules in `deploy/monitoring/alerts/`:
```bash
docker-compose -f docker-compose.dev.yml exec backend node scripts/create-admin.js \
--email admin@localhost \
--username admin \
--password admin123
```
## Production Deployment
### Prerequisites
- Docker and Docker Compose installed
- Domain with DNS configured
- SSL/TLS handled by reverse proxy (Traefik, Nginx, etc.)
### 1. Environment Setup
```bash
# Copy production template
cp .env.production.example .env
# Generate secure secrets
echo "JWT_SECRET=$(openssl rand -base64 32)" >> .env
echo "DB_PASSWORD=$(openssl rand -base64 24)" >> .env
```
Edit `.env` with your configuration:
```env
# Your domain
ADMIN_URL=https://yourdomain.com
FRONTEND_URL=https://yourdomain.com
# Database (PostgreSQL)
DB_USER=picpeak
DB_NAME=picpeak
# DB_PASSWORD already generated above
# Email
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_SECURE=true
SMTP_USER=your-email@gmail.com
SMTP_PASS=your-app-password
EMAIL_FROM=noreply@yourdomain.com
```
### 2. Frontend Configuration
```bash
# Configure frontend for production
echo "VITE_API_URL=/api" > frontend/.env.production
```
### 3. Deploy with Docker Compose
```bash
# Build and start services
docker-compose -f docker-compose.prod.yml up -d
# Check status
docker-compose -f docker-compose.prod.yml ps
# View logs
docker-compose -f docker-compose.prod.yml logs -f
```
### 4. Deploy with Traefik
If using Traefik, create `docker-compose.override.yml`:
```yaml
groups:
- name: photo-sharing
rules:
- alert: ServiceDown
expr: up{job="photo-sharing-backend"} == 0
for: 5m
annotations:
summary: "Photo sharing backend is down"
version: '3.8'
services:
frontend:
labels:
- "traefik.enable=true"
- "traefik.http.routers.picpeak.rule=Host(`yourdomain.com`)"
- "traefik.http.routers.picpeak.entrypoints=websecure"
- "traefik.http.routers.picpeak.tls.certresolver=letsencrypt"
- "traefik.http.services.picpeak.loadbalancer.server.port=80"
networks:
- traefik
- picpeak
networks:
traefik:
external: true
```
## Backup and Recovery
## Admin User Setup
### 1. Automated Backups
### Create First Admin
Set up cron job for automated backups:
After deployment, create your admin user:
```bash
# Edit crontab
crontab -e
# Production
docker-compose -f docker-compose.prod.yml exec backend node scripts/create-admin.js \
--email admin@yourdomain.com \
--username admin \
--password yourSecurePassword
# Add daily backup at 2 AM
0 2 * * * /opt/photo-sharing/deploy/scripts/backup.sh
# Auto-generate password
docker-compose -f docker-compose.prod.yml exec backend node scripts/create-admin.js \
--email admin@yourdomain.com
```
### 2. Manual Backup
The script will display:
- ✅ Admin user created successfully!
- Email: admin@yourdomain.com
- Username: admin
- Login URL: https://yourdomain.com/admin/login
- Password: (save this if auto-generated!)
### Managing Admin Users
```bash
cd deploy/scripts
./backup.sh
# List admin users
docker-compose -f docker-compose.prod.yml exec backend \
psql postgresql://picpeak:$DB_PASSWORD@db:5432/picpeak \
-c "SELECT id, username, email, is_active, last_login FROM admin_users;"
# Deactivate user
docker-compose -f docker-compose.prod.yml exec backend \
psql postgresql://picpeak:$DB_PASSWORD@db:5432/picpeak \
-c "UPDATE admin_users SET is_active = false WHERE email = 'user@example.com';"
```
### 3. Restore from Backup
## Configuration Reference
### Database Configuration
PicPeak automatically detects the environment and uses:
- **Development**: SQLite (`./data/photo_sharing.db`)
- **Production**: PostgreSQL (configured via environment variables)
### Environment Variables
#### Required for Production
| Variable | Description | Example |
|----------|-------------|---------|
| `JWT_SECRET` | JWT signing key | `openssl rand -base64 32` |
| `DB_PASSWORD` | PostgreSQL password | `openssl rand -base64 24` |
| `ADMIN_URL` | Admin panel URL | `https://yourdomain.com` |
| `FRONTEND_URL` | Frontend URL | `https://yourdomain.com` |
| `EMAIL_FROM` | Sender email | `noreply@yourdomain.com` |
#### Email Configuration
| Variable | Description | Example |
|----------|-------------|---------|
| `SMTP_HOST` | SMTP server | `smtp.gmail.com` |
| `SMTP_PORT` | SMTP port | `587` |
| `SMTP_SECURE` | Use TLS | `true` |
| `SMTP_USER` | SMTP username | `your-email@gmail.com` |
| `SMTP_PASS` | SMTP password | App-specific password |
### Storage Paths
- Photos: `./storage/events/active/`
- Archives: `./storage/events/archived/`
- Thumbnails: `./storage/thumbnails/`
- Uploads: `./storage/uploads/`
## Backup and Restore
### Backup Database
```bash
# Extract backup
tar -xzf backup-20240615-020000.tar.gz
# PostgreSQL backup
docker-compose -f docker-compose.prod.yml exec db \
pg_dump -U picpeak picpeak > backup-$(date +%Y%m%d).sql
# Restore database
docker exec -i $(docker ps -q -f name=photo-sharing_db) \
psql -U postgres photo_sharing < backup-20240615-020000/database.sql
# Restore photos
tar -xzf backup-20240615-020000/photos.tar.gz -C /opt/photo-sharing/
# Restore volumes
docker run --rm \
-v photo-sharing_app-data:/data \
-v $(pwd)/backup-20240615-020000:/backup \
alpine tar -xzf /backup/volume-photo-sharing_app-data.tar.gz -C /data
# Backup storage
tar -czf storage-backup-$(date +%Y%m%d).tar.gz ./storage
```
## Maintenance
### 1. Scaling Services
### Restore Database
```bash
# Scale backend to 5 replicas
docker service scale photo-sharing_backend=5
# PostgreSQL restore
docker-compose -f docker-compose.prod.yml exec -T db \
psql -U picpeak picpeak < backup-20240115.sql
# Scale frontend to 3 replicas
docker service scale photo-sharing_frontend=3
# Restore storage
tar -xzf storage-backup-20240115.tar.gz
```
### 2. Rolling Updates
```bash
# Update backend image
docker service update \
--image registry.yourdomain.com/photo-sharing-backend:v2.0 \
photo-sharing_backend
```
### 3. Drain Node for Maintenance
```bash
# Drain node
docker node update --availability drain worker-1
# Perform maintenance...
# Activate node
docker node update --availability active worker-1
```
## Troubleshooting
### Common Issues
#### 1. Service Won't Start
```bash
# Check service status
docker service ps photo-sharing_backend --no-trunc
# View detailed logs
docker service logs photo-sharing_backend --details
```
#### 2. Database Connection Issues
```bash
# Check database logs
docker service logs photo-sharing_db
# Test connection
docker exec $(docker ps -q -f name=photo-sharing_db) \
pg_isready -U postgres
```
#### 3. Traefik Certificate Issues
```bash
# Check Traefik logs
docker service logs traefik_traefik | grep acme
# Remove and regenerate certificates
rm -rf /opt/traefik/letsencrypt/acme.json
docker service update --force traefik_traefik
```
#### 4. Storage Issues
```bash
# Check disk usage
df -h
# Clean up Docker
docker system prune -a
```
### Debug Mode
Enable debug logging:
```bash
# Update service with debug logging
docker service update \
--env-add LOG_LEVEL=debug \
photo-sharing_backend
```
## Monitoring
### Health Checks
```bash
# Check all endpoints
curl -f https://photos.yourdomain.com/health
curl -f https://api.photos.yourdomain.com/api/health
curl -f https://traefik.yourdomain.com/ping
# Backend health
curl https://yourdomain.com/api/health
# Frontend health
curl https://yourdomain.com/health
```
## Security Best Practices
### Logs
1. **Regular Updates**
- Keep Docker and system packages updated
- Update application dependencies regularly
- Monitor security advisories
```bash
# All services
docker-compose -f docker-compose.prod.yml logs -f
2. **Access Control**
- Use strong passwords for all services
- Enable 2FA where possible
- Restrict SSH access to specific IPs
- Use Docker secrets for sensitive data
# Specific service
docker-compose -f docker-compose.prod.yml logs -f backend
3. **Network Security**
- Use internal networks for service communication
- Enable firewall rules
- Use TLS for all external communication
- Regular security scans with Trivy
# Last 100 lines
docker-compose -f docker-compose.prod.yml logs --tail=100 backend
```
4. **Backup Security**
- Encrypt backups at rest
- Test restore procedures regularly
- Store backups in multiple locations
- Rotate old backups
## Troubleshooting
## Performance Tuning
### Backend Won't Start
1. **Database Optimization**
```sql
-- Add indexes for common queries
CREATE INDEX idx_photos_event_id ON photos(event_id);
CREATE INDEX idx_access_logs_event_id ON access_logs(event_id);
1. Check database connection:
```bash
docker-compose -f docker-compose.prod.yml logs db
```
2. **Image Optimization**
- Use CDN for static assets
- Enable aggressive caching
- Optimize image sizes before upload
3. **Service Limits**
```yaml
deploy:
resources:
limits:
cpus: '2'
memory: 1G
reservations:
cpus: '0.5'
memory: 256M
2. Verify environment variables:
```bash
docker-compose -f docker-compose.prod.yml exec backend env | grep DB_
```
## Support
### Can't Login as Admin
For issues and questions:
- Check logs: `docker service logs <service_name>`
- Review documentation: [README.md](README.md)
- Check monitoring dashboards
- Contact: admin@yourdomain.com
1. Verify admin user exists:
```bash
docker-compose -f docker-compose.prod.yml exec backend \
psql postgresql://picpeak:$DB_PASSWORD@db:5432/picpeak \
-c "SELECT * FROM admin_users;"
```
2. Reset admin password:
```bash
# Create new admin with different email
docker-compose -f docker-compose.prod.yml exec backend \
node scripts/create-admin.js --email newadmin@yourdomain.com
```
### Photos Not Loading
1. Check file permissions:
```bash
ls -la ./storage/events/active/
```
2. Verify nginx proxy configuration:
```bash
docker-compose -f docker-compose.prod.yml exec frontend \
cat /etc/nginx/conf.d/default.conf
```
### Email Not Sending
1. Check email configuration:
```bash
docker-compose -f docker-compose.prod.yml exec backend env | grep SMTP_
```
2. View email queue:
```bash
docker-compose -f docker-compose.prod.yml exec backend \
psql postgresql://picpeak:$DB_PASSWORD@db:5432/picpeak \
-c "SELECT * FROM email_queue WHERE status = 'failed';"
```
## Maintenance
### Update Application
```bash
# Pull latest changes
git pull
# Rebuild images
docker-compose -f docker-compose.prod.yml build
# Restart services
docker-compose -f docker-compose.prod.yml up -d
```
### Clean Up
```bash
# Remove unused images
docker image prune -a
# Clean up logs
docker-compose -f docker-compose.prod.yml logs --tail=0 -f
# Remove old archives
find ./storage/events/archived -name "*.zip" -mtime +90 -delete
```
## Security Checklist
- [ ] Generated secure `JWT_SECRET`
- [ ] Generated secure `DB_PASSWORD`
- [ ] HTTPS enabled via reverse proxy
- [ ] Changed default admin credentials
- [ ] Configured real SMTP server
- [ ] Set file permissions: `chmod 600 .env`
- [ ] Firewall configured
- [ ] Regular backups scheduled
- [ ] Monitoring enabled