Files
shopdb-flask/.claude/archived/DOCKER-DEPLOYMENT-COMPLETE.md
Proudlock bd48814021 Reorganize repository structure and clean up documentation
Clean up and organize the flask-shopdb repository for better
maintainability and discoverability:

## Changes

- Update .gitignore for build artifacts (publish/, data/, 122M total)
- Reorganize .claude/ into 6 subdirectories with README navigation
- Consolidate overlapping MCP setup guides into MCP-QUICK-START.md
- Move deployment docs from root to docs/deployment/
- Archive dated status reports to .claude/archived/
- Delete temporary files (logs, backups, empty reports, ~50K)

## New Structure

.claude/ organized into:
- setup/ - MCP, VM, Hyper-V, GitHub setup guides + scripts (17 files)
- plans/ - Feature plans and protocols (5 files)
- maintenance/ - Deployment checklists and reports (4 files)
- archived/ - Historical documentation (9 files)
- skills/ - Claude Code automation (5 files)
- workflows/ - Security audit workflow (1 file)

docs/deployment/ created with 6 deployment guides:
- LOCAL-DEV-SETUP.md, DOCKER-SETUP.md, DOCKER-PREBUILT-APPROACH.md
- PRODUCTION-READINESS.md, DEPLOY-TO-VM.md, README.md

Root directory cleaned to essential docs only:
- CLAUDE.md, README.md, CONTRIBUTING.md, CHANGELOG.md

