Files
tfm_ainventory/.planning/phases/06-deployment-scale/PLAN-01-DOCKER-DEPLOYMENT.md
Daniel Bedeleanu 4b7621fcd1 feat(6): phase 6 planning complete - deployment, scale testing, backup/restore
Phase 6 comprehensive plans ready for execution:

Plan 1: Docker Containerization & Deployment Automation (6 tasks)
- Enhance backend/frontend Dockerfiles with health checks
- Create deploy.sh for single-command deployment
- Environment automation and validation
- Quick start guide and troubleshooting docs

Plan 2: Scale Testing & Performance Optimization (6 tasks)
- Locust-based load testing framework (5 concurrent users)
- Database seeding (10K items with realistic data)
- Metrics collection (CPU, memory, response times)
- Performance baseline establishment and SLO documentation
- Health check monitoring automation
- Load test execution guide

Plan 3: Backup/Restore & Operational Runbook (7 tasks)
- Automated backup script (daily/weekly with retention)
- Restore validation and disaster recovery procedures
- Cron job configuration for scheduled backups
- Comprehensive operational runbook (deployment, scaling, troubleshooting)
- Health monitoring checklist (daily/weekly/monthly)
- Disaster recovery plan (3+ scenarios, <10min RTO)
- Operations documentation index and integration guide

Context document summarizes:
- Phase goal: Production-ready multi-site deployment
- Key decisions: Docker strategy, automation scope, scale limits
- Upstream dependencies: Phase 5 complete
- Success criteria: Single-command deploy, 10K items + 5 users <2s latency
- Backup strategy: Daily incremental, weekly full (30/90 day retention)

All plans include:
- Detailed task breakdowns (5-7 per plan)
- Acceptance criteria and testing procedures
- Dependencies and blockers
- Effort estimates and risk assessment
- Success metrics and monitoring guidance

Ready for execution phase (estimated 4-5 weeks total).
2026-04-22 18:13:35 +03:00

14 KiB

Phase 6, Plan 1: Docker Containerization & Deployment Automation


plan: 06-deployment-scale/01-docker-deployment
feature: Docker containerization, automated deployment, environment automation
status: Ready for execution
estimated_tasks: 6
total_lines: ~450 (Dockerfile updates ~200, deploy.sh ~180, compose enhancements ~70)


Overview

This plan hardens the existing Docker setup and creates a single-command deployment script. The system already has Dockerfiles and docker-compose.yml; this plan:

  1. Enhances Dockerfiles — Add health checks, optimize layers, improve logging
  2. Creates deploy.sh — Automated deployment with validation, initialization, health checks
  3. Environment automation — Template generation, pre-flight validation
  4. Docker Compose improvements — Health checks, volume management, dependency ordering
  5. Documentation — Quick start guide for operators

Success: ./deploy.sh deploys full stack on fresh Ubuntu 22.04+ in <5 minutes with zero manual steps.


Tasks

Task 1: Enhance Backend Dockerfile

File: backend/Dockerfile
Status: Ready
Description: Add health checks, optimize build layers, improve production readiness

Changes:

  • Add HEALTHCHECK instruction (GET /health endpoint)
  • Optimize RUN commands (reduce layers)
  • Add metadata labels (version, maintainer, build-date)
  • Ensure logs go to stdout for Docker log capture
  • Pin Python version to 3.12

Acceptance Criteria:

  • Dockerfile builds without warnings
  • Health check responds correctly
  • Image size <500MB
  • Container logs visible in docker logs
  • All tests still pass

Testing:

docker build -t inventory-backend:test backend/
docker run --rm -p 8000:8000 inventory-backend:test
curl http://localhost:8000/health  # Should return 200

Task 2: Enhance Frontend Dockerfile

File: frontend/Dockerfile
Status: Ready
Description: Add health checks, optimize Next.js production build, logging

Changes:

  • Add HEALTHCHECK instruction (curl to /health or equivalent)
  • Multi-stage build (builder + runtime) to reduce image size
  • Ensure Next.js logs to stdout
  • Optimize node_modules caching layer
  • Pin Node.js version to LTS

