Files
KeepItGoingServer/PORTAINER_DEPLOYMENT.md
T
Keith SmithandClaude Sonnet 5 7e905a0566 Add Web Push notifications (PWA)
Wires up the previously-scaffolded VAPID/DeviceToken infrastructure end
to end: browser subscription flow on the Profile page's existing "Push
Notifications" toggle, a service worker push/notificationclick handler,
and server-side sending from the daily task digest. Also broadens that
digest's eligibility query so push-only users (email notifications off)
aren't silently skipped, and adds `generate_vapid_keys` since the pinned
py-vapid's own key generator is broken against current cryptography.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-04 22:30:56 -06:00

294 lines
8.0 KiB
Markdown

# 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.darksingularity.org/DarkSingularity/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.darksingularity.org/DarkSingularity/KeepItGoingServer.git
```
**Repository reference:** `refs/heads/main`
**Compose path:** `docker-compose.yml`
**Authentication:**
- If repository is private, enable authentication
- Username: your Gitea account username
- Password: a Gitea access token (recommended over your account password)
### Step 4: Configure Environment Variables
Scroll down to the **Environment variables** section and paste the following, replacing every `<...>` placeholder with the actual value from your password manager / secrets store (never commit real values to this file):
```env
# Django Core Settings
SECRET_KEY=<django-secret-key>
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=<db-password>
DB_ROOT_PASSWORD=<db-root-password>
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=<email-host-password>
DEFAULT_FROM_EMAIL=KeepItGoing <kig@keepitgoing.app>
SERVER_EMAIL=kig@keepitgoing.app
# Email Verification
EMAIL_VERIFICATION_TOKEN_EXPIRY_HOURS=24
# Web Push (generate with `python manage.py generate_vapid_keys`)
VAPID_PUBLIC_KEY=<vapid-public-key>
VAPID_PRIVATE_KEY=<vapid-private-key>
VAPID_ADMIN_EMAIL=<admin-contact-email>
# 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 the `DB_ROOT_PASSWORD` value from your Portainer stack environment variables
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)