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>
7.7 KiB
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
- Log into your Portainer instance
- Select your Docker environment
- Navigate to Stacks in the left sidebar
Step 2: Create New Stack
- Click + Add stack button
- Enter stack name:
keepitgoing
Step 3: Configure Git Repository
-
Select Git Repository as the build method
-
Fill in the following details:
Repository URL:
https://git.firebugit.com/Firebug_IT/KeepItGoingServer.gitRepository reference:
refs/heads/mainCompose path:
docker-compose.ymlAuthentication:
- 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:
# 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 <kig@keepitgoing.app>
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
- Scroll to the bottom
- Click Deploy the stack
- 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
- Wait for the stack to deploy (2-5 minutes for first deployment)
- In Portainer, go to Stacks > keepitgoing
- 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
- In Portainer, navigate to Containers
- Click on keepitgoing-web container
- Click Console button
- Select Connect with
/bin/bashshell - Run the following command:
python manage.py createsuperuser - Follow the prompts to create your admin account
Step 9: Configure Nginx Proxy Manager
-
Open your Nginx Proxy Manager
-
Go to Hosts > Proxy Hosts
-
Click Add Proxy Host
-
Configure as follows:
Details tab:
- Domain Names:
keepitgoing.app(andwww.keepitgoing.appif needed) - Scheme:
http - Forward Hostname/IP:
- If NPM is on same Docker network:
keepitgoing-web - If NPM is on same server but different network:
localhostor server IP - Port:
8000
- If NPM is on same Docker network:
- 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)
- Domain Names:
-
Save the proxy host
Step 10: Test the Deployment
- Visit
https://keepitgoing.app/api/- Should show API root - Visit
https://keepitgoing.app/admin/- Should show Django admin login - Log in with your superuser credentials
- Test user registration flow (requires email verification)
Post-Deployment
Updating the Stack
When you push new code to the Git repository:
- In Portainer, go to Stacks > keepitgoing
- Click ⚙️ Editor button
- Enable Pull latest image (if needed)
- Click ↻ Git pull and redeploy at the bottom
- Portainer will pull the latest code and redeploy
Or manually:
- 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:
- Go to Containers > keepitgoing-db
- Click Console
- Run:
mysqldump -u root -p keepitgoing > /tmp/backup.sql - Enter root password:
l7xF4j20HxqE2ZGNDR2FIoCCYwb6tDMq - Use File browser to download
/tmp/backup.sql
Scaling
To scale the web service for more capacity:
- Stop the stack
- Edit
docker-compose.ymlin Git - Add to web service:
deploy: replicas: 3 - Push to Git and redeploy in Portainer
Troubleshooting
Container won't start
- Check logs in Portainer
- Verify environment variables are set correctly
- Ensure MariaDB and Redis are healthy before web/celery start
Database connection errors
- Check
keepitgoing-dbcontainer is running - Verify
DB_PASSWORDmatches in environment variables - Check
DATABASE_URLis correctly formatted
Can't access via domain
- Verify Nginx Proxy Manager configuration
- Check port 8000 is accessible from NPM
- Verify
ALLOWED_HOSTSincludes your domain - Check firewall rules
Email not sending
- Verify SMTP credentials are correct
- Check Dreamhost allows SMTP from your server IP
- View web container logs for email errors
Security Notes
- ✅
.env.dockeris 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.mdin 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 persistencekeepitgoing_redis_data- Redis persistencekeepitgoing_static_files- Collected static files./media- User uploaded files (avatars)
Networks:
keepitgoing_frontend- External network (web service)keepitgoing_backend- Internal network (database, redis)