major-domo-v2/DOCKER.md
Cal Corum 5924249481 CLAUDE: Add comprehensive Docker deployment infrastructure
Implements production-ready Docker setup with multi-stage builds and
separate development/production configurations.

New Files:
- Dockerfile: Multi-stage build with Python 3.13
  * Builder stage: Compiles dependencies with build tools
  * Runtime stage: Minimal image (~150-200MB) with non-root user
  * Health checks and security hardening
- docker-compose.yml: Production config (pulls from Docker Hub)
  * Image: manticorum67/major-domo-discordapp:latest
  * Resource limits: 512MB RAM, 1 CPU
  * Volumes: /app/data (ro), /app/logs (rw)
- docker-compose.dev.yml: Development config (builds locally)
  * Higher resource limits: 1GB RAM, 2 CPU
  * DEBUG log level by default
- .dockerignore: Excludes unnecessary files from build context
- build-and-push.sh: Interactive build/push script for Docker Hub
- DOCKER.md: Comprehensive deployment guide (13K)
- BUILD_AND_PUSH.md: Docker Hub build/push guide (7.7K)

Configuration Updates:
- config.py: Updated sheets_credentials_path to /app/data location
- requirements.txt: Pinned all package versions for reproducibility
- .env.example: Added Docker-specific configuration

Key Features:
- Multi-stage build for optimized image size
- Non-root user (botuser, UID 1000) for security
- Separate dev/prod compose files
- Volume mounts for persistence (/app/data, /app/logs)
- Health checks and automatic restarts
- Resource limits and log rotation
- Docker Hub integration for production deployments

Docker Hub Repository: manticorum67/major-domo-discordapp

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-16 00:54:56 -05:00

12 KiB

Docker Deployment Guide

This guide covers deploying the Discord Bot v2.0 using Docker and Docker Compose.

Prerequisites

  • Docker 20.10+ installed
  • Docker Compose 2.0+ installed
  • Google Sheets service account credentials JSON file
  • Access to the database API (running on a separate host)

Deployment Modes

Uses docker-compose.yml - pulls pre-built image from Docker Hub

Development

Uses docker-compose.dev.yml - builds image locally from source


Quick Start (Production)

Deploy using pre-built image from Docker Hub:

1. Prepare Configuration

# Copy the example environment file
cp .env.example .env

# Edit .env with your actual values
nano .env

Required environment variables:

  • BOT_TOKEN - Your Discord bot token
  • API_TOKEN - Database API authentication token
  • DB_URL - Database API endpoint URL
  • GUILD_ID - Your Discord server ID

2. Prepare Data Directory

# Create data directory for Google Sheets credentials
mkdir -p data

# Copy your Google Sheets credentials file
cp /path/to/your/credentials.json data/major-domo-service-creds.json

# Set proper permissions (read-only)
chmod 444 data/major-domo-service-creds.json

3. Create Logs Directory

# Create logs directory (will be mounted as volume)
mkdir -p logs

4. Pull and Run

# Pull latest image from Docker Hub
docker-compose pull

# Start the bot
docker-compose up -d

# View logs
docker-compose logs -f discord-bot

Development Setup

Build and run locally with source code:

1. Complete steps 1-3 from Production setup above

2. Build and Run

# Build the Docker image locally
docker-compose -f docker-compose.dev.yml build

# Start the bot
docker-compose -f docker-compose.dev.yml up -d

# View logs
docker-compose -f docker-compose.dev.yml logs -f discord-bot

Docker Commands

Production Commands

# Pull latest image from Docker Hub
docker-compose pull

# Start in detached mode
docker-compose up -d

# Start in foreground (see logs)
docker-compose up

# Restart the bot
docker-compose restart discord-bot

# Stop the bot
docker-compose stop discord-bot

# Stop and remove container
docker-compose down

Development Commands

# Build the image locally
docker-compose -f docker-compose.dev.yml build

# Build without cache (force rebuild)
docker-compose -f docker-compose.dev.yml build --no-cache

# Start in detached mode
docker-compose -f docker-compose.dev.yml up -d

# Start and rebuild if needed
docker-compose -f docker-compose.dev.yml up -d --build

# Restart the bot
docker-compose -f docker-compose.dev.yml restart discord-bot

# Stop and remove
docker-compose -f docker-compose.dev.yml down

Monitoring Commands

# View logs (follow mode)
docker-compose logs -f discord-bot

# View last 100 lines of logs
docker-compose logs --tail=100 discord-bot

