# 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 admin-created or self-registered accounts - **Admin Approval**: Optional 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** ```bash git clone https://git.firebugit.com/Firebug_IT/KeepItGoingServer.git cd KeepItGoingServer ``` 2. **Create virtual environment** ```bash python3 -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate ``` 3. **Install dependencies** ```bash pip install -r requirements.txt ``` 4. **Configure environment** ```bash cp .env.example .env # Edit .env with your settings ``` 5. **Run migrations** ```bash export DJANGO_SETTINGS_MODULE=config.settings.development python manage.py migrate ``` 6. **Create superuser** ```bash python manage.py createsuperuser ``` 7. **Run development server** ```bash python manage.py runserver ``` 8. **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 development - `config.settings.production` - Production deployment - `config.settings.selfhosted` - Self-hosted instances Set via environment variable: ```bash export DJANGO_SETTINGS_MODULE=config.settings.development ``` ### Registration Control Self-registration is controlled with `ALLOW_SELF_REGISTRATION`. - `ALLOW_SELF_REGISTRATION=False` disables public signup and requires an administrator to create accounts - `ALLOW_SELF_REGISTRATION=True` enables the `/register/` page and `/api/users/register/` endpoint If the variable is omitted, self-registration is disabled by default. ### 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`:** ```python DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': BASE_DIR / 'db.sqlite3', } } ``` **Using DATABASE_URL in `.env`:** ```bash 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:** ```bash # 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:** ```bash 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:** ```bash # For production use: pip install psycopg2-binary # For development/if psycopg2-binary fails: # pip install psycopg2 ``` **4. Update settings:** Add to your `.env` file: ```bash DATABASE_URL=postgresql://keepitgoing_user:your_secure_password@localhost:5432/keepitgoing ``` Or configure directly in settings: ```python 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:** ```bash python manage.py migrate ``` **6. Performance tuning (optional):** Edit `/etc/postgresql/[version]/main/postgresql.conf`: ```ini # 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: ```bash 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:** ```bash # 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):** ```bash 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:** ```bash 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:** ```bash 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: ```bash DATABASE_URL=mysql://keepitgoing_user:your_secure_password@localhost:3306/keepitgoing ``` Or configure directly in settings: ```python 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:** ```bash 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): ```ini [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: ```bash sudo systemctl restart mariadb # or mysql ``` #### Database Migration Between Backends To migrate data from one database to another: **1. Export data from current database:** ```bash 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:** ```bash python manage.py migrate --run-syncdb ``` **4. Import data:** ```bash 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 `) - `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:** ```bash POST /api/auth/login/ { "email": "user@example.com", "password": "password" } ``` **Use Token:** ```bash Authorization: Bearer ``` ### 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 ```bash python manage.py test ``` ### Creating Migrations ```bash python manage.py makemigrations ``` ### Collecting Static Files ```bash 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 ```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 Choose your database backend. PostgreSQL is recommended for production. **Option A: PostgreSQL (Recommended for Production)** ```bash # 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)** ```bash # 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 ```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 # 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 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.): ```env 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 ``` **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` ```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 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: ```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 # If ALLOW_SELF_REGISTRATION=True and 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 # # If ALLOW_SELF_REGISTRATION=False: # 1. Create users through Django admin or management commands # 2. Mark them verified/approved as needed for your onboarding flow ``` ### 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 - [ ] Confirm `ALLOW_SELF_REGISTRATION` is set correctly for production - [ ] Test account onboarding flow (admin-created users or public registration) - [ ] 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 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: - 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