Acceptance Criteria:

  • Dockerfile builds without warnings
  • Health check responds correctly
  • Image size <300MB
  • Next.js startup logs appear in docker logs

Testing:

docker build -t inventory-frontend:test frontend/
docker run --rm -p 3000:3000 inventory-frontend:test
curl http://localhost:3000/_next/health  # Or custom endpoint

Task 3: Update docker-compose.yml

File: docker-compose.yml
Status: Ready
Description: Add health checks, improve service dependencies, enhance resilience

Changes:

  • Add healthcheck to all three services (backend, frontend, proxy)
  • Update depends_on to use health checks (wait_for: service_healthy)
  • Add resource limits (memory, CPU)
  • Improve volume definitions (use named volumes for persistence)
  • Add restart policies (restart: unless-stopped already present; verify)
  • Document all environment variables inline

Acceptance Criteria:

  • docker-compose up starts all services in order
  • Health checks report healthy status
  • Services restart on failure
  • Logs from all services visible via docker-compose logs

Testing:

docker-compose up -d
docker-compose ps  # Should show all healthy
docker-compose logs -f
docker-compose down

Task 4: Create deploy.sh (Automated Deployment)

File: deploy.sh (new, executable)
Status: Ready
Description: Single-command deployment with initialization, validation, health checks

Content (~180 lines):

#!/bin/bash
set -euo pipefail

# Phase 6, Plan 1, Task 4: Automated Deployment Script
# Usage: ./deploy.sh [production|staging|development] [--rebuild]

DEPLOYMENT_ENV="${1:-production}"
REBUILD="${2:---no-rebuild}"

# Color output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; exit 1; }

# 1. Pre-flight checks
log_info "Running pre-flight checks..."
command -v docker &> /dev/null || log_error "Docker not installed"
command -v docker-compose &> /dev/null || log_error "Docker Compose not installed"
[[ -f "docker-compose.yml" ]] || log_error "docker-compose.yml not found"
[[ -f "inventory.env" ]] || log_error "inventory.env not found; copy from template"

# 2. Validate environment file
log_info "Validating inventory.env..."
source inventory.env
[[ -z "${BACKEND_PORT:-}" ]] && log_warn "BACKEND_PORT not set; using default 8000"
[[ -z "${FRONTEND_PORT:-}" ]] && log_warn "FRONTEND_PORT not set; using default 3000"

# 3. Check port availability
log_info "Checking port availability..."
for port in ${BACKEND_PORT:-8000} ${FRONTEND_PORT:-3000} ${BACKEND_SSL_PORT:-8918} ${FRONTEND_SSL_PORT:-8919}; do
  netstat -tuln 2>/dev/null | grep -q ":$port " && log_error "Port $port already in use"
done

# 4. Build or pull images
log_info "Building Docker images (${REBUILD})..."
if [[ "$REBUILD" == "--rebuild" ]]; then
  docker-compose build --no-cache
else
  docker-compose build
fi

# 5. Create data directories
log_info "Creating data directories..."
mkdir -p data logs config
[[ -d "data/caddy_data" ]] || mkdir -p data/caddy_data
[[ -d "data/caddy_config" ]] || mkdir -p data/caddy_config

# 6. Initialize database (if not exists)
if [[ ! -f "data/inventory.db" ]]; then
  log_info "Initializing database..."
  # This will be handled by backend startup; just log the action
  log_info "Database will be initialized on first backend startup"
fi

# 7. Start services
log_info "Starting services..."
docker-compose up -d

# 8. Wait for health checks
log_info "Waiting for services to be healthy..."
max_attempts=30
attempt=0
while [[ $attempt -lt $max_attempts ]]; do
  healthy=$(docker-compose ps | grep -c "healthy" || echo "0")
  if [[ $healthy -eq 3 ]]; then
    log_info "All services healthy!"
    break
  fi
  attempt=$((attempt + 1))
  sleep 2
done

if [[ $attempt -eq $max_attempts ]]; then
  log_warn "Services did not become healthy within 60 seconds"
  docker-compose logs
  exit 1
fi

