Added comprehensive rate limiting to prevent abuse and DoS attacks: Configuration (config/settings/base.py): - Anon rate: 100 requests/hour for anonymous users - User rate: 1000 requests/hour for authenticated users - Login rate: 10 attempts/hour (prevents brute force) - Register rate: 5 attempts/hour (prevents account spam) - Sync rate: 100 requests/hour (prevents sync flooding) Custom throttle classes (users/throttles.py): - LoginRateThrottle: Strict limit for login endpoint - RegisterRateThrottle: Strict limit for registration endpoint - SyncRateThrottle: Moderate limit for sync endpoint Applied throttling to sensitive endpoints: - users.views.RegisterAPIView: 5/hour - users.views.TokenObtainPairView: 10/hour - sync.views.sync: 100/hour All other API endpoints use default throttles (anon: 100/hour, user: 1000/hour). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
KeepItGoing Server
A powerful Django-based task management system with time tracking, tag organization, and multi-user support.
Features
Task Management
- Hierarchical Tasks: Support for parent tasks and subtasks
- Priority Levels: Low, Medium, High, and Urgent
- Status Tracking: Pending, In Progress, Completed, Cancelled
- Due Dates & Times: Set specific due dates and times for tasks
- Recurrence: Daily, Weekly, Bi-weekly, Monthly, Yearly, and Custom patterns
Organization
- Tag-Based System: Organize tasks with multiple colored tags
- Smart Filtering: View tasks by All, Today, Upcoming, Overdue, or Completed
- Auto-Tag Assignment: New tasks automatically inherit the active filter tag
- Flexible Sorting: Sort by due date (earliest/latest) or priority (high-to-low/low-to-high)
Time Tracking
- Start/Stop Timers: Built-in time tracking for tasks
- Time Entry History: View detailed time logs for each task
- Formatted Display: Time shown as H:MM:SS with visual indicators
- Running Timer Display: Always visible timer in the UI when tracking time
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
User Interface
- 3-Pane Layout: Sidebar navigation, task list, and detail panel
- Responsive Design: Works on desktop, tablet, and mobile
- Dark Mode: Built-in dark/light theme toggle
- Quick Add: Fast task creation from any filter view
- Inline Actions: Toggle completion, start/stop timers without leaving the list
API & Sync
- RESTful API: Full REST API for programmatic access
- Mobile App Support: Sync protocol for Android app
- Real-time Updates: Task changes sync across devices
- Conflict Resolution: Handles offline changes and syncing
Tech Stack
- Backend: Django 5.x, Django REST Framework
- Database: SQLite (development), PostgreSQL-compatible
- Task Queue: Celery with Redis
- Authentication: JWT tokens with session support
- Frontend: HTML5, CSS3, Vanilla JavaScript
Installation
Prerequisites
- Python 3.12+
- pip
- virtualenv (recommended)
Quick Start
-
Clone the repository
git clone https://git.firebugit.com/Firebug_IT/KeepItGoingServer.git cd KeepItGoingServer -
Create virtual environment
python3 -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate -
Install dependencies
pip install -r requirements.txt -
Configure environment
cp .env.example .env # Edit .env with your settings -
Run migrations
export DJANGO_SETTINGS_MODULE=config.settings.development python manage.py migrate -
Create superuser
python manage.py createsuperuser -
Run development server
python manage.py runserver -
Access the application
- Web Interface: http://localhost:8000
- Admin Panel: http://localhost:8000/admin
- API Root: http://localhost:8000/api/
Configuration
Settings Modules
The project uses different settings modules for different environments:
config.settings.development- Local developmentconfig.settings.production- Production deploymentconfig.settings.selfhosted- Self-hosted instances
Set via environment variable:
export DJANGO_SETTINGS_MODULE=config.settings.development
Database Configuration
The application supports multiple database backends. Choose the one that fits your needs.
SQLite3 (Default - Development)
SQLite3 is the default database and requires no additional setup. It's perfect for development, testing, and single-user scenarios.
No installation required - SQLite comes bundled with Python.
Configuration in config/settings/development.py:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
Using DATABASE_URL in .env:
DATABASE_URL=sqlite:///db.sqlite3
When to use SQLite:
- ✅ Development and testing
- ✅ Single-user deployments
- ✅ Low-traffic personal projects
- ✅ Quick prototyping
- ✅ Embedded applications
When NOT to use SQLite:
- ❌ Production with multiple concurrent users
- ❌ High-traffic websites
- ❌ Applications requiring network database access
- ❌ Heavy write operations
Pros:
- Zero configuration - works out of the box
- No separate database server needed
- Lightweight and fast for small datasets
- Perfect for development and testing
- Easy to backup (single file)
Cons:
- Not recommended for production with multiple users
- Limited concurrent write operations (can cause database locks)
- No network access (local file only)
- Not suitable for high-traffic applications
- Limited scalability
PostgreSQL (Recommended for Production)
PostgreSQL is the recommended database for production deployments. It offers the best combination of performance, features, and reliability for Django applications.
When to use PostgreSQL:
- ✅ Production environments (highly recommended)
- ✅ Applications with multiple concurrent users
- ✅ Need for advanced features (JSONB, full-text search, etc.)
- ✅ Complex queries and data integrity requirements
- ✅ Scalability and performance are priorities
- ✅ Geographic data (PostGIS extension)
1. Install PostgreSQL:
# Ubuntu/Debian
sudo apt-get install postgresql postgresql-contrib libpq-dev
# macOS
brew install postgresql
# Start PostgreSQL service
# Ubuntu/Debian:
sudo systemctl start postgresql
sudo systemctl enable postgresql
# macOS:
brew services start postgresql
2. Create database and user:
sudo -u postgres psql
CREATE DATABASE keepitgoing;
CREATE USER keepitgoing_user WITH PASSWORD 'your_secure_password';
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;
-- For PostgreSQL 15+, also grant schema permissions:
\c keepitgoing
GRANT ALL ON SCHEMA public TO keepitgoing_user;
\q
3. Install Python driver:
# For production use:
pip install psycopg2-binary
# For development/if psycopg2-binary fails:
# pip install psycopg2
4. Update settings:
Add to your .env file:
DATABASE_URL=postgresql://keepitgoing_user:your_secure_password@localhost:5432/keepitgoing
Or configure directly in settings:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'keepitgoing',
'USER': 'keepitgoing_user',
'PASSWORD': 'your_secure_password',
'HOST': 'localhost',
'PORT': '5432',
'CONN_MAX_AGE': 600, # Connection pooling
}
}
5. Run migrations:
python manage.py migrate
6. Performance tuning (optional):
Edit /etc/postgresql/[version]/main/postgresql.conf:
# Adjust based on available RAM (25% of total RAM)
shared_buffers = 256MB
# Effective cache size (50-75% of total RAM)
effective_cache_size = 1GB
# Maintenance work memory
maintenance_work_mem = 64MB
# Maximum connections
max_connections = 100
Restart PostgreSQL:
sudo systemctl restart postgresql
MariaDB/MySQL (Alternative Production Database)
MariaDB and MySQL are well-supported alternatives for production deployments. MariaDB is recommended over MySQL for better performance and features.
When to use MySQL/MariaDB:
- ✅ Production environments with multiple users
- ✅ Applications requiring replication
- ✅ Teams familiar with MySQL ecosystem
- ✅ Need for specific MySQL features or tools
- ✅ Integration with existing MySQL infrastructure
1. Install MariaDB:
# Ubuntu/Debian
sudo apt-get install mariadb-server libmariadb-dev
# macOS
brew install mariadb
# For MySQL instead of MariaDB:
# Ubuntu/Debian: sudo apt-get install mysql-server libmysqlclient-dev
# macOS: brew install mysql
2. Secure installation (recommended):
sudo mysql_secure_installation
# This will prompt you to:
# - Set root password
# - Remove anonymous users
# - Disallow root login remotely
# - Remove test database
3. Create database and user:
sudo mysql
CREATE DATABASE keepitgoing CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'keepitgoing_user'@'localhost' IDENTIFIED BY 'your_secure_password';
GRANT ALL PRIVILEGES ON keepitgoing.* TO 'keepitgoing_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;
4. Install Python driver:
pip install mysqlclient
# If mysqlclient installation fails, you can use PyMySQL as an alternative:
# pip install pymysql
# Then add to your settings: import pymysql; pymysql.install_as_MySQLdb()
5. Update settings:
Add to your .env file:
DATABASE_URL=mysql://keepitgoing_user:your_secure_password@localhost:3306/keepitgoing
Or configure directly in settings:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'keepitgoing',
'USER': 'keepitgoing_user',
'PASSWORD': 'your_secure_password',
'HOST': 'localhost',
'PORT': '3306',
'OPTIONS': {
'charset': 'utf8mb4',
'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
},
}
}
6. Run migrations:
python manage.py migrate
Performance tuning (optional):
Edit /etc/mysql/mariadb.conf.d/50-server.cnf (MariaDB) or /etc/mysql/mysql.conf.d/mysqld.cnf (MySQL):
[mysqld]
# Increase buffer pool size (adjust based on available RAM)
innodb_buffer_pool_size = 1G
# Improve connection handling
max_connections = 200
# Enable query cache (MySQL 5.7 only, removed in MySQL 8.0)
query_cache_type = 1
query_cache_size = 64M
Restart database:
sudo systemctl restart mariadb # or mysql
Database Migration Between Backends
To migrate data from one database to another:
1. Export data from current database:
python manage.py dumpdata --natural-foreign --natural-primary \
-e contenttypes -e auth.Permission --indent 4 > data.json
2. Update database settings to new backend
3. Run migrations on new database:
python manage.py migrate --run-syncdb
4. Import data:
python manage.py loaddata data.json
Environment Variables
Key environment variables (see .env.example):
Core Settings
SECRET_KEY- Django secret key (required in production, generate withpython -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())")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)
Redis & Celery
REDIS_URL- Redis connection for Celery (e.g.,redis://localhost:6379/0)
Email Configuration (Required for Email Verification)
EMAIL_BACKEND- Email backend (usedjango.core.mail.backends.smtp.EmailBackendfor 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/emailEMAIL_HOST_PASSWORD- SMTP password or API keyDEFAULT_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
Authentication
The API supports both session-based and token-based authentication.
Get Token:
POST /api/auth/login/
{
"email": "user@example.com",
"password": "password"
}
Use Token:
Authorization: Bearer <token>
Endpoints
Tasks
GET /api/tasks/- List all tasksPOST /api/tasks/- Create taskGET /api/tasks/{id}/- Get task detailsPUT /api/tasks/{id}/- Update taskDELETE /api/tasks/{id}/- Delete task
Tags
GET /api/tags/- List all tagsPOST /api/tags/- Create tagGET /api/tags/{id}/- Get tag detailsPUT /api/tags/{id}/- Update tagDELETE /api/tags/{id}/- Delete tag
Time Entries
GET /api/time-entries/- List time entriesPOST /api/time-entries/- Create time entryPOST /api/tasks/{id}/start-timer/- Start timerPOST /api/time-entries/{id}/stop/- Stop timer
Sync (Mobile)
POST /api/sync/sync/- Bidirectional sync endpoint
Project Structure
keepitgoing-server/
├── config/ # Project configuration
│ ├── settings/ # Environment-specific settings
│ ├── urls.py # Main URL configuration
│ └── wsgi.py # WSGI entry point
├── tasks/ # Task management app
│ ├── models.py # Task, Tag, TimeEntry models
│ ├── views.py # API and web views
│ ├── serializers.py # DRF serializers
│ └── migrations/ # Database migrations
├── users/ # User management app
├── sync/ # Mobile sync app
├── notifications/ # Notification system
├── templates/ # Django templates
│ ├── base.html # Base template
│ └── tasks/ # Task templates
├── static/ # Static files
│ ├── css/ # Stylesheets
│ └── js/ # JavaScript
├── manage.py # Django management script
└── requirements.txt # Python dependencies
Database Models
Task
- Hierarchical structure (parent/subtasks)
- Multiple tags per task
- Due date and time
- Priority and status
- Recurrence patterns
- Soft delete support
Tag
- Color-coded organization
- Multi-task assignment
- Sort ordering
- Archive capability
TimeEntry
- Start/end timestamps
- Duration calculation
- User association
Development
Running Tests
python manage.py test
Creating Migrations
python manage.py makemigrations
Collecting Static Files
python manage.py collectstatic
Code Style
- Follow PEP 8 for Python code
- Use meaningful variable names
- Add docstrings to functions and classes
Deployment
Production Setup Guide
This guide covers deploying KeepItGoing Server in a production environment.
Prerequisites
- 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
# 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
Choose your database backend. PostgreSQL is recommended for production.
Option A: PostgreSQL (Recommended for Production)
# Install PostgreSQL
sudo apt install -y postgresql postgresql-contrib libpq-dev
# 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
Option B: MySQL/MariaDB (Alternative Production Database)
# Install MariaDB
sudo apt install -y mariadb-server libmariadb-dev
# Secure MariaDB installation
sudo mysql_secure_installation
# Create database and user
sudo mysql << EOF
CREATE DATABASE keepitgoing CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'keepitgoing_user'@'localhost' IDENTIFIED BY 'STRONG_PASSWORD_HERE';
GRANT ALL PRIVILEGES ON keepitgoing.* TO 'keepitgoing_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;
EOF
Option C: SQLite (Development/Testing Only)
No database server setup required. SQLite uses a local file and is configured automatically. Not recommended for production with multiple users.
Step 3: Application Setup
# 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
# Install database driver based on your choice from Step 2
# For PostgreSQL:
pip install psycopg2-binary
# For MySQL/MariaDB:
# pip install mysqlclient
# For SQLite: no additional package needed
# 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 Configuration
# Choose ONE of the following based on your database from Step 2:
# Option A: PostgreSQL (Recommended)
DATABASE_URL=postgresql://keepitgoing_user:STRONG_PASSWORD_HERE@localhost:5432/keepitgoing
# Option B: MySQL/MariaDB (Alternative)
# DATABASE_URL=mysql://keepitgoing_user:STRONG_PASSWORD_HERE@localhost:3306/keepitgoing
# Option C: SQLite (Development/Testing only - Not for production!)
# DATABASE_URL=sqlite:///db.sqlite3
# Email Configuration (Gmail example - see Step 4 for other providers)
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:
Generic SMTP Server (Any Provider):
For any standard SMTP server (custom mail server, hosting provider, etc.):
EMAIL_HOST=smtp.yourdomain.com
EMAIL_PORT=587 # Use 587 for TLS or 465 for SSL
EMAIL_USE_TLS=True # Set to True for port 587
EMAIL_USE_SSL=False # Set to True for port 465 (not both TLS and SSL)
EMAIL_HOST_USER=noreply@yourdomain.com
EMAIL_HOST_PASSWORD=your-smtp-password
DEFAULT_FROM_EMAIL=KeepItGoing <noreply@yourdomain.com>
Common SMTP ports:
- Port 587: STARTTLS (recommended) - use
EMAIL_USE_TLS=True - Port 465: SSL/TLS - use
EMAIL_USE_SSL=True - Port 25: Unencrypted (not recommended)
Gmail:
- Enable 2-factor authentication on your Google account
- Generate an App Password: https://myaccount.google.com/apppasswords
- Use the app password in
EMAIL_HOST_PASSWORD
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:
- Create SendGrid account and verify sender identity
- Generate API key from Settings > API Keys
- Configure:
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:
- Verify domain in AWS SES console
- Create SMTP credentials
- Configure:
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:
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:
sudo nano /etc/systemd/system/keepitgoing.service
Add the following content:
[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:
sudo mkdir -p /var/log/keepitgoing
sudo chown keepitgoing:keepitgoing /var/log/keepitgoing
Enable and start service:
sudo systemctl daemon-reload
sudo systemctl enable keepitgoing
sudo systemctl start keepitgoing
sudo systemctl status keepitgoing
Step 6: Celery Service (Optional, for background tasks)
sudo nano /etc/systemd/system/keepitgoing-celery.service
[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:
sudo systemctl enable keepitgoing-celery
sudo systemctl start keepitgoing-celery
Step 7: Nginx Configuration
sudo nano /etc/nginx/sites-available/keepitgoing
Add the following configuration:
upstream keepitgoing {
server unix:/home/keepitgoing/KeepItGoingServer/gunicorn.sock fail_timeout=0;
}
server {
listen 80;
server_name tasks.firebugit.com;
# Redirect HTTP to HTTPS
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 / {
proxy_pass http://keepitgoing;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
# WebSocket support (if needed)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
Enable site and restart nginx:
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)
# Obtain SSL certificate
sudo certbot --nginx -d tasks.firebugit.com
# Certbot will automatically configure nginx
# Certificate auto-renews via cron
Step 9: Firewall Setup
# 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
# 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 = Falsein production settings - Generate and configure strong
SECRET_KEY - Set up proper
ALLOWED_HOSTS(only your domain) - Configure
CSRF_TRUSTED_ORIGINSfor 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 migrateto apply all migrations - Run
python manage.py collectstaticfor static files - Create superuser account for admin access
- Test user registration and email verification flow
- Test admin approval workflow
- Configure
SITE_DOMAINto 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:
# 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:
# 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:
# 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:
# 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:
# 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:
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:
# 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:
# 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
This server works with the KeepItGoing Android app via the sync endpoint.
Sync Protocol:
- Client sends current state and last sync timestamp
- Server returns updates since last sync
- Server accepts client changes
- Conflict resolution handled server-side
Contributing
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
Proprietary - All Rights Reserved Copyright (c) 2025 Firebug IT
Support
For issues and questions:
- Create an issue in the repository
- Email: keith@firebugit.com
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)
- Initial release
- Complete task management system
- Tag-based organization
- Time tracking
- Multi-user support
- Mobile app sync
- Web interface with dark mode
- Responsive design
- RESTful API
Built with ❤️ by Firebug IT