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>
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
-
Build Frontend on Host
cd frontend npm ci npm run build # Creates frontend/dist/ -
Build Docker Image (Simple)
# Uses Dockerfile.prebuilt (Python only, no npm) docker compose -f docker-compose.prebuilt.yml build -
Start Services
docker compose -f docker-compose.prebuilt.yml up -d -
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)
Recommended Next Steps
- CI/CD Pipeline - Build images automatically, push to registry
- Pre-Built Images - Sites pull instead of building (2 min deploy)
- Backup Watcher Fix - Switch to Alpine base or pre-download restic
- TLS Certificates - Use proper certs from CA (not self-signed)
- 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 copiedstart-docker-quick.sh- Quick restart scriptDOCKER-PREBUILT-APPROACH.md- Documents workaroundPRODUCTION-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.