# 9. Verify connectivity
log_info "Verifying connectivity..."
if curl -sf "http://localhost:${BACKEND_PORT:-8000}/health" &> /dev/null; then
  log_info "Backend healthy: http://localhost:${BACKEND_PORT:-8000}"
else
  log_error "Backend health check failed"
fi

# 10. Display summary
log_info "Deployment successful!"
echo ""
echo "Access points:"
echo "  Frontend: http://localhost:${FRONTEND_PORT:-3000}"
echo "  Backend API: http://localhost:${BACKEND_PORT:-8000}"
echo "  Secure (HTTPS): https://localhost:${FRONTEND_SSL_PORT:-8919}"
echo ""
echo "View logs: docker-compose logs -f"
echo "Stop services: docker-compose down"

Acceptance Criteria:

  • Script exits with error on missing Docker/Compose
  • Pre-flight checks validate all prerequisites
  • Images build successfully
  • Services start and health checks pass
  • Displays access URLs at end
  • Exit code 0 on success, non-zero on failure

Testing:

chmod +x deploy.sh
./deploy.sh production
# Verify all services running and accessible
./deploy.sh staging --rebuild
# Clean up
docker-compose down

Task 5: Create Environment Template & Validation

Files:

  • inventory.env.template (new)
  • .env.validation.sh (new, 80 lines)

Status: Ready
Description: Provide environment template and validation script to prevent misconfiguration

inventory.env.template:

# TFM aInventory Deployment Configuration
# Copy to inventory.env and customize for your deployment

# Service Ports
BACKEND_PORT=8000
FRONTEND_PORT=3000
BACKEND_SSL_PORT=8918
FRONTEND_SSL_PORT=8919

# Security
JWT_SECRET_KEY=change_me_in_production_use_openssl_rand_hex_32

# AI Configuration (Optional, uses defaults if not set)
AI_PROVIDER=gemini
GEMINI_API_KEY=
CLAUDE_API_KEY=

# LDAP Configuration (Optional, uses local auth if not set)
LDAP_SERVER=
LDAP_PORT=389
LDAP_BASE_DN=
LDAP_USE_SSL=false

# Database
DATA_DIR=/app/data
DB_PATH=/app/data/inventory.db

# Logging
LOGS_DIR=/app/logs
LOG_LEVEL=INFO

# Network (CORS)
ALLOWED_ORIGINS=http://localhost:3000,https://localhost:8919
EXTRA_ALLOWED_ORIGINS=

# Deployment metadata
DEPLOYMENT_NAME=production
DEPLOYMENT_REGION=default

.env.validation.sh:

#!/bin/bash
# Validate inventory.env before deployment

set -euo pipefail

log_error() { echo "[ERROR] $1" >&2; exit 1; }
log_warn() { echo "[WARN] $1" >&2; }

[[ -f "inventory.env" ]] || log_error "inventory.env not found"
source inventory.env

# Validate required variables
[[ -z "${BACKEND_PORT:-}" ]] && log_error "BACKEND_PORT not set"
[[ -z "${FRONTEND_PORT:-}" ]] && log_error "FRONTEND_PORT not set"
[[ "$BACKEND_PORT" =~ ^[0-9]+$ ]] || log_error "BACKEND_PORT must be numeric"
[[ "$FRONTEND_PORT" =~ ^[0-9]+$ ]] || log_error "FRONTEND_PORT must be numeric"

# Warn on defaults
if [[ "${JWT_SECRET_KEY:-}" == "change_me_in_production_use_openssl_rand_hex_32" ]]; then
  log_warn "JWT_SECRET_KEY is using default value; regenerate for production"
fi

echo "[OK] inventory.env validation passed"

Acceptance Criteria:

  • Template covers all deployment scenarios (dev/staging/prod)
  • Validation script checks all critical variables
  • Clear comments explaining each setting
  • Example values provided (not actual secrets)

Task 6: Create Quick Start Guide & Troubleshooting

File: docs/DEPLOYMENT_QUICKSTART.md (new, ~150 lines)
Status: Ready
Description: Operator-friendly deployment guide, no domain knowledge required

Content:

# Deployment Quick Start Guide