# Check container status
docker-compose ps

# Check resource usage
docker stats major-domo-discord-bot-v2

# Execute commands inside container
docker-compose exec discord-bot bash

# View bot process
docker-compose exec discord-bot ps aux

Maintenance Commands

# Pull latest code and restart
git pull
docker-compose up -d --build

# Clear logs
docker-compose exec discord-bot sh -c "rm -rf /logs/*.log"

# Restart after configuration changes
docker-compose down && docker-compose up -d

# View container health status
docker inspect --format='{{.State.Health.Status}}' major-domo-discord-bot-v2

Directory Structure

discord-app-v2/
├── Dockerfile                  # Multi-stage build configuration
├── docker-compose.yml          # Production: pulls from Docker Hub
├── docker-compose.dev.yml      # Development: builds locally
├── .dockerignore              # Files to exclude from image
├── .env                       # Environment configuration (not in git)
├── .env.example              # Environment template
├── DOCKER.md                 # This deployment guide
├── BUILD_AND_PUSH.md         # Guide for pushing to Docker Hub
├── data/                     # Google Sheets credentials (mounted volume)
│   └── major-domo-service-creds.json
├── logs/                     # Log files (mounted volume)
│   ├── discord_bot_v2.log
│   └── discord_bot_v2.json
└── ... (application code)

Docker Hub Repository

Repository: manticorum67/major-domo-discordapp URL: https://hub.docker.com/r/manticorum67/major-domo-discordapp

Production deployments pull from this repository. See BUILD_AND_PUSH.md for instructions on building and pushing new versions.

Multi-Stage Build

The Dockerfile uses a multi-stage build for optimization:

Stage 1: Builder

  • Based on python:3.13-slim
  • Installs build dependencies (gcc, g++)
  • Compiles Python packages with C extensions
  • Creates .local directory with all dependencies

Stage 2: Runtime

  • Based on python:3.13-slim
  • Only includes runtime dependencies
  • Copies compiled packages from builder
  • Runs as non-root user (botuser)
  • Final image size: ~150-200MB (vs ~500MB+ single-stage)

Security Features

Non-Root User

The bot runs as botuser (UID 1000) with restricted permissions:

RUN groupadd -r botuser && \
    useradd -r -g botuser -u 1000 -m -s /bin/bash botuser
USER botuser

Read-Only Credentials

Mount credentials as read-only:

volumes:
  - ./data:/data:ro  # ro = read-only

Resource Limits

Default resource limits in docker-compose.yml:

  • CPU: 1.0 cores max, 0.25 cores reserved
  • Memory: 512MB max, 256MB reserved

Adjust based on your server capacity:

deploy:
  resources:
    limits:
      cpus: '2.0'      # Increase for heavy workloads
      memory: 1G       # Increase if needed

Volume Mounts

Data Volume (Read-Only)

Contains Google Sheets credentials:

volumes:
  - ${SHEETS_CREDENTIALS_HOST_PATH:-./data}:/data:ro

Logs Volume (Read-Write)

Persistent log storage:

volumes:
  - ${LOGS_HOST_PATH:-./logs}:/logs:rw

Development Mode

Mount source code for live development:

volumes:
  - .:/app:ro  # Uncomment in docker-compose.yml

Health Checks

The bot includes a health check that runs every 60 seconds:

HEALTHCHECK --interval=60s --timeout=10s --start-period=30s --retries=3 \
    CMD python -c "import sys; sys.exit(0)" || exit 1

Check health status:

docker inspect --format='{{.State.Health.Status}}' major-domo-discord-bot-v2

Logging

Container Logs

Docker captures stdout/stderr:

docker-compose logs -f discord-bot

Application Logs

Persistent logs in mounted volume:

  • /logs/discord_bot_v2.log - Human-readable logs
  • /logs/discord_bot_v2.json - Structured JSON logs

Log Rotation

Docker manages log rotation:

logging:
  driver: "json-file"
  options:
    max-size: "10m"   # Max size per file
    max-file: "3"     # Keep 3 files

Networking

The bot connects outbound to:

  • Discord API (discord.com)
  • Database API (configured via DB_URL)
  • Google Sheets API (sheets.googleapis.com)

No inbound ports are exposed (bot initiates all connections).

Custom Network

The compose file creates a bridge network:

networks:
  major-domo-network:
    driver: bridge

Troubleshooting

