Files

1213 lines
33 KiB
Markdown

# 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 <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:**
```bash
POST /api/auth/login/
{
"email": "user@example.com",
"password": "password"
}
```
**Use Token:**
```bash
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
```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 <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.):
```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 <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`
```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