## Prerequisites
- Ubuntu 22.04 LTS or similar Linux distro
- Docker 24.0+
- Docker Compose 2.0+
- 2GB RAM, 10GB free disk

## Installation (5 minutes)

### 1. Prepare Environment
\`\`\`bash
git clone <repo> tfm-inventory
cd tfm-inventory
cp inventory.env.template inventory.env
# Edit inventory.env with your deployment settings
\`\`\`

### 2. Generate Secure Secret
\`\`\`bash
openssl rand -hex 32 > /tmp/jwt_secret
# Copy output into inventory.env JWT_SECRET_KEY
\`\`\`

### 3. Deploy
\`\`\`bash
chmod +x deploy.sh
./deploy.sh production
\`\`\`

### 4. Verify Access
- Frontend: http://localhost:3000
- Backend: http://localhost:8000
- API Docs: http://localhost:8000/docs

## Scaling (Adding Users)

System tested and stable with 5 concurrent users. For more:
1. Increase BACKEND_PORT pool (run multiple instances behind load balancer)
2. Monitor logs for errors: `docker-compose logs -f backend`
3. Check database locks: `docker-compose exec backend python -c "import sqlite3; db=sqlite3.connect('/app/data/inventory.db'); print(db.execute('PRAGMA database_list').fetchall())"`

## Troubleshooting

| Issue | Solution |
|-------|----------|
| Port already in use | Change BACKEND_PORT/FRONTEND_PORT in inventory.env |
| Health check failing | Wait 30s, then: `docker-compose logs` to check service logs |
| Database locked | Restart backend: `docker-compose restart backend` |
| HTTPS certificate warning | First-time is normal; trust the certificate in browser |

## Backup & Restore
\`\`\`bash
# Automatic daily backups (see BACKUP_RUNBOOK.md)
./backup.sh daily
./restore.sh data/backups/inventory-2026-04-22.tar.gz
\`\`\`

## Support
- Logs: `docker-compose logs -f`
- Health status: `docker-compose ps`
- Stop all: `docker-compose down`
- Full reset: `docker-compose down -v` (⚠️ deletes data)

Acceptance Criteria:

  • Guide is readable by non-technical ops teams
  • All 5 steps complete in <5 minutes
  • Troubleshooting covers common issues
  • Links to related docs (backup, scaling, health monitoring)

Dependencies

Upstream:

  • Phase 5 complete (all features implemented, tests passing)
  • Existing Dockerfiles and docker-compose.yml

Cross-Plan:

  • Plan 2 (Scale Testing) uses deploy.sh from this plan
  • Plan 3 (Backup/Restore) integrates with deployment structure

Blocked By: None


Testing Strategy

Unit Testing (Standalone)

# Each component can be tested independently
docker build -t inventory-backend:test backend/
docker build -t inventory-frontend:test frontend/
docker run --rm inventory-backend:test pytest backend/tests/  # Verify tests still pass

Integration Testing

# Deploy stack
./deploy.sh production --rebuild
# Verify all services healthy
docker-compose ps | grep healthy
# Run smoke tests
curl http://localhost:8000/health
curl http://localhost:3000/
# Verify data persistence
# (detailed in Plan 3)

Deployment Validation

# On fresh VM with only Docker installed
git clone <repo>
cd tfm-inventory
./deploy.sh production
# Should complete without errors

Success Metrics

  • ./deploy.sh completes in <5 minutes
  • Zero manual intervention required
  • All services report healthy
  • Backend API responds at /health
  • Frontend loads in browser
  • Logs accessible via docker-compose logs
  • Environment validation prevents misconfiguration

Notes

  • Existing docker-compose.yml already has 3 services; we enhance, not replace
  • Health checks will help automation tools (Kubernetes, Docker Swarm) manage restarts
  • Pre-flight checks prevent common pitfalls (port conflicts, missing files)
  • Logging to stdout ensures compatibility with container log aggregation

Effort Estimate: 16 hours (2 days)
Dependencies: None (Phase 5 complete assumed)
Risk: Low (mostly additive enhancements to existing Dockerfiles)


Last updated: 2026-04-22 (Planning Phase)