Keith SmithandClaude Sonnet 4.5 4e903b688d Fix duplicate user field in tasks migration
Remove duplicate AddField operation for tag.user field in
tasks/migrations/0002_initial.py. The migration was attempting
to add the user ForeignKey field twice, causing PostgreSQL to
fail with "column 'user_id' of relation 'tags' already exists".

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-26 17:01:59 -07:00
2025-12-26 15:59:09 -07:00
2025-12-26 15:59:09 -07:00

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

  1. Clone the repository

    git clone https://git.firebugit.com/Firebug_IT/KeepItGoingServer.git
    cd KeepItGoingServer
    
  2. Create virtual environment

    python3 -m venv venv
    source venv/bin/activate  # On Windows: venv\Scripts\activate
    
  3. Install dependencies

    pip install -r requirements.txt
    
  4. Configure environment

    cp .env.example .env
    # Edit .env with your settings
    
  5. Run migrations

    export DJANGO_SETTINGS_MODULE=config.settings.development
    python manage.py migrate
    
  6. Create superuser

    python manage.py createsuperuser
    
  7. Run development server

    python manage.py runserver
    
  8. Access the application

Configuration

Settings Modules

The project uses different settings modules for different environments:

  • config.settings.development - Local development
  • config.settings.production - Production deployment
  • config.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 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 with python -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 (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

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 tasks
  • POST /api/tasks/ - Create task
  • GET /api/tasks/{id}/ - Get task details
  • PUT /api/tasks/{id}/ - Update task
  • DELETE /api/tasks/{id}/ - Delete task

Tags

  • GET /api/tags/ - List all tags
  • POST /api/tags/ - Create tag
  • GET /api/tags/{id}/ - Get tag details
  • PUT /api/tags/{id}/ - Update tag
  • DELETE /api/tags/{id}/ - Delete tag

Time Entries

  • GET /api/time-entries/ - List time entries
  • POST /api/time-entries/ - Create time entry
  • POST /api/tasks/{id}/start-timer/ - Start timer
  • POST /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:

  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
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:
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:
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 = 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:

# 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

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

Proprietary - All Rights Reserved Copyright (c) 2025 Firebug IT

Support

For issues and questions:

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

S
Description
Task management solution Server
Readme
637 KiB
2026-01-04 10:09:58 -07:00
Languages
Python 55.1%
HTML 23.8%
CSS 10.4%
JavaScript 7.3%
Shell 1.8%
Other 1.6%