Bot Won't Start

  1. Check logs:

    docker-compose logs discord-bot
    
  2. Verify environment variables:

    docker-compose exec discord-bot env | grep BOT_TOKEN
    
  3. Check credentials file:

    docker-compose exec discord-bot ls -la /data/
    

Permission Errors

If you see permission errors accessing /data or /logs:

# Fix data directory permissions
chmod -R 755 data/
chmod 444 data/major-domo-service-creds.json

# Fix logs directory permissions
chmod -R 755 logs/

Database Connection Issues

Test database connectivity:

docker-compose exec discord-bot python -c "
import aiohttp
import asyncio
import os

async def test():
    url = os.getenv('DB_URL')
    token = os.getenv('API_TOKEN')
    async with aiohttp.ClientSession() as session:
        async with session.get(f'{url}/health',
                               headers={'Authorization': f'Bearer {token}'}) as resp:
            print(f'Status: {resp.status}')
            print(await resp.text())

asyncio.run(test())
"

High Memory Usage

If the bot uses too much memory:

  1. Check current usage:

    docker stats major-domo-discord-bot-v2
    
  2. Increase memory limit:

    # In docker-compose.yml
    deploy:
      resources:
        limits:
          memory: 1G  # Increase from 512M
    
  3. Restart with new limits:

    docker-compose up -d
    

Container Keeps Restarting

Check exit code and error:

docker-compose ps
docker logs major-domo-discord-bot-v2 --tail=50

Common issues:

  • Invalid BOT_TOKEN - Check .env file
  • Missing credentials - Check /data mount
  • Database unreachable - Check DB_URL

Production Deployment

Best Practices

  1. Use specific image tags:

    docker tag major-domo/discord-bot-v2:latest major-domo/discord-bot-v2:v2.0.0
    
  2. Enable auto-restart:

    restart: unless-stopped  # Already set in compose file
    
  3. Set production environment:

    ENVIRONMENT=production
    LOG_LEVEL=INFO
    
  4. Monitor resource usage:

    docker stats major-domo-discord-bot-v2
    
  5. Regular updates:

    git pull
    docker-compose build --no-cache
    docker-compose up -d
    

Backup Strategy

Backup critical data:

# Backup logs
tar -czf logs-backup-$(date +%Y%m%d).tar.gz logs/

# Backup configuration
cp .env .env.backup

# Backup credentials
cp data/major-domo-service-creds.json data/creds.backup.json

Updates and Maintenance

Update Bot Code (Production)

# 1. Pull latest image from Docker Hub
docker-compose pull

# 2. Restart with new image
docker-compose up -d

# 3. Verify it's running
docker-compose logs -f discord-bot

Update Bot Code (Development)

# 1. Pull latest code
git pull

# 2. Rebuild image
docker-compose -f docker-compose.dev.yml build

# 3. Restart with new image
docker-compose -f docker-compose.dev.yml up -d

# 4. Verify it's running
docker-compose -f docker-compose.dev.yml logs -f discord-bot

Update Dependencies

# 1. Update requirements.txt locally
pip install -U discord.py pydantic aiohttp
pip freeze > requirements.txt

# 2. Rebuild image with new dependencies
docker-compose build --no-cache

# 3. Restart
docker-compose up -d

Database Migration

If the database API is updated:

# 1. Update DB_URL in .env if needed
nano .env

# 2. Restart bot to pick up new configuration
docker-compose restart discord-bot

# 3. Test connectivity
docker-compose logs -f discord-bot

File Comparison: Production vs Development

docker-compose.yml (Production)

  • Pulls pre-built image from Docker Hub: manticorum67/major-domo-discordapp:latest
  • Environment: production
  • Log level: INFO (default)
  • Resource limits: 512MB RAM, 1 CPU
  • No source code mounting

docker-compose.dev.yml (Development)

  • Builds image locally from Dockerfile
  • Environment: development
  • Log level: DEBUG (default)
  • Resource limits: 1GB RAM, 2 CPU (more generous)
  • Optional source code mounting for live updates

When to Use Each

Use Production (docker-compose.yml):

  • Production servers
  • Staging environments
  • Any deployment not modifying code
  • Faster deployment (no build step)

Use Development (docker-compose.dev.yml):

  • Local development
  • Testing code changes
  • Building new features
  • Debugging issues

Additional Resources

Support

For issues or questions:

  1. Check logs: docker-compose logs discord-bot
  2. Review bot documentation in CLAUDE.md and command READMEs
  3. Check health status: docker inspect major-domo-discord-bot-v2