Benefits:
- Clear navigation via README.md in each subdirectory
- No duplicate/overlapping documentation
- Large artifacts properly gitignored (won't bloat repository)
- Historical context preserved in archived/

See .claude/CLEANUP-SUMMARY.md for complete details.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-09-11 15:45:05 -04:00

6.7 KiB

Docker Deployment - Complete and Working

Date: 2026-09-07
Branch: wj (post-wilm merge)
Status: [OK] Core system operational, backup watcher pending

What's Running

CONTAINER              STATUS           PORT
flask-shopdb-db-1      Up (healthy)     3306/tcp (internal)
flask-shopdb-api-1     Up               https://localhost:5001

Gunicorn Workers: 4 workers with gevent (PIDs 74-77)
Plugins Enabled: 12 of 17 installed
Database: MySQL 8.4 with all migrations applied

Access

URL: https://localhost:5001
Expected: Browser warning for self-signed certificate (click through)
Login: admin / (needs password reset - see below)

How to Use

Start Stack

docker compose -f docker-compose.prebuilt.yml up -d

Stop Stack

docker compose -f docker-compose.prebuilt.yml down

View Logs

docker logs -f flask-shopdb-api-1
docker logs flask-shopdb-db-1

Reset Admin Password

# Generate hash
docker exec flask-shopdb-api-1 python -c \
  "from werkzeug.security import generate_password_hash; print(generate_password_hash('your-password'))"

# Update database (replace HASH with output above)
docker exec flask-shopdb-db-1 mysql -uroot -p$MYSQL_ROOT_PASSWORD shopdb_flask -e \
  "UPDATE users SET passwordhash='HASH', failedlogins=0, lockeduntil=NULL WHERE username='admin';"

Quick reset to password "admin":

docker exec flask-shopdb-db-1 mysql -uroot -proot-dev-password-not-for-production shopdb_flask -e \
  "UPDATE users SET 
    passwordhash='scrypt:32768:8:1\$B4LhpPrM6qxijInK\$b99b47a0bb5fd45761a1823f401f70a3ceccf71a5d38dc433378aa07426ef8eaf7e679ff3dd7b0ce9772600f83368ac642e9419b9beaa49f87483318bae34547',
    failedlogins=0, lockeduntil=NULL 
   WHERE username='admin';"

Rebuild After Code Changes

# Rebuild frontend (if frontend code changed)
cd frontend
npm run build
cd ..

# Rebuild Docker image
docker compose -f docker-compose.prebuilt.yml build api

# Restart
docker compose -f docker-compose.prebuilt.yml up -d

Run Database Migrations

docker exec flask-shopdb-api-1 flask db upgrade

Plugin Management

# List plugins
docker exec flask-shopdb-api-1 flask plugin list

# Enable plugin
docker exec flask-shopdb-api-1 flask plugin enable PLUGIN_NAME

# Disable plugin
docker exec flask-shopdb-api-1 flask plugin disable PLUGIN_NAME

Build Process Used

Why Pre-Built Frontend?

Problem: Zscaler corporate proxy causes npm to fail inside Docker builds

Solution: Build frontend on host, copy into Docker image

Build Steps Taken

  1. Build Frontend on Host

    cd frontend
    npm ci
    npm run build
    # Creates frontend/dist/
    
  2. Build Docker Image (Simple)

    # Uses Dockerfile.prebuilt (Python only, no npm)
    docker compose -f docker-compose.prebuilt.yml build
    
  3. Start Services

    docker compose -f docker-compose.prebuilt.yml up -d
    
  4. Auto-Bootstrap

    • Container entrypoint runs migrations
    • Detects first deployment (no instance/plugins.json)
    • Auto-installs all 17 plugins (disabled by default)
    • Starts gunicorn

Architecture

Volumes

  • flask-shopdb_db_data - MySQL database (persistent)
  • flask-shopdb_instance_data - Plugin state, uploads, branding (persistent)

Networks

  • flask-shopdb_default - Internal bridge network

Image

  • Built: 2026-09-07 00:26:27 EDT
  • Size: 914MB
  • Base: python:3.14-slim
  • Frontend: Pre-built Vue 3 SPA (from host)

What's Not Working Yet

Backup Watcher Service

Status: [FAIL] Build failed
Reason: Oracle Linux base image can't download packages due to SSL cert issues with Zscaler
Impact: Can't auto-execute backups on schedule (manual backups still work via one-shot container)

Error:

Cannot download repomd.xml: Curl error (60): SSL peer certificate or SSH remote key was not OK

Workaround Attempted:

  • Copied Zscaler cert to scripts/backup/zscaler-root-ca.pem
  • Dockerfile.backup copies cert and runs update-ca-trust
  • Still fails because microdnf runs BEFORE cert is trusted

Fix Needed:

  • Pre-download restic binary and bake into image OR
  • Use different base image (Alpine/Debian instead of Oracle Linux) OR
  • Skip backup watcher entirely, use cron on host to trigger one-shot backup container

Production Readiness

Core Application: [OK] Production ready
Deployment Process: [WARN] Requires npm on host + Docker build
Backup System: [FAIL] Not complete (watcher service build fails)

  1. CI/CD Pipeline - Build images automatically, push to registry
  2. Pre-Built Images - Sites pull instead of building (2 min deploy)
  3. Backup Watcher Fix - Switch to Alpine base or pre-download restic
  4. TLS Certificates - Use proper certs from CA (not self-signed)
  5. Secrets Management - Externalize passwords (.env with strong values)

Files Created

  • Dockerfile.prebuilt - Simplified Docker build (no npm)
  • docker-compose.prebuilt.yml - Docker Compose for pre-built approach
  • .dockerignore.prebuilt - Allows frontend/dist to be copied
  • start-docker-quick.sh - Quick restart script
  • DOCKER-PREBUILT-APPROACH.md - Documents workaround
  • PRODUCTION-READINESS.md - Honest assessment

Comparison to Previous Attempts

Approach Result Time Issue
Multi-stage Dockerfile [FAIL] Failed 15+ min npm fails with Zscaler
Pre-built frontend [OK] Success 3 min Works!
Backup containers [FAIL] Failed N/A Oracle Linux SSL issues

Verification

# Test frontend
curl -k https://localhost:5001/
# Should return: <!DOCTYPE html>

# Test API
curl -k https://localhost:5001/api/settings
# Should return: {"data":[...]}

# Test database
docker exec flask-shopdb-db-1 mysql -uroot -p$MYSQL_ROOT_PASSWORD \
  -e "SELECT COUNT(*) FROM shopdb_flask.users;"
# Should return: count of users

# Check workers
docker logs flask-shopdb-api-1 2>&1 | grep "Booting worker"
# Should show: 4 workers with PIDs

# Check plugins
docker exec flask-shopdb-api-1 flask plugin list | grep Enabled | wc -l
# Should return: 12

Summary

ShopDB Docker deployment is operational for core functionality:

  • [OK] Database running
  • [OK] API serving requests
  • [OK] Frontend built and accessible
  • [OK] Plugins installed and working
  • [OK] HTTPS configured
  • [WARN] Backup watcher needs work (but manual backups functional)

The pre-built frontend approach successfully bypasses Zscaler corporate proxy issues. Build time is 2-3 minutes (vs 15+ for failed multi-stage approach).

For production deployment, recommend setting up CI/CD to build images automatically and push to registry so sites can pull pre-built images instead of building locally.