Add comprehensive production deployment documentation

Add detailed production setup guide covering:
- Step-by-step deployment instructions for Ubuntu/Debian
- Email provider configuration (Gmail, SendGrid, AWS SES, Mailgun)
- Gunicorn and Celery systemd service configurations
- Nginx reverse proxy setup with SSL
- Complete production checklist
- Email verification and admin approval setup
- Troubleshooting guide
- Maintenance tasks and backup procedures
- Enhanced environment variables documentation
- Updated changelog with v1.1.0 features

The guide provides complete instructions for deploying the application
with the new email verification and admin approval system.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Keith Smith
2025-12-22 18:16:56 -07:00
co-authored by Claude Sonnet 4.5
parent 21d9d01885
commit f6dff9c459
+553 -26
View File
@@ -23,9 +23,13 @@ A powerful Django-based task management system with time tracking, tag organizat
- **Formatted Display**: Time shown as H:MM:SS with visual indicators - **Formatted Display**: Time shown as H:MM:SS with visual indicators
- **Running Timer Display**: Always visible timer in the UI when tracking time - **Running Timer Display**: Always visible timer in the UI when tracking time
### Collaboration ### Collaboration & User Management
- **Task Sharing**: Share individual tasks or entire tags with other users - **Task Sharing**: Share individual tasks or entire tags with other users
- **Multi-user Support**: Full authentication and user management - **Multi-user Support**: Full authentication and user management
- **Email Verification**: Secure email verification for new user registrations
- **Admin Approval**: Optional admin approval workflow for new users
- **User Profiles**: Customizable profiles with timezone and notification preferences
- **Password Management**: Secure password change functionality
- **Shared Views**: See tasks shared with you alongside your own - **Shared Views**: See tasks shared with you alongside your own
### User Interface ### User Interface
@@ -286,12 +290,32 @@ python manage.py loaddata data.json
Key environment variables (see `.env.example`): Key environment variables (see `.env.example`):
- `SECRET_KEY` - Django secret key (required in production) #### Core Settings
- `DEBUG` - Enable debug mode (True/False) - `SECRET_KEY` - Django secret key (required in production, generate with `python -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())"`)
- `ALLOWED_HOSTS` - Comma-separated list of allowed hosts - `DEBUG` - Enable debug mode (True/False, must be False in production)
- `ALLOWED_HOSTS` - Comma-separated list of allowed hosts (e.g., `tasks.firebugit.com,localhost`)
- `CSRF_TRUSTED_ORIGINS` - HTTPS origins for CSRF (e.g., `https://tasks.firebugit.com`)
- `SITE_DOMAIN` - Domain name for email links (e.g., `tasks.firebugit.com`)
#### Database
- `DATABASE_URL` - Database connection string (optional, overrides settings) - `DATABASE_URL` - Database connection string (optional, overrides settings)
- `REDIS_URL` - Redis connection for Celery
- `CSRF_TRUSTED_ORIGINS` - HTTPS origins for CSRF #### Redis & Celery
- `REDIS_URL` - Redis connection for Celery (e.g., `redis://localhost:6379/0`)
#### Email Configuration (Required for Email Verification)
- `EMAIL_BACKEND` - Email backend (use `django.core.mail.backends.smtp.EmailBackend` for production)
- `EMAIL_HOST` - SMTP server hostname (e.g., `smtp.gmail.com`, `smtp.sendgrid.net`)
- `EMAIL_PORT` - SMTP port (587 for TLS, 465 for SSL)
- `EMAIL_USE_TLS` - Use TLS (True/False, use True for port 587)
- `EMAIL_USE_SSL` - Use SSL (True/False, use True for port 465)
- `EMAIL_HOST_USER` - SMTP username/email
- `EMAIL_HOST_PASSWORD` - SMTP password or API key
- `DEFAULT_FROM_EMAIL` - From email address (e.g., `KeepItGoing <noreply@firebugit.com>`)
- `SERVER_EMAIL` - Server error email address
#### Email Verification Settings
- `EMAIL_VERIFICATION_TOKEN_EXPIRY_HOURS` - Hours before verification tokens expire (default: 24)
## API Documentation ## API Documentation
@@ -426,45 +450,538 @@ python manage.py collectstatic
## Deployment ## Deployment
### Production Checklist ### Production Setup Guide
- [ ] Set `DEBUG = False` This guide covers deploying KeepItGoing Server in a production environment.
- [ ] Configure strong `SECRET_KEY`
- [ ] Set up proper `ALLOWED_HOSTS`
- [ ] Configure `CSRF_TRUSTED_ORIGINS` for HTTPS
- [ ] Use PostgreSQL instead of SQLite
- [ ] Set up Redis for Celery
- [ ] Configure static file serving
- [ ] Set up SSL/TLS certificates
- [ ] Configure backup strategy
- [ ] Set up monitoring and logging
### Nginx Configuration #### Prerequisites
Example nginx config for reverse proxy: - Ubuntu/Debian Linux server (or similar)
- Root or sudo access
- Domain name pointing to your server
- SSL certificate (Let's Encrypt recommended)
#### Step 1: System Preparation
```bash
# Update system packages
sudo apt update && sudo apt upgrade -y
# Install required system packages
sudo apt install -y python3.12 python3.12-venv python3-pip \
postgresql postgresql-contrib nginx \
redis-server git curl
# Install Let's Encrypt certbot (optional, for SSL)
sudo apt install -y certbot python3-certbot-nginx
```
#### Step 2: Database Setup
```bash
# Create PostgreSQL database and user
sudo -u postgres psql << EOF
CREATE DATABASE keepitgoing;
CREATE USER keepitgoing_user WITH PASSWORD 'STRONG_PASSWORD_HERE';
ALTER ROLE keepitgoing_user SET client_encoding TO 'utf8';
ALTER ROLE keepitgoing_user SET default_transaction_isolation TO 'read committed';
ALTER ROLE keepitgoing_user SET timezone TO 'UTC';
GRANT ALL PRIVILEGES ON DATABASE keepitgoing TO keepitgoing_user;
\q
EOF
```
#### Step 3: Application Setup
```bash
# Create application user
sudo useradd -m -s /bin/bash keepitgoing
sudo su - keepitgoing
# Clone repository
git clone https://git.firebugit.com/Firebug_IT/KeepItGoingServer.git
cd KeepItGoingServer
# Create virtual environment
python3.12 -m venv venv
source venv/bin/activate
# Install dependencies
pip install -r requirements.txt
pip install gunicorn psycopg2-binary
# Create production environment file
cat > .env << 'EOF'
# Django Settings
SECRET_KEY=GENERATE_WITH_get_random_secret_key
DEBUG=False
ALLOWED_HOSTS=tasks.firebugit.com,localhost,127.0.0.1
CSRF_TRUSTED_ORIGINS=https://tasks.firebugit.com
SITE_DOMAIN=tasks.firebugit.com
# Database
DATABASE_URL=postgresql://keepitgoing_user:STRONG_PASSWORD_HERE@localhost:5432/keepitgoing
# Email Configuration (Gmail example)
EMAIL_BACKEND=django.core.mail.backends.smtp.EmailBackend
EMAIL_HOST=smtp.gmail.com
EMAIL_PORT=587
EMAIL_USE_TLS=True
EMAIL_HOST_USER=your-email@gmail.com
EMAIL_HOST_PASSWORD=your-app-password
DEFAULT_FROM_EMAIL=KeepItGoing <noreply@firebugit.com>
SERVER_EMAIL=server@firebugit.com
# Email Verification
EMAIL_VERIFICATION_TOKEN_EXPIRY_HOURS=24
# Redis (for Celery)
REDIS_URL=redis://localhost:6379/0
EOF
# Generate SECRET_KEY
python -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())"
# Copy the output and replace SECRET_KEY in .env
# Run migrations
export DJANGO_SETTINGS_MODULE=config.settings.production
python manage.py migrate
# Create superuser (admin account)
python manage.py createsuperuser
# Collect static files
python manage.py collectstatic --noinput
# Exit back to root
exit
```
#### Step 4: Email Provider Setup
Choose one of the following email providers:
**Gmail:**
1. Enable 2-factor authentication on your Google account
2. Generate an App Password: https://myaccount.google.com/apppasswords
3. Use the app password in `EMAIL_HOST_PASSWORD`
```env
EMAIL_HOST=smtp.gmail.com
EMAIL_PORT=587
EMAIL_USE_TLS=True
EMAIL_HOST_USER=your-email@gmail.com
EMAIL_HOST_PASSWORD=your-16-char-app-password
```
**SendGrid:**
1. Create SendGrid account and verify sender identity
2. Generate API key from Settings > API Keys
3. Configure:
```env
EMAIL_HOST=smtp.sendgrid.net
EMAIL_PORT=587
EMAIL_USE_TLS=True
EMAIL_HOST_USER=apikey
EMAIL_HOST_PASSWORD=SG.your-api-key-here
```
**AWS SES:**
1. Verify domain in AWS SES console
2. Create SMTP credentials
3. Configure:
```env
EMAIL_HOST=email-smtp.us-east-1.amazonaws.com
EMAIL_PORT=587
EMAIL_USE_TLS=True
EMAIL_HOST_USER=your-smtp-username
EMAIL_HOST_PASSWORD=your-smtp-password
```
**Mailgun:**
```env
EMAIL_HOST=smtp.mailgun.org
EMAIL_PORT=587
EMAIL_USE_TLS=True
EMAIL_HOST_USER=postmaster@mg.yourdomain.com
EMAIL_HOST_PASSWORD=your-mailgun-password
```
#### Step 5: Gunicorn Service
Create systemd service file for Gunicorn:
```bash
sudo nano /etc/systemd/system/keepitgoing.service
```
Add the following content:
```ini
[Unit]
Description=KeepItGoing Gunicorn daemon
After=network.target postgresql.service
[Service]
Type=notify
User=keepitgoing
Group=keepitgoing
WorkingDirectory=/home/keepitgoing/KeepItGoingServer
Environment="PATH=/home/keepitgoing/KeepItGoingServer/venv/bin"
Environment="DJANGO_SETTINGS_MODULE=config.settings.production"
EnvironmentFile=/home/keepitgoing/KeepItGoingServer/.env
ExecStart=/home/keepitgoing/KeepItGoingServer/venv/bin/gunicorn \
--workers 3 \
--bind unix:/home/keepitgoing/KeepItGoingServer/gunicorn.sock \
--timeout 60 \
--access-logfile /var/log/keepitgoing/access.log \
--error-logfile /var/log/keepitgoing/error.log \
config.wsgi:application
ExecReload=/bin/kill -s HUP $MAINPID
KillMode=mixed
TimeoutStopSec=5
PrivateTmp=true
[Install]
WantedBy=multi-user.target
```
Create log directory:
```bash
sudo mkdir -p /var/log/keepitgoing
sudo chown keepitgoing:keepitgoing /var/log/keepitgoing
```
Enable and start service:
```bash
sudo systemctl daemon-reload
sudo systemctl enable keepitgoing
sudo systemctl start keepitgoing
sudo systemctl status keepitgoing
```
#### Step 6: Celery Service (Optional, for background tasks)
```bash
sudo nano /etc/systemd/system/keepitgoing-celery.service
```
```ini
[Unit]
Description=KeepItGoing Celery Worker
After=network.target redis.service
[Service]
Type=forking
User=keepitgoing
Group=keepitgoing
WorkingDirectory=/home/keepitgoing/KeepItGoingServer
Environment="PATH=/home/keepitgoing/KeepItGoingServer/venv/bin"
Environment="DJANGO_SETTINGS_MODULE=config.settings.production"
EnvironmentFile=/home/keepitgoing/KeepItGoingServer/.env
ExecStart=/home/keepitgoing/KeepItGoingServer/venv/bin/celery -A config worker -l info
[Install]
WantedBy=multi-user.target
```
Enable and start:
```bash
sudo systemctl enable keepitgoing-celery
sudo systemctl start keepitgoing-celery
```
#### Step 7: Nginx Configuration
```bash
sudo nano /etc/nginx/sites-available/keepitgoing
```
Add the following configuration:
```nginx ```nginx
upstream keepitgoing {
server unix:/home/keepitgoing/KeepItGoingServer/gunicorn.sock fail_timeout=0;
}
server { server {
listen 443 ssl; listen 80;
server_name tasks.firebugit.com; server_name tasks.firebugit.com;
ssl_certificate /path/to/cert.pem; # Redirect HTTP to HTTPS
ssl_certificate_key /path/to/key.pem; return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name tasks.firebugit.com;
# SSL Configuration
ssl_certificate /etc/letsencrypt/live/tasks.firebugit.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/tasks.firebugit.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# Security Headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
client_max_body_size 10M;
# Static files
location /static/ {
alias /home/keepitgoing/KeepItGoingServer/staticfiles/;
expires 30d;
add_header Cache-Control "public, immutable";
}
# Media files
location /media/ {
alias /home/keepitgoing/KeepItGoingServer/media/;
expires 7d;
}
# Application
location / { location / {
proxy_pass http://localhost:8000; proxy_pass http://keepitgoing;
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Proto $scheme;
} proxy_redirect off;
location /static/ { # WebSocket support (if needed)
alias /path/to/static/; proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
} }
} }
``` ```
Enable site and restart nginx:
```bash
sudo ln -s /etc/nginx/sites-available/keepitgoing /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
```
#### Step 8: SSL Certificate (Let's Encrypt)
```bash
# Obtain SSL certificate
sudo certbot --nginx -d tasks.firebugit.com
# Certbot will automatically configure nginx
# Certificate auto-renews via cron
```
#### Step 9: Firewall Setup
```bash
# Allow SSH, HTTP, and HTTPS
sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable
sudo ufw status
```
#### Step 10: Initial Admin User and Approval
```bash
# Log in to the web interface at https://tasks.firebugit.com/admin
# Use the superuser credentials created in Step 3
# When new users register:
# 1. They receive verification email
# 2. After clicking verification link, you receive admin notification
# 3. Go to Admin > Users > select user(s) > Actions > "Approve selected users"
# 4. User receives approval email and can now log in
```
### Production Checklist
Complete this checklist before going live:
**Security:**
- [ ] Set `DEBUG = False` in production settings
- [ ] Generate and configure strong `SECRET_KEY`
- [ ] Set up proper `ALLOWED_HOSTS` (only your domain)
- [ ] Configure `CSRF_TRUSTED_ORIGINS` for HTTPS
- [ ] Install and configure SSL/TLS certificates
- [ ] Enable firewall (ufw) with only necessary ports
- [ ] Set strong passwords for database and admin users
- [ ] Review and harden SSH configuration
- [ ] Configure security headers in nginx
**Database:**
- [ ] Use PostgreSQL (not SQLite) in production
- [ ] Configure regular database backups
- [ ] Set up database connection pooling if needed
- [ ] Verify database user has minimum required permissions
**Email:**
- [ ] Configure production email backend (SMTP)
- [ ] Test email delivery (verification and approval emails)
- [ ] Verify sender domain/email is whitelisted
- [ ] Set up SPF, DKIM, and DMARC records for your domain
- [ ] Monitor email delivery rates and bounces
**Application:**
- [ ] Run `python manage.py migrate` to apply all migrations
- [ ] Run `python manage.py collectstatic` for static files
- [ ] Create superuser account for admin access
- [ ] Test user registration and email verification flow
- [ ] Test admin approval workflow
- [ ] Configure `SITE_DOMAIN` to your production domain
- [ ] Set appropriate `EMAIL_VERIFICATION_TOKEN_EXPIRY_HOURS`
**Services:**
- [ ] Set up Gunicorn systemd service
- [ ] Configure nginx as reverse proxy
- [ ] Set up Redis for Celery (if using background tasks)
- [ ] Configure Celery systemd service (if needed)
- [ ] Verify all services start on boot
**Monitoring & Logging:**
- [ ] Set up application logging
- [ ] Configure nginx access and error logs
- [ ] Set up log rotation
- [ ] Configure system monitoring (disk, memory, CPU)
- [ ] Set up uptime monitoring
- [ ] Configure error alerting (email or Slack)
- [ ] Monitor database performance
**Backups:**
- [ ] Configure automated database backups
- [ ] Set up media file backups
- [ ] Test backup restoration process
- [ ] Store backups off-site
- [ ] Document backup and recovery procedures
**Performance:**
- [ ] Configure appropriate Gunicorn worker count
- [ ] Enable nginx gzip compression
- [ ] Set up static file caching
- [ ] Configure database connection pooling
- [ ] Monitor application performance
- [ ] Set up CDN for static files (optional)
### Troubleshooting
**Gunicorn won't start:**
```bash
# Check service status
sudo systemctl status keepitgoing
# View logs
sudo journalctl -u keepitgoing -n 50
# Check if socket exists
ls -la /home/keepitgoing/KeepItGoingServer/gunicorn.sock
```
**Emails not sending:**
```bash
# Test email configuration in Django shell
sudo su - keepitgoing
cd KeepItGoingServer
source venv/bin/activate
export DJANGO_SETTINGS_MODULE=config.settings.production
python manage.py shell
# In the shell:
from django.core.mail import send_mail
send_mail(
'Test Subject',
'Test message.',
'noreply@firebugit.com',
['your-email@example.com'],
)
# Check for any errors
```
**Static files not loading:**
```bash
# Recollect static files
sudo su - keepitgoing
cd KeepItGoingServer
source venv/bin/activate
export DJANGO_SETTINGS_MODULE=config.settings.production
python manage.py collectstatic --noinput
# Check nginx configuration
sudo nginx -t
# Check file permissions
ls -la /home/keepitgoing/KeepItGoingServer/staticfiles/
```
**Database connection errors:**
```bash
# Test PostgreSQL connection
sudo -u postgres psql keepitgoing
# Check if PostgreSQL is running
sudo systemctl status postgresql
# Verify credentials in .env match database
```
**Permission denied errors:**
```bash
# Fix ownership
sudo chown -R keepitgoing:keepitgoing /home/keepitgoing/KeepItGoingServer
# Fix socket permissions
sudo chown keepitgoing:www-data /home/keepitgoing/KeepItGoingServer/gunicorn.sock
```
### Maintenance Tasks
**Update application:**
```bash
sudo su - keepitgoing
cd KeepItGoingServer
git pull origin main
source venv/bin/activate
pip install -r requirements.txt
export DJANGO_SETTINGS_MODULE=config.settings.production
python manage.py migrate
python manage.py collectstatic --noinput
exit
# Restart services
sudo systemctl restart keepitgoing
```
**Database backup:**
```bash
# Manual backup
sudo -u postgres pg_dump keepitgoing > keepitgoing_backup_$(date +%Y%m%d).sql
# Automated backup (add to crontab)
0 2 * * * sudo -u postgres pg_dump keepitgoing | gzip > /backups/keepitgoing_$(date +\%Y\%m\%d).sql.gz
```
**View application logs:**
```bash
# Gunicorn logs
sudo tail -f /var/log/keepitgoing/error.log
sudo tail -f /var/log/keepitgoing/access.log
# Nginx logs
sudo tail -f /var/log/nginx/error.log
sudo tail -f /var/log/nginx/access.log
# System logs
sudo journalctl -u keepitgoing -f
```
## Mobile App Integration ## Mobile App Integration
This server works with the KeepItGoing Android app via the sync endpoint. This server works with the KeepItGoing Android app via the sync endpoint.
@@ -496,6 +1013,16 @@ For issues and questions:
## Changelog ## Changelog
### Version 1.1.0 (2025-01-22)
- **Email Verification System**: Users must verify email before logging in
- **Admin Approval Workflow**: Admins approve new users via Django admin
- **Email Notifications**: Verification, approval, and admin notification emails
- **Password Change**: Users can change their password from profile page
- **Enhanced Registration**: Collect first name, last name, and timezone
- **Profile Enhancements**: Improved profile page with dark/light mode support
- **Security**: UUID tokens, expiration, one-time use, email enumeration protection
- **Custom Authentication**: Backend enforces verification and approval
### Version 1.0.0 (2025-01-18) ### Version 1.0.0 (2025-01-18)
- Initial release - Initial release
- Complete task management system - Complete task management system