diff --git a/PORTAINER_DEPLOYMENT.md b/PORTAINER_DEPLOYMENT.md new file mode 100644 index 0000000..9c5eba5 --- /dev/null +++ b/PORTAINER_DEPLOYMENT.md @@ -0,0 +1,289 @@ +# KeepItGoing Server - Portainer Stack Deployment Guide + +## Overview + +This guide will walk you through deploying the KeepItGoing server to your Docker server using Portainer Stacks with Git repository integration. + +## Prerequisites + +- Portainer installed and accessible +- Access to your Docker server via Portainer +- Git repository: `https://git.firebugit.com/Firebug_IT/KeepItGoingServer.git` +- Git credentials configured in Portainer (or repository is public) + +## Deployment Steps + +### Step 1: Access Portainer + +1. Log into your Portainer instance +2. Select your Docker environment +3. Navigate to **Stacks** in the left sidebar + +### Step 2: Create New Stack + +1. Click **+ Add stack** button +2. Enter stack name: `keepitgoing` + +### Step 3: Configure Git Repository + +1. Select **Git Repository** as the build method +2. Fill in the following details: + + **Repository URL:** + ``` + https://git.firebugit.com/Firebug_IT/KeepItGoingServer.git + ``` + + **Repository reference:** `refs/heads/main` + + **Compose path:** `docker-compose.yml` + + **Authentication:** + - If repository is private, enable authentication + - Username: `keith@firebugit.com` + - Password: (your Git password) + - Or use an access token if available + +### Step 4: Configure Environment Variables + +Scroll down to the **Environment variables** section and paste the following: + +```env +# Django Core Settings +SECRET_KEY=Zfb$!,3Gm\b,x~:a)9@k*Gun.#F{ju3dH-G8aWp4R"&NQ{1x>14v#)EbhpB*XMWD +DEBUG=False +ALLOWED_HOSTS=keepitgoing.app,www.keepitgoing.app,localhost +CSRF_TRUSTED_ORIGINS=https://keepitgoing.app,https://www.keepitgoing.app +SITE_DOMAIN=keepitgoing.app + +# Database Configuration +DB_NAME=keepitgoing +DB_USER=keepitgoing +DB_PASSWORD=6SWh6Pz01hBFGNzWM0Pszz2moluqxyv7 +DB_ROOT_PASSWORD=l7xF4j20HxqE2ZGNDR2FIoCCYwb6tDMq +DB_HOST=mariadb +DB_PORT=3306 + +# Redis Configuration +REDIS_URL=redis://redis:6379/0 + +# Email Configuration (Dreamhost SMTP) +EMAIL_BACKEND=django.core.mail.backends.smtp.EmailBackend +EMAIL_HOST=smtp.dreamhost.com +EMAIL_PORT=587 +EMAIL_USE_TLS=True +EMAIL_HOST_USER=kig@keepitgoing.app +EMAIL_HOST_PASSWORD=Frankenmonster1! +DEFAULT_FROM_EMAIL=KeepItGoing +SERVER_EMAIL=kig@keepitgoing.app + +# Email Verification +EMAIL_VERIFICATION_TOKEN_EXPIRY_HOURS=24 + +# CORS Configuration +CORS_ALLOWED_ORIGINS=https://keepitgoing.app,https://www.keepitgoing.app + +# SaaS Mode +SAAS_MODE=False + +# Gunicorn Configuration +GUNICORN_WORKERS=3 +GUNICORN_TIMEOUT=60 + +# Django Settings Module +DJANGO_SETTINGS_MODULE=config.settings.selfhosted +``` + +### Step 5: Deploy the Stack + +1. Scroll to the bottom +2. Click **Deploy the stack** +3. Portainer will: + - Clone the Git repository + - Pull/build the Docker images + - Start all 5 containers (mariadb, redis, web, celery-worker, celery-beat) + +### Step 6: Monitor Deployment + +1. Wait for the stack to deploy (2-5 minutes for first deployment) +2. In Portainer, go to **Stacks** > **keepitgoing** +3. Check the status of all containers: + - ✅ keepitgoing-db (mariadb) + - ✅ keepitgoing-redis + - ✅ keepitgoing-web + - ✅ keepitgoing-celery-worker + - ✅ keepitgoing-celery-beat + +### Step 7: View Logs + +Click on each container to view logs and ensure they started correctly: + +**Web container logs should show:** +``` +✓ MariaDB is ready! +Running database migrations... +✓ Migrations complete +Collecting static files... +✓ Static files collected +Starting Gunicorn WSGI server... +``` + +### Step 8: Create Django Superuser + +1. In Portainer, navigate to **Containers** +2. Click on **keepitgoing-web** container +3. Click **Console** button +4. Select **Connect** with `/bin/bash` shell +5. Run the following command: + ```bash + python manage.py createsuperuser + ``` +6. Follow the prompts to create your admin account + +### Step 9: Configure Nginx Proxy Manager + +1. Open your Nginx Proxy Manager +2. Go to **Hosts** > **Proxy Hosts** +3. Click **Add Proxy Host** +4. Configure as follows: + + **Details tab:** + - Domain Names: `keepitgoing.app` (and `www.keepitgoing.app` if needed) + - Scheme: `http` + - Forward Hostname/IP: + - If NPM is on same Docker network: `keepitgoing-web` + - If NPM is on same server but different network: `localhost` or server IP + - Port: `8000` + - Cache Assets: ✅ (enabled) + - Block Common Exploits: ✅ (enabled) + - Websockets Support: ✅ (enabled) + + **SSL tab:** + - SSL Certificate: Request a new SSL certificate + - Force SSL: ✅ (enabled) + - HTTP/2 Support: ✅ (enabled) + - HSTS Enabled: ✅ (enabled) + +5. Save the proxy host + +### Step 10: Test the Deployment + +1. Visit `https://keepitgoing.app/api/` - Should show API root +2. Visit `https://keepitgoing.app/admin/` - Should show Django admin login +3. Log in with your superuser credentials +4. Test user registration flow (requires email verification) + +## Post-Deployment + +### Updating the Stack + +When you push new code to the Git repository: + +1. In Portainer, go to **Stacks** > **keepitgoing** +2. Click **⚙️ Editor** button +3. Enable **Pull latest image** (if needed) +4. Click **↻ Git pull and redeploy** at the bottom +5. Portainer will pull the latest code and redeploy + +Or manually: +1. Click **⬇️ Pull and redeploy** button on the stack page + +### Viewing Logs + +In Portainer: +- **Stacks** > **keepitgoing** > **Logs** - View all container logs +- **Containers** > Select container > **Logs** - View individual container logs + +### Managing Containers + +All containers are visible in: +- **Stacks** > **keepitgoing** - Stack overview +- **Containers** - Individual container management + +### Database Backups + +To backup the database: + +1. Go to **Containers** > **keepitgoing-db** +2. Click **Console** +3. Run: + ```bash + mysqldump -u root -p keepitgoing > /tmp/backup.sql + ``` +4. Enter root password: `l7xF4j20HxqE2ZGNDR2FIoCCYwb6tDMq` +5. Use **File browser** to download `/tmp/backup.sql` + +### Scaling + +To scale the web service for more capacity: + +1. Stop the stack +2. Edit `docker-compose.yml` in Git +3. Add to web service: + ```yaml + deploy: + replicas: 3 + ``` +4. Push to Git and redeploy in Portainer + +## Troubleshooting + +### Container won't start + +1. Check logs in Portainer +2. Verify environment variables are set correctly +3. Ensure MariaDB and Redis are healthy before web/celery start + +### Database connection errors + +1. Check `keepitgoing-db` container is running +2. Verify `DB_PASSWORD` matches in environment variables +3. Check `DATABASE_URL` is correctly formatted + +### Can't access via domain + +1. Verify Nginx Proxy Manager configuration +2. Check port 8000 is accessible from NPM +3. Verify `ALLOWED_HOSTS` includes your domain +4. Check firewall rules + +### Email not sending + +1. Verify SMTP credentials are correct +2. Check Dreamhost allows SMTP from your server IP +3. View web container logs for email errors + +## Security Notes + +- ✅ `.env.docker` is **not** in Git repository (contains secrets) +- ✅ Environment variables are stored in Portainer (encrypted) +- ✅ Database passwords are randomly generated +- ✅ SSL/TLS enforced via Nginx Proxy Manager +- ✅ DEBUG=False in production +- ✅ All containers run as non-root users + +## Support + +For issues or questions: +- Check container logs in Portainer +- Review `README.md` in the repository +- Check Django admin for application-specific issues + +## Stack Information + +**Services:** +- **web** - Django/Gunicorn (port 8000) +- **mariadb** - MariaDB 11.2 database +- **redis** - Redis 7 cache/broker +- **celery-worker** - Background task processor +- **celery-beat** - Scheduled task scheduler + +**Volumes:** +- `keepitgoing_db_data` - Database persistence +- `keepitgoing_redis_data` - Redis persistence +- `keepitgoing_static_files` - Collected static files +- `./media` - User uploaded files (avatars) + +**Networks:** +- `keepitgoing_frontend` - External network (web service) +- `keepitgoing_backend` - Internal network (database, redis) diff --git a/tasks/migrations/0002_initial.py b/tasks/migrations/0002_initial.py index 8dd7b3d..b5e1f6e 100644 --- a/tasks/migrations/0002_initial.py +++ b/tasks/migrations/0002_initial.py @@ -35,11 +35,6 @@ class Migration(migrations.Migration): name='user', field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tasks', to=settings.AUTH_USER_MODEL), ), - migrations.AddField( - model_name='tag', - name='user', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tags', to=settings.AUTH_USER_MODEL), - ), migrations.AddField( model_name='task', name='group',