diff --git a/demo/.proselintrc b/demo/.proselintrc new file mode 100644 index 0000000..ada0932 --- /dev/null +++ b/demo/.proselintrc @@ -0,0 +1,6 @@ +{ + "flags": [ + "typography.symbols.curly_quotes", + "leonard.exclamation.30ppm" + ] +} \ No newline at end of file diff --git a/demo/AGENTS.md b/demo/AGENTS.md new file mode 100644 index 0000000..96c063c --- /dev/null +++ b/demo/AGENTS.md @@ -0,0 +1,384 @@ +# TSYS Developer Support Stack - Development Guidelines + +## ๐ŸŽฏ Development Principles + +### Demo-First Architecture +- **Demo-Only Configuration**: All services configured for demonstration purposes only +- **No Persistent Data**: Zero data persistence between demo sessions +- **Dynamic User Handling**: Automatic UID/GID detection and application +- **Security-First**: Docker socket proxy for all container operations +- **Minimal Bind Mounts**: Prefer Docker volumes over host bind mounts. Use host bind mounts only for minimal bootstrap purposes of configuration data that needs to be persistent. +- **Consistent Naming**: `tsysdevstack-supportstack-demo-` prefix everywhere including in the docker-compose file for the service names. +- **One-Command Deployment**: Single script deployment with full validation + +### Dynamic Environment Strategy +- **User Detection**: Automatic current user and group ID detection +- **Docker Group Handling**: Dynamic docker group ID resolution +- **Variable-Driven Configuration**: All settings via environment variables +- **Template-Based Compose**: Generate docker-compose.yml from templates +- **Environment Isolation**: Separate demo.env for all configuration + +### FOSS Only Policy +- Exclusively use free/libre/open source software +- Verify license compatibility +- Prefer official Docker images +- Document any proprietary dependencies + +### Inner Loop Focus +- Support daily development workflows +- Avoid project-specific dependencies +- Prioritize developer productivity +- Maintain workstation-local deployment + +### Code Organization Policy +- **Mandatory Code Subdirectory**: ALL created files, configurations, scripts, and code MUST be placed in the `code/` subdirectory +- **No Root-Level Code**: Absolutely NO code files shall be created at the project root level +- **Structured Organization**: All implementation artifacts belong under `code/` with proper subdirectory organization + +### System Interference Policy +- **NEVER interfere with existing processes**: Do not kill, stop, or modify any running processes without explicit permission +- **Check before acting**: Always verify what processes/screen sessions are running before taking any action +- **Use unique identifiers**: Create uniquely named sessions/processes to avoid conflicts +- **Ask first**: Always request permission before touching any existing work on the system +- **Respect concurrent work**: Other users/processes may be running - do not assume exclusive access + +--- + +## ๐Ÿ›ก๏ธ Quality Assurance Standards + +### Mandatory Tool Validation +- **yamllint**: ALL YAML files MUST pass yamllint validation before commit +- **shellcheck**: ALL shell scripts MUST pass shellcheck validation before commit +- **hadolint**: ALL Dockerfiles MUST pass hadolint validation before commit +- **Pre-commit Hooks**: Automated validation on every commit attempt + +### Zero-Tolerance Policy +- **No YAML syntax errors**: Prevents Docker Compose failures +- **No shell script errors**: Prevents deployment script failures +- **No Docker image issues**: Prevents container startup failures +- **No port conflicts**: Prevents service accessibility issues +- **No permission problems**: Prevents file ownership issues + +### Proactive Validation Checklist +Before ANY file is created or modified: +1. โœ… YAML syntax validated with yamllint +2. โœ… Shell script validated with shellcheck +3. โœ… Environment variables verified +4. โœ… Port availability confirmed +5. โœ… Docker image existence verified +6. โœ… Service dependencies validated +7. โœ… Health check endpoints confirmed +8. โœ… Resource requirements assessed + +--- + +## ๐Ÿ—๏ธ Architecture Guidelines + +### Service Categories +- **Infrastructure Services**: Core platform services +- **Monitoring & Observability**: Metrics and visualization +- **Documentation & Diagramming**: Knowledge management +- **Developer Tools**: Productivity enhancers + +### Design Patterns +- **Service Discovery**: Automatic via Homepage dashboard +- **Health Checks**: Comprehensive for all services +- **Network Isolation**: Docker network per stack +- **Resource Limits**: Memory and CPU constraints + +--- + +## ๐Ÿ”ง Technical Standards + +### Docker Configuration Standards + +#### Demo Service Template +```yaml +# Standard service template (docker-compose.yml.template) +services: + service-name: + image: official/image:tag + user: "${UID}:${GID}" + container_name: "${COMPOSE_PROJECT_NAME}-service-name" + restart: unless-stopped + networks: + - ${COMPOSE_NETWORK_NAME} + volumes: + - "${COMPOSE_PROJECT_NAME}_service_data:/path" + environment: + - PUID=${UID} + - PGID=${GID} + labels: + homepage.group: "Group Name" + homepage.name: "Display Name" + homepage.icon: "icon-name" + homepage.href: "http://localhost:${SERVICE_PORT}" + homepage.description: "Brief description" +``` + +#### Dynamic Variable Requirements +- **UID/GID**: Current user and group detection +- **DOCKER_GID**: Docker group ID for socket access +- **COMPOSE_PROJECT_NAME**: `tsysdevstack-supportstack-demo` +- **COMPOSE_NETWORK_NAME**: `tsysdevstack-supportstack-demo-network` +- **Service Ports**: All configurable via environment variables + +### Port Assignment Strategy +- Range: 4000-4099 +- Groups: Sequential allocation +- Document in README.md port table +- Avoid conflicts with host services + +### Network Configuration +- Network name: `tsysdevstack_supportstack-demo` +- IP binding: `192.168.3.6:{port}` where applicable +- Inter-service communication via container names +- Only necessary ports exposed to host + +--- + +## ๐Ÿ“‹ Quality Assurance + +### Testing Requirements +- Automated health check validation +- Port accessibility verification +- Service discovery functionality +- Resource usage monitoring +- User workflow validation + +### Code Quality Standards +- Clear, commented configurations +- Consistent naming conventions +- Comprehensive documentation +- Atomic commits with conventional messages + +### Security Guidelines + +#### Demo Security Model +- **Demo-Hardened Configurations**: All settings optimized for demonstration +- **No External Network Access**: Isolated except for image pulls +- **Production Separation**: Clear distinction from production deployments +- **Security Documentation**: All assumptions clearly documented + +#### Docker Socket Security +- **Mandatory Proxy**: All container operations through docker-socket-proxy +- **Restricted API Access**: Minimal permissions per service requirements +- **No Direct Socket Access**: Prevent direct Docker socket mounting +- **Group-Based Access**: Dynamic docker group ID assignment + +#### File System Security +- **Dynamic User Mapping**: Automatic UID/GID detection prevents ownership issues +- **Volume-First Storage**: Prefer Docker volumes over bind mounts +- **Read-Only Bind Mounts**: Minimal host filesystem access +- **Permission Validation**: Automated file ownership verification + +--- + +## ๐Ÿ”„ Development Workflow + +### Demo-First Service Addition +1. **Research**: Verify FOSS status and official Docker image availability +2. **Plan**: Determine port assignment and service group +3. **Template Configuration**: Add to docker-compose.yml.template with variables +4. **Environment Setup**: Add service variables to demo.env +5. **Security Integration**: Configure docker-socket-proxy permissions +6. **Dynamic Testing**: Validate with demo-stack.sh and demo-test.sh +7. **Documentation Update**: Update README.md, PRD.md, and AGENTS.md +8. **Atomic Commit**: Conventional commit with detailed description + +### Process Management Guidelines +- **Screen Sessions**: Use descriptive, unique names (e.g., `demo-deploy-YYYYMMDD-HHMMSS`) +- **Background Processes**: Always use logging to track progress +- **Process Discovery**: Use `ps aux | grep` and `screen -ls` to check existing work +- **Safe Termination**: Only terminate processes you explicitly started +- **Permission First**: Always ask before modifying/killing any existing process + +### Template-Driven Development +- **Variable Configuration**: All settings via environment variables +- **Naming Convention**: Consistent `tsysdevstack-supportstack-demo-` prefix +- **User Handling**: Dynamic UID/GID detection in all services +- **Security Integration**: Docker socket proxy for container operations +- **Volume Strategy**: Docker volumes with dynamic naming + +### Service Removal Process +1. **Deprecate**: Mark service for removal in documentation +2. **Test**: Verify stack functionality without service +3. **Remove**: Delete from docker-compose.yml +4. **Update**: Clean up documentation and port assignments +5. **Commit**: Document removal in commit message + +### Configuration Changes +1. **Plan**: Document change rationale and impact +2. **Test**: Validate in development environment +3. **Update**: Apply changes to configuration files +4. **Verify**: Run full test suite +5. **Document**: Update relevant documentation +6. **Commit**: Atomic commit with detailed description + +--- + +## ๐Ÿ“Š Monitoring & Observability + +### Health Check Standards +- All services must include health checks +- Health checks complete within 10 seconds +- HTTP endpoints preferred +- Fallback to container status checks + +### Resource Limits +- Memory: < 512MB per service (where applicable) +- CPU: < 25% per service (idle) +- Startup time: < 60 seconds for full stack +- Disk usage: Temporary volumes only + +### Logging Standards +- Structured logging where possible +- Log levels: INFO, WARN, ERROR +- Container logs accessible via `docker compose logs` +- No persistent log storage in demo mode + +--- + +## ๐Ÿงช Testing Guidelines + +### Demo Testing Framework +```bash +# ALWAYS check for existing work first +screen -ls +ps aux | grep demo-stack + +# Dynamic deployment and testing (use unique session names) +screen -S demo-deploy-$(date +%Y%m%d-%H%M%S) -dm -L -Logfile deploy-$(date +%Y%m%d-%H%M%S).log ./demo-stack.sh deploy +./demo-test.sh full # Comprehensive QA/validation +./demo-test.sh security # Security compliance validation +./demo-test.sh permissions # File ownership validation +./demo-test.sh network # Network isolation validation +``` + +### Automated Validation Suite +- **File Ownership**: Verify no root-owned files on host +- **User Mapping**: Validate UID/GID detection and application +- **Docker Group**: Confirm docker group access for socket proxy +- **Service Health**: All services passing health checks +- **Port Accessibility**: Verify all ports accessible from host +- **Network Isolation**: Confirm services isolated in demo network +- **Volume Permissions**: Validate Docker volume permissions +- **Security Compliance**: Docker socket proxy restrictions enforced + +### Manual Testing Checklist +- [ ] All web interfaces accessible via browser +- [ ] Demo credentials work correctly +- [ ] Service discovery functional in Homepage +- [ ] Inter-service communication working through proxy +- [ ] Resource usage within defined limits +- [ ] No port conflicts on host system +- [ ] All health checks passing +- [ ] No root-owned files created on host +- [ ] Docker socket proxy functioning correctly +- [ ] Dynamic user detection working properly + +### Performance Testing +- Startup time measurement +- Memory usage monitoring +- CPU usage validation +- Network connectivity testing +- Resource leak detection + +--- + +## ๐Ÿ“š Documentation Standards + +### README.md Requirements +- Quick start instructions +- Service overview table +- Technical configuration details +- Troubleshooting guide +- Security notes and warnings + +### PRD.md Requirements +- Product vision and goals +- Functional requirements +- User experience requirements +- Acceptance criteria +- Success metrics + +### AGENTS.md Requirements +- Development principles +- Technical standards +- Quality assurance guidelines +- Development workflow +- Testing procedures + +--- + +## ๐Ÿ”’ Security Considerations + +### Demo Security Model +- Hardcoded credentials clearly marked +- No encryption or security hardening +- Network isolation within Docker +- No external access except image pulls + +### Security Checklist +- [ ] All services use demo credentials +- [ ] No persistent sensitive data +- [ ] Network properly isolated +- [ ] Only necessary ports exposed +- [ ] Security warnings documented +- [ ] Production deployment guidance included + +--- + +## ๐Ÿš€ Deployment Guidelines + +### Local Development +```bash +# Check for existing work BEFORE starting +screen -ls +ps aux | grep demo-stack + +# Start development stack with unique session name +screen -S demo-deploy-$(date +%Y%m%d-%H%M%S) -dm -L -Logfile deploy-$(date +%Y%m%d-%H%M%S).log ./demo-stack.sh deploy + +# Monitor startup +docker compose logs -f + +# Validate deployment +./test-stack.sh +``` + +### Demo Preparation +1. Clean all containers and volumes +2. Pull latest images +3. Verify all health checks +4. Test complete user workflows +5. Document any known issues + +### Production Migration +- Replace demo credentials with secure ones +- Implement persistent data storage +- Add encryption and security hardening +- Configure backup and recovery +- Set up monitoring and alerting + +--- + +## ๐Ÿ“ž Development Support + +### Getting Help +1. Check troubleshooting section in README.md +2. Review service logs: `docker compose logs {service}` +3. Consult individual service documentation +4. Check health status: `docker compose ps` +5. **CRITICAL**: Always check for existing processes before starting new ones: `screen -ls` and `ps aux | grep demo-stack` + +### Issue Reporting +- Include full error messages +- Provide system information +- Document reproduction steps +- Include relevant configuration snippets +- Specify demo vs production context + +--- + +*Last updated: 2025-11-13* \ No newline at end of file diff --git a/demo/PRD.md b/demo/PRD.md new file mode 100644 index 0000000..7ef02e2 --- /dev/null +++ b/demo/PRD.md @@ -0,0 +1,766 @@ +# ๐Ÿ“‹ TSYS Developer Support Stack - Product Requirements Document + +
+ +[![Document ID: PRD-SUPPORT-DEMO-001](https://img.shields.io/badge/ID-PRD--SUPPORT--DEMO--001-blue.svg)](#) +[![Version: 1.0](https://img.shields.io/badge/Version-1.0-green.svg)](#) +[![Status: Draft](https://img.shields.io/badge/Status-Draft-orange.svg)](#) +[![Date: 2025-11-13](https://img.shields.io/badge/Date-2025--11--13-lightgrey.svg)](#) +[![Author: TSYS Development Team](https://img.shields.io/badge/Author-TSYS%20Dev%20Team-purple.svg)](#) + +**Demo Version - Product Requirements Document** + +
+ +--- + +## ๐Ÿ“– Table of Contents + +- [๐ŸŽฏ Product Vision](#-product-vision) +- [๐Ÿ—๏ธ Architecture Overview](#๏ธ-architecture-overview) +- [๐Ÿ“Š Functional Requirements](#-functional-requirements) +- [๐Ÿ”ง Technical Requirements](#-technical-requirements) +- [๐ŸŽจ User Experience Requirements](#-user-experience-requirements) +- [๐Ÿ”’ Security Requirements](#-security-requirements) +- [๐Ÿ“‹ Non-Functional Requirements](#-non-functional-requirements) +- [๐Ÿงช Testing Requirements](#-testing-requirements) +- [๐Ÿ“š Documentation Requirements](#-documentation-requirements) +- [โœ… Acceptance Criteria](#-acceptance-criteria) +- [๐Ÿš€ Success Metrics](#-success-metrics) +- [๐Ÿ“… Implementation Timeline](#-implementation-timeline) +- [๐Ÿ”„ Change Management](#-change-management) +- [๐Ÿ“ž Support & Maintenance](#-support--maintenance) +- [๐Ÿ“‹ Appendix](#-appendix) + +--- + +## ๐ŸŽฏ Product Vision + +> **To create a comprehensive, demo-ready developer support services stack that enhances developer productivity and quality of life for the TSYS engineering team.** + +This stack is designed to: +- ๐Ÿ  **Run locally** on every developer workstation +- โšก **Support daily development workflows** with essential services +- ๐Ÿ”’ **Maintain security** and simplicity +- ๐Ÿ†“ **Adhere to free/libre/open source principles** +- ๐ŸŽฏ **Focus on inner loop development** rather than project-specific dependencies + +--- + +## ๐Ÿ—๏ธ Architecture Overview + +### ๐ŸŽจ Design Principles + +
+ +```mermaid +graph LR + A[Demo-First] --> E[TSYS Support Stack] + B[Service Discovery] --> E + C[FOSS Only] --> E + D[Inner Loop Focus] --> E + F[Workstation Local] --> E + G[Security Conscious] --> E + + style A fill:#ffeb3b + style B fill:#4caf50 + style C fill:#2196f3 + style D fill:#ff9800 + style F fill:#9c27b0 + style G fill:#f44336 + style E fill:#e1f5fe +``` + +
+ +| Principle | Description | Priority | +|-----------|-------------|----------| +| **๐ŸŽญ Demo-First Architecture** | Demonstration-only deployment with dynamic user detection, no persistence, one-command deployment | ๐Ÿ”ฅ High | +| **๐Ÿ” Service Discovery** | Automatic discovery via Homepage dashboard with Docker labels | ๐Ÿ”ฅ High | +| **๐Ÿ†“ FOSS Only** | Exclusively use free/libre/open source software | ๐Ÿ”ฅ High | +| **โšก Inner Loop Focus** | Support daily development workflows, not project-specific dependencies | ๐Ÿ”ฅ High | +| **๐Ÿ  Workstation Local** | Run locally on developer machines, not centralized infrastructure | ๐Ÿ”ฅ High | +| **๐Ÿ”’ Security Conscious** | Demo-hardened configurations with clear production separation | ๐Ÿ”ฅ High | + +### ๐Ÿ“ฆ Service Categories + +| Category | Purpose | Services | +|----------|---------|----------| +| **๐Ÿ—๏ธ Infrastructure Services** | Core platform and management services | DNS Management, Container Socket Proxy, Container Management | +| **๐Ÿ“Š Monitoring & Observability** | Data collection and visualization services | Time Series Database, Visualization Platform | +| **๐Ÿ“š Documentation & Diagramming** | Knowledge management and creation tools | Diagramming Server, Diagrams as a Service | +| **๐Ÿ› ๏ธ Developer Tools** | Productivity and workflow enhancement services | Homepage, Time Tracking, Archiving, Email Testing, Habit Tracking | + +--- + +## ๐Ÿ“Š Functional Requirements + +### ๐Ÿ—๏ธ FR-001: Infrastructure Services + +#### FR-001.1: DNS Management Service +
+ +```mermaid +graph TD + A[DNS Management Service] --> B[Web Administration] + A --> C[DNS Filtering] + A --> D[Network Monitoring] + A --> E[Demo Configuration] + A --> F[Health Monitoring] + A --> G[Service Discovery] + + style A fill:#e3f2fd + style B fill:#bbdefb + style C fill:#bbdefb + style D fill:#bbdefb + style E fill:#fff3e0 + style F fill:#e8f5e8 + style G fill:#fce4ec +``` + +
+ +| Requirement | Description | Acceptance | +|-------------|-------------|------------| +| **๐ŸŒ Web Interface** | Browser-based administration interface | โœ… Required | +| **๐Ÿ›ก๏ธ DNS Filtering** | Ad blocking and content filtering capabilities | โœ… Required | +| **๐Ÿ“Š Network Monitoring** | Traffic analysis and reporting | โœ… Required | +| **๐ŸŽญ Demo Configuration** | Default settings for demonstration | โœ… Required | +| **๐Ÿ”— Web Access** | Assigned port for web interface | โœ… Required | +| **โค๏ธ Health Check** | Endpoint for service monitoring | โœ… Required | +| **๐Ÿท๏ธ Service Discovery** | Integration with Infrastructure group | โœ… Required | + +#### FR-001.2: Container Socket Proxy +
+ +```mermaid +graph TD + A[Container Socket Proxy] --> B[API Access Control] + A --> C[Request Filtering] + A --> D[Security Restrictions] + A --> E[Permission Management] + A --> F[Health Monitoring] + A --> G[Service Discovery] + + style A fill:#ffebee + style B fill:#ffcdd2 + style C fill:#ffcdd2 + style D fill:#ffcdd2 + style E fill:#fff3e0 + style F fill:#e8f5e8 + style G fill:#fce4ec +``` + +
+ +| Requirement | Description | Acceptance | +|-------------|-------------|------------| +| **๐Ÿ›ก๏ธ API Access Control** | Restrict Docker socket API endpoints | โœ… Required | +| **๐Ÿ” Request Filtering** | Block dangerous operations by default | โœ… Required | +| **๐Ÿ”’ Security Restrictions** | Granular permission management | โœ… Required | +| **โš™๏ธ Permission Management** | Environment-based access control | โœ… Required | +| **โค๏ธ Health Check** | Endpoint for service monitoring | โœ… Required | +| **๐Ÿท๏ธ Service Discovery** | Integration with Infrastructure group | โœ… Required | + +#### FR-001.3: Container Management Service +
+ +```mermaid +graph TD + A[Container Management Service] --> B[Container Lifecycle] + A --> C[Image Management] + A --> D[Volume & Network Management] + A --> E[User Authentication] + A --> F[Health Monitoring] + A --> G[Service Discovery] + + style A fill:#f3e5f5 + style B fill:#e1bee7 + style C fill:#e1bee7 + style D fill:#e1bee7 + style E fill:#fff3e0 + style F fill:#e8f5e8 + style G fill:#fce4ec +``` + +
+ +| Requirement | Description | Acceptance | +|-------------|-------------|------------| +| **๐Ÿ”„ Container Lifecycle** | Start/stop/restart container operations | โœ… Required | +| **๐Ÿ“ฆ Image Management** | Registry integration and image operations | โœ… Required | +| **๐Ÿ’พ Volume & Network** | Storage and network configuration | โœ… Required | +| **๐Ÿ” Authentication** | User authentication with demo credentials | โœ… Required | +| **๐Ÿ”— Web Access** | Assigned port for web interface | โœ… Required | +| **โค๏ธ Health Check** | Endpoint for service monitoring | โœ… Required | +| **๐Ÿท๏ธ Service Discovery** | Integration with Infrastructure group | โœ… Required | + +### ๐Ÿ“Š FR-002: Monitoring & Observability + +#### FR-002.1: Time Series Database +
+ +```mermaid +graph TD + A[Time Series Database] --> B[HTTP API] + A --> C[Web Administration] + A --> D[Demo Database] + A --> E[Data Access] + A --> F[Health Monitoring] + A --> G[Service Discovery] + + style A fill:#e8f5e8 + style B fill:#c8e6c9 + style C fill:#c8e6c9 + style D fill:#fff3e0 + style E fill:#bbdefb + style F fill:#e8f5e8 + style G fill:#fce4ec +``` + +
+ +| Requirement | Description | Acceptance | +|-------------|-------------|------------| +| **๐ŸŒ HTTP API** | Data ingestion and querying interface | โœ… Required | +| **๐Ÿ–ฅ๏ธ Web Interface** | Browser-based administration | โœ… Required | +| **๐ŸŽญ Demo Database** | Sample data for demonstration | โœ… Required | +| **๐Ÿ”— Data Access** | Assigned port for API and web access | โœ… Required | +| **โค๏ธ Health Check** | Endpoint for service monitoring | โœ… Required | +| **๐Ÿท๏ธ Service Discovery** | Integration with Monitoring group | โœ… Required | + +#### FR-002.2: Visualization Platform +
+ +```mermaid +graph TD + A[Visualization Platform] --> B[Data Source Connection] + A --> C[Demo Dashboards] + A --> D[Dashboard Creation] + A --> E[Admin Authentication] + A --> F[Health Monitoring] + A --> G[Service Discovery] + + style A fill:#fff3e0 + style B fill:#ffe0b2 + style C fill:#ffe0b2 + style D fill:#ffe0b2 + style E fill:#fff3e0 + style F fill:#e8f5e8 + style G fill:#fce4ec +``` + +
+ +| Requirement | Description | Acceptance | +|-------------|-------------|------------| +| **๐Ÿ”— Data Connection** | Pre-configured connection to time series database | โœ… Required | +| **๐Ÿ“Š Demo Dashboards** | System metrics visualization | โœ… Required | +| **๐ŸŽจ Dashboard Creation** | Web-based dashboard editing | โœ… Required | +| **๐Ÿ” Admin Authentication** | Authentication with demo credentials | โœ… Required | +| **๐Ÿ”— Web Access** | Assigned port for web interface | โœ… Required | +| **โค๏ธ Health Check** | Endpoint for service monitoring | โœ… Required | +| **๐Ÿท๏ธ Service Discovery** | Integration with Monitoring group | โœ… Required | + +### ๐Ÿ› ๏ธ FR-003: Developer Tools + +#### FR-003.1: Habit Tracking Service +
+ +```mermaid +graph TD + A[Habit Tracking Service] --> B[Personal Dashboard] + A --> C[Habit Management] + A --> D[Progress Tracking] + A --> E[Gamification System] + A --> F[Integrations Support] + A --> G[Health Monitoring] + A --> H[Service Discovery] + + style A fill:#fff3e0 + style B fill:#ffe0b2 + style C fill:#ffe0b2 + style D fill:#ffe0b2 + style E fill:#ffe0b2 + style F fill:#e8f5e8 + style G fill:#e8f5e8 + style H fill:#fce4ec +``` + +
+ +| Requirement | Description | Acceptance | +|-------------|-------------|------------| +| **๐Ÿ“Š Personal Dashboard** | Visual overview of habits and progress | โœ… Required | +| **๐ŸŽฏ Habit Management** | Create, edit, and delete habits | โœ… Required | +| **๐Ÿ“ˆ Progress Tracking** | Track consistency and improvements | โœ… Required | +| **๐ŸŽฎ Gamification** | Points system and achievement tracking | โœ… Required | +| **๐Ÿ”— Integrations** | Support for external data providers | โœ… Optional | +| **๐Ÿ”— Web Access** | Assigned port for web interface | โœ… Required | +| **โค๏ธ Health Check** | Endpoint for service monitoring | โœ… Required | +| **๐Ÿท๏ธ Service Discovery** | Integration with Developer Tools group | โœ… Required | + +### ๐Ÿ“š FR-004: Documentation & Diagramming + +#### FR-004.1: Diagramming Server +
+ +```mermaid +graph TD + A[Diagramming Server] --> B[Browser-based Editing] + A --> C[Multiple Export Formats] + A --> D[Cloud Storage Integration] + A --> E[No Authentication] + A --> F[Health Monitoring] + A --> G[Service Discovery] + + style A fill:#fce4ec + style B fill:#f8bbd9 + style C fill:#f8bbd9 + style D fill:#fff3e0 + style E fill:#e8f5e8 + style F fill:#e8f5e8 + style G fill:#fce4ec +``` + +
+ +| Requirement | Description | Acceptance | +|-------------|-------------|------------| +| **๐ŸŽจ Browser Editing** | Diagram creation and editing in browser | โœ… Required | +| **๐Ÿ“ค Export Formats** | PNG, SVG, PDF export capabilities | โœ… Required | +| **โ˜๏ธ Cloud Integration** | Optional cloud storage integration | โœ… Optional | +| **๐Ÿ”“ No Authentication** | Demo mode without login requirements | โœ… Required | +| **๐Ÿ”— Web Access** | Assigned port for web interface | โœ… Required | +| **โค๏ธ Health Check** | Endpoint for service monitoring | โœ… Required | +| **๐Ÿท๏ธ Service Discovery** | Integration with Documentation group | โœ… Required | + +#### FR-004.2: Diagrams as a Service +
+ +```mermaid +graph TD + A[Diagrams as a Service] --> B[Multiple Diagram Types] + A --> C[HTTP API] + A --> D[Web Interface] + A --> E[No Authentication] + A --> F[Health Monitoring] + A --> G[Service Discovery] + + style A fill:#e0f2f1 + style B fill:#b2dfdb + style C fill:#b2dfdb + style D fill:#b2dfdb + style E fill:#e8f5e8 + style F fill:#e8f5e8 + style G fill:#fce4ec +``` + +
+ +| Requirement | Description | Acceptance | +|-------------|-------------|------------| +| **๐ŸŽจ Diagram Types** | PlantUML, Mermaid, GraphViz support | โœ… Required | +| **๐ŸŒ HTTP API** | Programmatic diagram generation | โœ… Required | +| **๐Ÿ–ฅ๏ธ Web Interface** | Simple testing interface | โœ… Required | +| **๐Ÿ”“ No Authentication** | Demo mode without login requirements | โœ… Required | +| **๐Ÿ”— API Access** | Assigned port for API and web access | โœ… Required | +| **โค๏ธ Health Check** | Endpoint for service monitoring | โœ… Required | +| **๐Ÿท๏ธ Service Discovery** | Integration with Documentation group | โœ… Required | + +--- + +## ๐Ÿ”ง Technical Requirements + +### ๐Ÿณ TR-001: Containerization Standards + +| Requirement | Description | Priority | +|-------------|-------------|----------| +| **๐Ÿ“ฆ Official Images** | Use official Docker images only | ๐Ÿ”ฅ High | +| **โค๏ธ Health Checks** | Comprehensive health monitoring | ๐Ÿ”ฅ High | +| **๐Ÿ” Service Discovery** | Automatic dashboard integration | ๐Ÿ”ฅ High | +| **๐Ÿ”„ Restart Policies** | Appropriate recovery mechanisms | ๐Ÿ”ฅ High | + +### ๐ŸŒ TR-002: Network Architecture + +| Requirement | Description | Priority | +|-------------|-------------|----------| +| **๐Ÿ”’ Dedicated Network** | Isolated network environment | ๐Ÿ”ฅ High | +| **๐Ÿ”ข Port Consistency** | Sequential numbering pattern | ๐Ÿ”ฅ High | +| **๐ŸŒ Web Access** | Standard browser interfaces | ๐Ÿ”ฅ High | +| **๐Ÿค Inter-service Communication** | Required service interactions | ๐Ÿ”ฅ High | + +### ๐Ÿ’พ TR-003: Data Strategy + +| Requirement | Description | Priority | +|-------------|-------------|----------| +| **๐Ÿšซ No Persistence** | Demo simplicity focus | ๐Ÿ”ฅ High | +| **โฐ Temporary Data** | Service functionality support | ๐Ÿ”ฅ High | +| **๐Ÿ”„ Session Reset** | Clean state between demos | ๐Ÿ”ฅ High | +| **๐Ÿ” Demo Credentials** | Simplified authentication | ๐Ÿ”ฅ High | + +### ๐Ÿ”— TR-004: Service Integration + +| Requirement | Description | Priority | +|-------------|-------------|----------| +| **๐Ÿท๏ธ Dashboard Discovery** | Centralized service visibility | ๐Ÿ”ฅ High | +| **๐Ÿ“Š Consistent Metadata** | Standardized service information | ๐Ÿ”ฅ High | +| **๐ŸŽจ Unified Access** | Consistent user experience | ๐Ÿ”ฅ High | +| **๐Ÿ”„ Standard Interfaces** | Common interaction patterns | ๐Ÿ”ฅ High | + +--- + +## ๐ŸŽจ User Experience Requirements + +### ๐Ÿ  UX-001: Unified Dashboard + +
+ +```mermaid +graph LR + A[Single Entry Point] --> B[Automatic Discovery] + A --> C[Intuitive Organization] + A --> D[Consistent Design] + A --> E[Real-time Status] + + style A fill:#e1f5fe + style B fill:#b3e5fc + style C fill:#b3e5fc + style D fill:#b3e5fc + style E fill:#b3e5fc +``` + +
+ +| Requirement | Description | Success Metric | +|-------------|-------------|----------------| +| **๐Ÿšช Single Entry Point** | One dashboard for all services | 100% service visibility | +| **๐Ÿ” Automatic Discovery** | No manual configuration required | Zero-touch setup | +| **๐Ÿ“‚ Intuitive Organization** | Logical service grouping | User satisfaction > 90% | +| **๐ŸŽจ Consistent Design** | Unified visual experience | Design consistency > 95% | +| **๐Ÿ“Š Real-time Status** | Live service health indicators | Status accuracy > 99% | + +### โšก UX-002: Zero-Configuration Access + +| Requirement | Description | Success Metric | +|-------------|-------------|----------------| +| **๐ŸŒ Browser Access** | Immediate web interface availability | 100% browser compatibility | +| **๐Ÿšซ No Manual Setup** | Eliminate configuration steps | Setup time < 30 seconds | +| **๐Ÿ” Pre-configured Auth** | Default authentication where needed | Login success rate > 95% | +| **๐Ÿ’ก Clear Error Messages** | Intuitive troubleshooting guidance | Issue resolution < 2 minutes | + +### ๐ŸŽญ UX-003: Instant Demo Experience + +| Requirement | Description | Success Metric | +|-------------|-------------|----------------| +| **โšก Single Command** | One-command deployment | Deployment time < 60 seconds | +| **๐Ÿš€ Rapid Initialization** | Fast service startup | All services ready < 60 seconds | +| **๐ŸŽฏ Immediate Features** | No setup delays for functionality | Feature availability = 100% | +| **๐Ÿ”„ Clean Sessions** | Fresh state between demos | Data reset success = 100% | + +--- + +## ๐Ÿ”’ Security Requirements + +### ๐Ÿ›ก๏ธ SEC-001: Demo-Only Security Model + +| Requirement | Description | Implementation | +|-------------|-------------|----------------| +| **๐ŸŽญ Demo Configuration** | Development/demo use only | Clear documentation warnings | +| **๐Ÿ”“ Hardcoded Credentials** | Clearly marked demo credentials | Obvious demo-only labeling | +| **๐Ÿšซ No External Access** | Isolated from external networks | Docker network isolation | +| **๐Ÿ”“ No Hardening** | No encryption or security features | Simplified demo setup | + +### ๐Ÿ”’ SEC-002: Network Isolation + +| Requirement | Description | Implementation | +|-------------|-------------|----------------| +| **๐Ÿ  Docker Isolation** | Services contained within Docker network | Dedicated network configuration | +| **๐Ÿ”Œ Minimal Exposure** | Only necessary ports exposed | Port access control | +| **๐Ÿšซ No Privilege Escalation** | Prevent container privilege escalation | Security context configuration | +| **๐Ÿ”— Secure API Access** | Container socket proxy for API access | Proxy service implementation | + +--- + +## ๐Ÿ“‹ Non-Functional Requirements + +### โšก NFR-001: Performance + +| Metric | Requirement | Target | +|--------|-------------|--------| +| **๐Ÿš€ Startup Time** | All services must start within | 60 seconds | +| **โค๏ธ Health Check Speed** | Health checks must complete within | 10 seconds | +| **๐Ÿ’พ Memory Usage** | Per service memory limit | < 512MB | +| **๐Ÿ–ฅ๏ธ CPU Usage** | Per service CPU usage (idle) | < 25% | + +### ๐Ÿ”„ NFR-002: Reliability + +| Requirement | Description | Implementation | +|-------------|-------------|----------------| +| **โค๏ธ Health Checks** | All services include health monitoring | Comprehensive health endpoints | +| **๐Ÿ”„ Auto Restart** | Automatic recovery on failure | Restart policy configuration | +| **โน๏ธ Graceful Shutdown** | Proper service termination handling | Signal handling implementation | +| **๐Ÿ”— Dependency Management** | Service startup order management | Dependency configuration | + +### ๐Ÿ”ง NFR-003: Maintainability + +| Requirement | Description | Standard | +|-------------|-------------|----------| +| **๐Ÿ“ Clear Configuration** | Well-documented setup | Commented configurations | +| **๐Ÿท๏ธ Consistent Naming** | Standardized service organization | Naming conventions | +| **๐Ÿ“š Comprehensive Docs** | Complete documentation coverage | Documentation standards | +| **โž• Easy Service Management** | Simple addition/removal processes | Modular architecture | + +--- + +## ๐Ÿงช Testing Requirements + +### ๐Ÿค– TST-001: Automated Testing + +
+ +```mermaid +graph TD + A[Automated Testing] --> B[Health Validation] + A --> C[Port Verification] + A --> D[Service Discovery] + A --> E[Resource Monitoring] + A --> F[Comprehensive Suite] + + style A fill:#e8f5e8 + style B fill:#c8e6c9 + style C fill:#c8e6c9 + style D fill:#c8e6c9 + style E fill:#c8e6c9 + style F fill:#c8e6c9 +``` + +
+ +| Test Type | Description | Tool/Script | +|-----------|-------------|-------------| +| **โค๏ธ Health Validation** | Service health check verification | `test-stack.sh` | +| **๐Ÿ”Œ Port Accessibility** | Port availability and response testing | `test-stack.sh` | +| **๐Ÿ” Service Discovery** | Dashboard integration verification | `test-stack.sh` | +| **๐Ÿ“Š Resource Monitoring** | Memory and CPU usage validation | `test-stack.sh` | +| **๐Ÿ“‹ Comprehensive Suite** | Full integration testing | `test-stack.sh` | + +### โœ‹ TST-002: Manual Testing + +| Test Area | Description | Success Criteria | +|-----------|-------------|------------------| +| **๐ŸŒ Web Interfaces** | Browser interface functionality | All interfaces accessible | +| **๐Ÿ” Demo Credentials** | Authentication verification | Login success = 100% | +| **๐Ÿ”— Service Integration** | Cross-service functionality | Integration tests pass | +| **๐Ÿ‘ค User Workflows** | End-to-end user scenarios | Workflow completion = 100% | + +--- + +## ๐Ÿ“š Documentation Requirements + +### ๐Ÿ“– DOC-001: Technical Documentation + +| Requirement | Description | Location | +|-------------|-------------|----------| +| **๐Ÿ“‹ README Updates** | Complete service documentation | `README.md` | +| **๐ŸŒ Access Information** | Service URLs and credentials | `README.md` | +| **โš™๏ธ Configuration Details** | Technical setup specifications | `README.md` | +| **๐Ÿ”ง Troubleshooting Guide** | Common issue resolution | `README.md` | + +### ๐Ÿ‘ฅ DOC-002: User Documentation + +| Requirement | Description | Location | +|-------------|-------------|----------| +| **๐Ÿš€ Quick Start** | Rapid deployment instructions | `README.md` | +| **๐Ÿ“š Service Descriptions** | Feature and use case documentation | `README.md` | +| **๐Ÿ” Credential Reference** | Demo credential information | `README.md` | +| **โ“ FAQ Section** | Common questions and answers | `README.md` | + +--- + +## โœ… Acceptance Criteria + +### ๐Ÿš€ AC-001: Deployment Success + +| Criteria | Description | Status | +|----------|-------------|--------| +| **โšก Service Startup** | All services start with `docker compose up -d` | โœ… Required | +| **โค๏ธ Health Validation** | All services pass health checks within 60 seconds | โœ… Required | +| **๐Ÿ” Service Discovery** | Homepage discovers and displays all services | โœ… Required | +| **๐ŸŒ Web Access** | All interfaces accessible via browser | โœ… Required | + +### ๐Ÿ”ง AC-002: Functionality Verification + +| Criteria | Description | Status | +|----------|-------------|--------| +| **๐Ÿ›ก๏ธ DNS Management** | Web interface loads and functions correctly | โœ… Required | +| **๐Ÿ”„ Container Management** | Container operations work properly | โœ… Required | +| **๐Ÿ“Š Database Operations** | Data storage and retrieval functional | โœ… Required | +| **๐Ÿ“ˆ Visualization** | Dashboards display and update correctly | โœ… Required | +| **๐ŸŽจ Diagramming** | Creation and export functions work | โœ… Required | +| **๐Ÿ“ Diagram Service** | Text-to-diagram conversion functional | โœ… Required | + +### ๐Ÿ”— AC-003: Integration Testing + +| Criteria | Description | Status | +|----------|-------------|--------| +| **๐Ÿ” Service Discovery** | Automatic discovery works correctly | โœ… Required | +| **๐Ÿค Inter-service Communication** | Required communications function | โœ… Required | +| **โค๏ธ Health Monitoring** | Health checks trigger appropriately | โœ… Required | +| **๐Ÿ“Š Resource Management** | Usage remains within defined limits | โœ… Required | + +--- + +## ๐Ÿš€ Success Metrics + +### ๐Ÿ“Š Deployment Metrics + +| Metric | Target | Measurement | +|--------|--------|-------------| +| **โฑ๏ธ Stack Readiness** | < 2 minutes | Time to full functionality | +| **โœ… Service Success Rate** | 100% | Services starting successfully | +| **โค๏ธ Health Check Pass Rate** | 100% | Services passing health checks | + +### ๐Ÿ‘ฅ User Experience Metrics + +| Metric | Target | Measurement | +|--------|--------|-------------| +| **โšก Deployment Success** | 100% | Single-command deployment success | +| **๐Ÿ” Dashboard Accessibility** | 100% | Services accessible via Homepage | +| **๐Ÿšซ Configuration Required** | None | Zero configuration for basic use | + +--- + +## ๐Ÿ“… Implementation Timeline + +
+ +```mermaid +gantt + title TSYS Developer Support Stack Implementation + dateFormat YYYY-MM-DD + section Phase 1: Core Infrastructure + DNS Management Service :active, p1-1, 2025-11-13, 3d + Container Management :p1-2, after p1-1, 2d + Service Discovery Validation :p1-3, after p1-2, 2d + + section Phase 2: Monitoring Stack + Time Series Database :p2-1, after p1-3, 2d + Visualization Platform :p2-2, after p2-1, 3d + Dashboard Creation :p2-3, after p2-2, 2d + + section Phase 3: Documentation Tools + Diagramming Server :p3-1, after p2-3, 2d + Diagram Service :p3-2, after p3-1, 2d + Integration Testing :p3-3, after p3-2, 2d + + section Phase 4: Testing & Documentation + Comprehensive Test Suite :p4-1, after p3-3, 3d + Documentation Updates :p4-2, after p4-1, 2d + Final Validation :p4-3, after p4-2, 2d +``` + +
+ +### ๐Ÿ“… Phase Details + +| Phase | Duration | Focus | Deliverables | +|-------|----------|-------|--------------| +| **๐Ÿ—๏ธ Phase 1** | Week 1 | Core Infrastructure | DNS Management, Container Management, Service Discovery | +| **๐Ÿ“Š Phase 2** | Week 1 | Monitoring Stack | Time Series Database, Visualization Platform, Dashboards | +| **๐Ÿ“š Phase 3** | Week 2 | Documentation Tools | Diagramming Server, Diagram Service, Integration | +| **๐Ÿงช Phase 4** | Week 2 | Testing & Documentation | Test Suite, Documentation, Validation | + +--- + +## ๐Ÿ”„ Change Management + +### ๐Ÿ“ Version Control Strategy + +| Practice | Description | Standard | +|----------|-------------|----------| +| **๐Ÿ“Š Comprehensive Tracking** | All changes tracked via Git | 100% change coverage | +| **๐Ÿ“‹ Structured Messages** | Conventional commit formatting | Commit message standards | +| **โš›๏ธ Atomic Changes** | Small, focused commits | Single-purpose commits | +| **๐Ÿ“ Detailed Descriptions** | Clear change documentation | Comprehensive commit messages | + +### ๐Ÿ” Quality Assurance Process + +| Step | Description | Tool/Process | +|------|-------------|--------------| +| **๐Ÿค– Automated Validation** | Automated testing on all changes | Test suite execution | +| **โœ‹ Manual Testing** | Manual validation for new services | User acceptance testing | +| **๐Ÿ“š Documentation Updates** | Synchronized documentation updates | Documentation review | +| **โœ… Requirements Validation** | Continuous validation against PRD | Requirements traceability | + +--- + +## ๐Ÿ“ž Support & Maintenance + +### ๐Ÿ”ง Troubleshooting Framework + +| Component | Description | Implementation | +|-----------|-------------|----------------| +| **๐Ÿ“‹ Comprehensive Logging** | Service logging and diagnostics | Docker log integration | +| **๐Ÿ“Š Real-time Monitoring** | Live health and status reporting | Health check endpoints | +| **๐Ÿ“– Documented Procedures** | Resolution procedures for common issues | Troubleshooting guides | + +### ๐Ÿ”„ Maintenance Strategy + +| Activity | Description | Frequency | +|----------|-------------|----------| +| **๐Ÿ“ฆ Image Updates** | Regular service image updates | Weekly | +| **โš™๏ธ Configuration Management** | Change tracking and validation | Continuous | +| **๐Ÿ”— Compatibility Preservation** | Maintain backward compatibility | During updates | +| **๐Ÿ“ˆ Continuous Improvement** | User feedback-based enhancements | Ongoing | + +--- + +## ๐Ÿ“‹ Appendix + +### ๐Ÿ“ฆ A. Service Categories + +| Category | Purpose | Example Services | +|----------|---------|-----------------| +| **๐Ÿ—๏ธ Infrastructure Services** | Core platform and management tools | DNS Management, Container Socket Proxy, Container Management | +| **๐Ÿ“Š Monitoring & Observability** | Data collection and visualization | Time Series Database, Visualization Platform | +| **๐Ÿ“š Documentation & Diagramming** | Knowledge management and creation | Diagramming Server, Diagrams as a Service | +| **๐Ÿ› ๏ธ Developer Tools** | Productivity and workflow enhancement | Homepage, Time Tracking, Archiving, Habit Tracking | + +### ๐Ÿ”— B. Integration Requirements + +| Requirement | Description | Implementation | +|-------------|-------------|----------------| +| **๐Ÿท๏ธ Dashboard Discovery** | Centralized service visibility | Homepage integration | +| **๐Ÿค Inter-service Communication** | Required service interactions | Network configuration | +| **๐Ÿ” Consistent Authentication** | Unified access patterns | Demo credential strategy | +| **โค๏ธ Unified Monitoring** | Standardized health checking | Health check standards | + +### โœ… C. Success Criteria + +| Criteria | Description | Measurement | +|----------|-------------|-------------| +| **๐Ÿ” Service Discoverability** | All services accessible from central dashboard | 100% service visibility | +| **โšก Rapid Demonstration** | Complete functionality demonstration within 2 minutes | Time-to-demo < 120 seconds | +| **๐ŸŽฏ Intuitive Experience** | Minimal training required for basic use | User satisfaction > 90% | +| **๐Ÿ”„ Cross-Platform Reliability** | Consistent operation across development environments | Platform compatibility > 95% | + +--- + +
+ +--- + +## ๐Ÿ“„ Document Information + +**Document ID**: PRD-SUPPORT-DEMO-001 +**Version**: 1.0 +**Date**: 2025-11-13 +**Author**: TSYS Development Team +**Status**: Draft + +--- + +*This PRD serves as the source of truth for the TSYS Developer Support Stack demo implementation and will be used for audit and quality assurance purposes.* + +
\ No newline at end of file diff --git a/demo/README.md b/demo/README.md new file mode 100644 index 0000000..e4c811f --- /dev/null +++ b/demo/README.md @@ -0,0 +1,415 @@ +# ๐Ÿš€ TSYS Developer Support Stack - Demo + +
+ +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) +[![Docker](https://img.shields.io/badge/Docker-Ready-blue.svg)](https://www.docker.com/) +[![FOSS](https://img.shields.io/badge/FOSS-Only-green.svg)](https://www.fsf.org/) +[![Demo](https://img.shields.io/badge/Mode-Demo-orange.svg)](#) + +*A comprehensive, demo-ready developer support services stack that enhances productivity and quality of life for the TSYS engineering team.* + +
+ +--- + +## ๐Ÿ“– Table of Contents + +- [๐Ÿš€ Quick Start](#-quick-start) +- [๐Ÿ“‹ Services Overview](#-services-overview) +- [๐Ÿ”ง Technical Configuration](#-technical-configuration) +- [๐Ÿ” Demo Credentials](#-demo-credentials) +- [๐Ÿ“Š Service Dependencies](#-service-dependencies) +- [๐Ÿงช Testing](#-testing) +- [๐Ÿ” Troubleshooting](#-troubleshooting) +- [๐Ÿ“ Data Management](#-data-management) +- [๐Ÿ”„ Updates & Maintenance](#-updates--maintenance) +- [๐Ÿ“š Documentation](#-documentation) +- [๐Ÿšจ Security Notes](#-security-notes) +- [๐Ÿ“ž Support](#-support) + +--- + +## ๐Ÿš€ Quick Start + +
+ +```bash +# ๐ŸŽฏ Demo deployment with dynamic user detection +./demo-stack.sh deploy + +# ๐Ÿ”ง Comprehensive testing and validation +./demo-test.sh full +``` + +
+ +๐ŸŽ‰ **Access all services via the Homepage dashboard at** **[http://localhost:${HOMEPAGE_PORT}](http://localhost:${HOMEPAGE_PORT})** + +> โš ๏ธ **Demo Configuration Only** - This stack is designed for demonstration purposes with no data persistence. + +--- + +## ๐Ÿ”ง Dynamic Deployment Architecture + +### ๐Ÿ“‹ Environment Variables + +All configuration is managed through `demo.env` and dynamic detection: + +| Variable | Description | Default | +|-----------|-------------|----------| +| **COMPOSE_PROJECT_NAME** | Consistent naming prefix | `tsysdevstack-supportstack-demo` | +| **UID** | Current user ID | Auto-detected | +| **GID** | Current group ID | Auto-detected | +| **DOCKER_GID** | Docker group ID | Auto-detected | +| **COMPOSE_NETWORK_NAME** | Docker network name | `tsysdevstack-supportstack-demo-network` | + +### ๐ŸŽฏ Deployment Scripts + +| Script | Purpose | Usage | +|---------|---------|--------| +| **demo-stack.sh** | Dynamic deployment with user detection | `./demo-stack.sh [deploy|stop|restart]` | +| **demo-test.sh** | Comprehensive QA and validation | `./demo-test.sh [full|security|permissions]` | +| **demo.env** | All environment variables | Source of configuration | + +--- + +## ๐Ÿ“‹ Services Overview + +### ๐Ÿ› ๏ธ Developer Tools +| Service | Port | Description | ๐ŸŒ Access | +|---------|------|-------------|-----------| +| **Homepage** | 4000 | Central dashboard for service discovery | [Open](http://192.168.3.6:4000) | +| **Atomic Tracker** | 4012 | Habit tracking and personal dashboard | [Open](http://192.168.3.6:4012) | +| **Wakapi** | 4015 | Open-source WakaTime alternative for time tracking | [Open](http://192.168.3.6:4015) | +| **MailHog** | 4017 | Web and API based SMTP testing tool | [Open](http://192.168.3.6:4017) | +| **Atuin** | 4018 | Magical shell history synchronization | [Open](http://192.168.3.6:4018) | + +### ๐Ÿ“š Archival & Content Management +| Service | Port | Description | ๐ŸŒ Access | +|---------|------|-------------|-----------| +| **ArchiveBox** | 4013 | Web archiving solution | [Open](http://192.168.3.6:4013) | +| **Tube Archivist** | 4014 | YouTube video archiving | [Open](http://192.168.3.6:4014) | + +### ๐Ÿ—๏ธ Infrastructure Services +| Service | Port | Description | ๐ŸŒ Access | +|---------|------|-------------|-----------| +| **Pi-hole** | 4006 | DNS-based ad blocking and monitoring | [Open](http://192.168.3.6:4006) | +| **Portainer** | 4007 | Web-based container management | [Open](http://192.168.3.6:4007) | + +### ๐Ÿ“Š Monitoring & Observability +| Service | Port | Description | ๐ŸŒ Access | +|---------|------|-------------|-----------| +| **InfluxDB** | 4008 | Time series database for metrics | [Open](http://192.168.3.6:4008) | +| **Grafana** | 4009 | Analytics and visualization platform | [Open](http://192.168.3.6:4009) | + +### ๐Ÿ“š Documentation & Diagramming +| Service | Port | Description | ๐ŸŒ Access | +|---------|------|-------------|-----------| +| **Draw.io** | 4010 | Web-based diagramming application | [Open](http://192.168.3.6:4010) | +| **Kroki** | 4011 | Diagrams as a service | [Open](http://192.168.3.6:4011) | + +--- + +## ๐Ÿ”ง Technical Configuration + +### ๐Ÿณ Docker Integration + +
+ +```yaml +# Demo service template (docker-compose.yml.template) +services: + service-name: + image: official/image:tag + user: "${UID}:${GID}" + container_name: "${COMPOSE_PROJECT_NAME}-service-name" + restart: unless-stopped + networks: + - ${COMPOSE_NETWORK_NAME} + volumes: + - "${COMPOSE_PROJECT_NAME}_service_data:/path" + environment: + - PUID=${UID} + - PGID=${GID} + labels: + homepage.group: "Group Name" + homepage.name: "Display Name" + homepage.icon: "icon-name" + homepage.href: "http://localhost:${SERVICE_PORT}" + homepage.description: "Brief description" +``` + +
+ +### โš™๏ธ Dynamic Configuration + +| Setting | Variable | Description | +|---------|-----------|-------------| +| **Service Naming** | `${COMPOSE_PROJECT_NAME}-{service}` | Dynamic container naming | +| **Network** | `${COMPOSE_NETWORK_NAME}` | Dedicated Docker network | +| **User Mapping** | `${UID}:${GID}` | Dynamic user detection | +| **Docker Group** | `${DOCKER_GID}` | Docker socket access | +| **Volume Naming** | `${COMPOSE_PROJECT_NAME}_{service}_data` | Consistent volumes | +| **Restart Policy** | `unless-stopped` | Automatic recovery | + +### ๐Ÿ” Health Check Endpoints + +| Service | Health Check Path | Status | +|---------|-------------------|--------| +| **Pi-hole** (DNS Management) | `HTTP GET /` | โœ… Active | +| **Portainer** (Container Management) | `HTTP GET /` | โœ… Active | +| **InfluxDB** (Time Series Database) | `HTTP GET /ping` | โœ… Active | +| **Grafana** (Visualization Platform) | `HTTP GET /api/health` | โœ… Active | +| **Draw.io** (Diagramming Server) | `HTTP GET /` | โœ… Active | +| **Kroki** (Diagrams as a Service) | `HTTP GET /health` | โœ… Active | + +### ๐Ÿท๏ธ Service Discovery Labels + +All services include Homepage labels for auto-discovery: + +```yaml +labels: + homepage.group: "Service category" + homepage.name: "Display name" + homepage.icon: "Appropriate icon" + homepage.href: "Full URL" + homepage.description: "Brief service description" +``` + +--- + +## ๐Ÿ” Demo Credentials + +> โš ๏ธ **Demo Configuration Only** - Reset all credentials before production use + +| Service | Username | Password | ๐Ÿ”— Access | +|---------|----------|----------|-----------| +| **Grafana** | `admin` | `demo_password` | [Login](http://localhost:4009) | +| **Portainer** | `admin` | `demo_password` | [Login](http://localhost:4007) | + +--- + +## ๐Ÿ“Š Service Dependencies + +```mermaid +graph TD + A[Homepage Dashboard] --> B[All Services] + C[Container Management] --> D[Container Socket Proxy] + E[Visualization Platform] --> F[Time Series Database] + G[All Other Services] --> H[No Dependencies] + + style A fill:#e1f5fe + style C fill:#f3e5f5 + style E fill:#e8f5e8 + style G fill:#fff3e0 +``` + +| Service | Dependencies | Status | +|---------|--------------|--------| +| **Container Management** (Portainer) | Container Socket Proxy | ๐Ÿ”— Required | +| **Visualization Platform** (Grafana) | Time Series Database (InfluxDB) | ๐Ÿ”— Required | +| **All Other Services** | None | โœ… Standalone | + +--- + +## ๐Ÿงช Testing & Validation + +### ๐Ÿค– Automated Demo Testing + +
+ +```bash +# ๐ŸŽฏ Full deployment and validation +./demo-stack.sh deploy && ./demo-test.sh full + +# ๐Ÿ” Security compliance validation +./demo-test.sh security + +# ๐Ÿ‘ค File ownership validation +./demo-test.sh permissions + +# ๐ŸŒ Network isolation validation +./demo-test.sh network +``` + +
+ +### โœ… Manual Validation Commands + +```bash +# ๐Ÿ“Š Check service status with dynamic naming +docker compose ps + +# ๐Ÿ“‹ View service logs +docker compose logs {service-name} + +# ๐ŸŒ Test individual endpoints with variables +curl -f http://localhost:${HOMEPAGE_PORT}/ +curl -f http://localhost:${INFLUXDB_PORT}/ping +curl -f http://localhost:${GRAFANA_PORT}/api/health + +# ๐Ÿ” Validate user permissions +ls -la /var/lib/docker/volumes/${COMPOSE_PROJECT_NAME}_*/ +``` + +--- + +## ๐Ÿ” Troubleshooting + +### ๐Ÿšจ Common Issues + +#### Services not starting +```bash +# ๐Ÿ”ง Check Docker daemon +docker info + +# ๐ŸŒ Check network +docker network ls | grep tsysdevstack_supportstack + +# ๐Ÿ”„ Recreate network +docker network create tsysdevstack_supportstack +``` + +#### Port conflicts +```bash +# ๐Ÿ” Check port usage +netstat -tulpn | grep :400 + +# ๐Ÿ—‘๏ธ Kill conflicting processes +sudo fuser -k {port}/tcp +``` + +#### Health check failures +```bash +# ๐Ÿ” Check individual service health +docker compose exec {service} curl -f http://localhost:{internal-port}/health + +# ๐Ÿ”„ Restart specific service +docker compose restart {service} +``` + +### ๐Ÿ› ๏ธ Service-Specific Issues + +| Issue | Service | Solution | +|-------|---------|----------| +| **DNS issues** | Pi-hole | Ensure Docker DNS settings allow custom DNS servers
Check that port 53 is available on the host | +| **Database connection** | Grafana-InfluxDB | Verify both services are on the same network
Check database connectivity: `curl http://localhost:4008/ping` | +| **Container access** | Portainer | Ensure container socket is properly mounted
Check Container Socket Proxy service if used | + +--- + +## ๐Ÿ“ Data Management + +### ๐ŸŽญ Demo Mode Configuration + +> ๐Ÿ’ก **No persistent data storage** - All data resets on container restart + +| Feature | Configuration | +|---------|---------------| +| **Data Persistence** | โŒ Disabled (demo mode) | +| **Storage Type** | Docker volumes (temporary) | +| **Data Reset** | โœ… Automatic on restart | +| **Credentials** | ๐Ÿ”’ Hardcoded demo only | + +### ๐Ÿ—‚๏ธ Volume Management + +```bash +# ๐Ÿ“‹ List volumes +docker volume ls | grep tsysdevstack + +# ๐Ÿ—‘๏ธ Clean up all data +docker compose down -v +``` + +--- + +## ๐Ÿ”„ Updates & Maintenance + +### ๐Ÿ“ฆ Image Updates + +
+ +```bash +# ๐Ÿ”„ Pull latest images +docker compose pull + +# ๐Ÿš€ Recreate with new images +docker compose up -d --force-recreate +``` + +
+ +### โš™๏ธ Configuration Changes + +1. **Edit** `docker-compose.yml` +2. **Apply** changes: `docker compose up -d` +3. **Verify** with `docker compose ps` +4. **Test** functionality + +--- + +## ๐Ÿ“š Documentation + +| Document | Purpose | Link | +|----------|---------|------| +| **๐Ÿ“‹ Product Requirements** | Business requirements and specifications | [PRD.md](PRD.md) | +| **๐Ÿค– Development Guidelines** | Development principles and standards | [AGENTS.md](AGENTS.md) | +| **๐ŸŒ Service Documentation** | Individual service guides | Service web interfaces | + +--- + +## ๐Ÿšจ Security Notes + +> โš ๏ธ **Demo Configuration Only - Production Use Prohibited** + +### ๐Ÿ”’ Demo Security Model +- ๐Ÿ”“ **Demo Credentials**: Hardcoded for demonstration only +- ๐Ÿšซ **No Hardening**: No encryption or security features +- ๐ŸŒ **Network Isolation**: Do not expose to external networks +- ๐Ÿ”„ **Ephemeral Data**: All data resets on container restart +- ๐Ÿ“ก **Docker Socket Proxy**: Mandatory for all container operations + +### ๐Ÿ›ก๏ธ Security Requirements +- **Dynamic User Detection**: Prevents root file ownership issues +- **Docker Group Access**: Required for socket proxy functionality +- **Volume-First Storage**: Docker volumes preferred over bind mounts +- **Read-Only Host Access**: Minimal host filesystem interaction +- **Network Segregation**: Services isolated in demo network + +### โš ๏ธ Production Migration Warning +- Reset all credentials before production deployment +- Implement persistent data storage +- Add encryption and security hardening +- Configure proper backup and recovery +- Set up monitoring and alerting + +--- + +## ๐Ÿ“ž Support + +### ๐Ÿ†˜ Getting Help + +1. **๐Ÿ“– Check** troubleshooting section above +2. **๐Ÿ“‹ Review** service logs: `docker compose logs` +3. **๐Ÿ“š Consult** individual service documentation +4. **๐Ÿ” Check** health status: `docker compose ps` + +### ๐Ÿ› Issue Reporting + +When reporting issues, please include: +- ๐Ÿ“ Full error messages +- ๐Ÿ’ป System information +- ๐Ÿ”„ Reproduction steps +- โš™๏ธ Configuration snippets +- ๐ŸŽญ Demo vs production context + +--- + +
+ +**๐ŸŽ‰ Happy Developing!** + +*Last updated: 2025-11-13* + +
\ No newline at end of file diff --git a/demo/config/grafana/dashboards.yml b/demo/config/grafana/dashboards.yml new file mode 100644 index 0000000..57b87a3 --- /dev/null +++ b/demo/config/grafana/dashboards.yml @@ -0,0 +1,14 @@ +--- +# TSYS Developer Support Stack - Grafana Dashboards Configuration +apiVersion: 1 + +providers: + - name: 'default' + orgId: 1 + folder: '' + type: file + disableDeletion: false + updateIntervalSeconds: 10 + allowUiUpdates: true + options: + path: /etc/grafana/provisioning/dashboards diff --git a/demo/config/grafana/datasources.yml b/demo/config/grafana/datasources.yml new file mode 100644 index 0000000..2cac766 --- /dev/null +++ b/demo/config/grafana/datasources.yml @@ -0,0 +1,20 @@ +--- +# TSYS Developer Support Stack - Grafana Datasources Configuration +apiVersion: 1 + +datasources: + - name: InfluxDB + type: influxdb + access: proxy + url: http://influxdb:8086 + database: demo_metrics + user: demo_admin + password: demo_password + isDefault: true + jsonData: + version: Flux + organization: tsysdemo + defaultBucket: demo_metrics + tlsSkipVerify: true + secureJsonData: + token: demo_token_replace_in_production diff --git a/demo/config/homepage/docker.yaml b/demo/config/homepage/docker.yaml new file mode 100644 index 0000000..d4e6f63 --- /dev/null +++ b/demo/config/homepage/docker.yaml @@ -0,0 +1,34 @@ +--- +# TSYS Developer Support Stack - Homepage Configuration +# This file will be automatically generated by Homepage service discovery + +providers: + openweathermap: openweathermapapikey + longshore: longshoreapikey + +widgets: + - resources: + cpu: true + memory: true + disk: true + - search: + provider: duckduckgo + target: _blank + - datetime: + format: + dateStyle: long + timeStyle: short + hour12: true + +bookmarks: + - Development: + - Github: + - abbr: GH + href: https://github.com/ + - Docker Hub: + - abbr: DH + href: https://hub.docker.com/ + - Documentation: + - TSYS Docs: + - abbr: TSYS + href: https://docs.tsys.dev/ diff --git a/demo/demo.env b/demo/demo.env new file mode 100644 index 0000000..0265c45 --- /dev/null +++ b/demo/demo.env @@ -0,0 +1,89 @@ +# TSYS Developer Support Stack - Demo Environment Configuration +# Project Identification +COMPOSE_PROJECT_NAME=tsysdevstack-supportstack-demo +COMPOSE_NETWORK_NAME=tsysdevstack-supportstack-demo-network + +# Dynamic User Detection (to be auto-populated by scripts) +DEMO_UID=1000 +DEMO_GID=1000 +DEMO_DOCKER_GID=996 + +# Port Assignments (4000-4099 range) +HOMEPAGE_PORT=4000 +DOCKER_SOCKET_PROXY_PORT=4005 +PIHOLE_PORT=4006 +PORTAINER_PORT=4007 +INFLUXDB_PORT=4008 +GRAFANA_PORT=4009 +DRAWIO_PORT=4010 +KROKI_PORT=4011 +ATOMIC_TRACKER_PORT=4012 +ARCHIVEBOX_PORT=4013 +TUBE_ARCHIVIST_PORT=4014 +WAKAPI_PORT=4015 +MAILHOG_PORT=4017 +ATUIN_PORT=4018 + +# Demo Credentials (CLEARLY MARKED AS DEMO ONLY) +DEMO_ADMIN_USER=admin +DEMO_ADMIN_PASSWORD=demo_password +DEMO_GRAFANA_ADMIN_PASSWORD=demo_password +DEMO_PORTAINER_PASSWORD=demo_password + +# Network Configuration +NETWORK_SUBNET=192.168.3.0/24 +NETWORK_GATEWAY=192.168.3.1 + +# Resource Limits +MEMORY_LIMIT=512m +CPU_LIMIT=0.25 + +# Health Check Timeouts +HEALTH_CHECK_TIMEOUT=10s +HEALTH_CHECK_INTERVAL=30s +HEALTH_CHECK_RETRIES=3 + +# Docker Socket Proxy Configuration +DOCKER_SOCKET_PROXY_CONTAINERS=1 +DOCKER_SOCKET_PROXY_IMAGES=1 +DOCKER_SOCKET_PROXY_NETWORKS=1 +DOCKER_SOCKET_PROXY_VOLUMES=1 +DOCKER_SOCKET_PROXY_EXEC=0 +DOCKER_SOCKET_PROXY_PRIVILEGED=0 +DOCKER_SOCKET_PROXY_SERVICES=0 +DOCKER_SOCKET_PROXY_TASKS=0 +DOCKER_SOCKET_PROXY_SECRETS=0 +DOCKER_SOCKET_PROXY_CONFIGS=0 +DOCKER_SOCKET_PROXY_PLUGINS=0 + +# InfluxDB Configuration +INFLUXDB_ORG=tsysdemo +INFLUXDB_BUCKET=demo_metrics +INFLUXDB_ADMIN_USER=demo_admin +INFLUXDB_ADMIN_PASSWORD=demo_password +INFLUXDB_AUTH_TOKEN=demo_token_replace_in_production + +# Grafana Configuration +GF_SECURITY_ADMIN_USER=admin +GF_SECURITY_ADMIN_PASSWORD=demo_password +GF_INSTALL_PLUGINS=grafana-clock-panel,grafana-simple-json-datasource + +# Pi-hole Configuration +PIHOLE_WEBPASSWORD=demo_password +WEBTHEME=default-darker + +# ArchiveBox Configuration +ARCHIVEBOX_SECRET_KEY=demo_secret_replace_in_production + +# Tube Archivist Configuration +TA_HOST=tubearchivist +TA_PORT=4014 +TA_DEBUG=false + +# Wakapi Configuration +WAKAPI_PASSWORD_SALT=demo_salt_replace_in_production + +# Atuin Configuration +ATUIN_HOST=atuin +ATUIN_PORT=4018 +ATUIN_OPEN_REGISTRATION=true \ No newline at end of file diff --git a/demo/docker-compose.yml b/demo/docker-compose.yml new file mode 100644 index 0000000..afd0f41 --- /dev/null +++ b/demo/docker-compose.yml @@ -0,0 +1,445 @@ +--- +# TSYS Developer Support Stack - Docker Compose Template +# Version: 1.0 +# Purpose: Demo deployment with dynamic configuration +# โš ๏ธ DEMO CONFIGURATION ONLY - NOT FOR PRODUCTION + +networks: + tsysdevstack-supportstack-demo-network: + driver: bridge + ipam: + config: + - subnet: 192.168.3.0/24 + gateway: 192.168.3.1 + +volumes: + tsysdevstack-supportstack-demo_homepage_data: + driver: local + tsysdevstack-supportstack-demo_pihole_data: + driver: local + tsysdevstack-supportstack-demo_portainer_data: + driver: local + tsysdevstack-supportstack-demo_influxdb_data: + driver: local + tsysdevstack-supportstack-demo_grafana_data: + driver: local + tsysdevstack-supportstack-demo_drawio_data: + driver: local + tsysdevstack-supportstack-demo_kroki_data: + driver: local + tsysdevstack-supportstack-demo_atomictracker_data: + driver: local + tsysdevstack-supportstack-demo_archivebox_data: + driver: local + tsysdevstack-supportstack-demo_tubearchivist_data: + driver: local + tsysdevstack-supportstack-demo_wakapi_data: + driver: local + tsysdevstack-supportstack-demo_mailhog_data: + driver: local + tsysdevstack-supportstack-demo_atuin_data: + driver: local + +services: + # Docker Socket Proxy - Security Layer + docker-socket-proxy: + image: tecnativa/docker-socket-proxy:latest + container_name: "tsysdevstack-supportstack-demo-docker-socket-proxy" + restart: unless-stopped + networks: + - tsysdevstack-supportstack-demo-network + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro + environment: + - CONTAINERS=1 + - IMAGES=1 + - NETWORKS=1 + - VOLUMES=1 + - EXEC=0 + - PRIVILEGED=0 + - SERVICES=0 + - TASKS=0 + - SECRETS=0 + - CONFIGS=0 + - PLUGINS=0 + labels: + homepage.group: "Infrastructure" + homepage.name: "Docker Socket Proxy" + homepage.icon: "docker" + homepage.href: "http://localhost:4005" + homepage.description: "Secure proxy for Docker socket access" + + # Homepage - Central Dashboard + homepage: + image: ghcr.io/gethomepage/homepage:latest + container_name: "tsysdevstack-supportstack-demo-homepage" + restart: unless-stopped + networks: + - tsysdevstack-supportstack-demo-network + ports: + - "4000:3000" + volumes: + - tsysdevstack-supportstack-demo_homepage_data:/app/config + environment: + - PUID=1000 + - PGID=1000 + labels: + homepage.group: "Developer Tools" + homepage.name: "Homepage" + homepage.icon: "homepage" + homepage.href: "http://localhost:4000" + homepage.description: "Central dashboard for service discovery" + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", + "http://localhost:3000"] + interval: 30s + timeout: 10s + retries: 3 + + # Pi-hole - DNS Management + pihole: + image: pihole/pihole:latest + container_name: "tsysdevstack-supportstack-demo-pihole" + restart: unless-stopped + networks: + - tsysdevstack-supportstack-demo-network + ports: + - "4006:80" + - "53:53/tcp" + - "53:53/udp" + volumes: + - tsysdevstack-supportstack-demo_pihole_data:/etc/pihole + environment: + - TZ=UTC + - WEBPASSWORD=demo_password + - WEBTHEME=default-darker + - PUID=1000 + - PGID=1000 + labels: + homepage.group: "Infrastructure" + homepage.name: "Pi-hole" + homepage.icon: "pihole" + homepage.href: "http://localhost:4006" + homepage.description: "DNS management with ad blocking" + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", + "http://localhost/admin"] + interval: 30s + timeout: 10s + retries: 3 + + # Portainer - Container Management + portainer: + image: portainer/portainer-ce:latest + container_name: "tsysdevstack-supportstack-demo-portainer" + restart: unless-stopped + networks: + - tsysdevstack-supportstack-demo-network + ports: + - "4007:9000" + volumes: + - tsysdevstack-supportstack-demo_portainer_data:/data + environment: + - PUID=1000 + - PGID=1000 + labels: + homepage.group: "Infrastructure" + homepage.name: "Portainer" + homepage.icon: "portainer" + homepage.href: "http://localhost:4007" + homepage.description: "Web-based container management" + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", + "http://localhost:9000"] + interval: 30s + timeout: 10s + retries: 3 + + # InfluxDB - Time Series Database + influxdb: + image: influxdb:2.7-alpine + container_name: "tsysdevstack-supportstack-demo-influxdb" + restart: unless-stopped + networks: + - tsysdevstack-supportstack-demo-network + ports: + - "4008:8086" + volumes: + - tsysdevstack-supportstack-demo_influxdb_data:/var/lib/influxdb2 + environment: + - DOCKER_INFLUXDB_INIT_MODE=setup + - DOCKER_INFLUXDB_INIT_USERNAME=demo_admin + - DOCKER_INFLUXDB_INIT_PASSWORD=demo_password + - DOCKER_INFLUXDB_INIT_ORG=tsysdemo + - DOCKER_INFLUXDB_INIT_BUCKET=demo_metrics + - DOCKER_INFLUXDB_INIT_ADMIN_TOKEN=demo_token_replace_in_production + - PUID=1000 + - PGID=1000 + labels: + homepage.group: "Monitoring" + homepage.name: "InfluxDB" + homepage.icon: "influxdb" + homepage.href: "http://localhost:4008" + homepage.description: "Time series database for metrics" + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", + "http://localhost:8086/ping"] + interval: 30s + timeout: 10s + retries: 3 + + # Grafana - Visualization Platform + grafana: + image: grafana/grafana:latest + container_name: "tsysdevstack-supportstack-demo-grafana" + restart: unless-stopped + networks: + - tsysdevstack-supportstack-demo-network + ports: + - "4009:3000" + volumes: + - tsysdevstack-supportstack-demo_grafana_data:/var/lib/grafana + environment: + - GF_SECURITY_ADMIN_USER=admin + - GF_SECURITY_ADMIN_PASSWORD=demo_password + - GF_INSTALL_PLUGINS=grafana-clock-panel,grafana-simple-json-datasource + - PUID=1000 + - PGID=1000 + labels: + homepage.group: "Monitoring" + homepage.name: "Grafana" + homepage.icon: "grafana" + homepage.href: "http://localhost:4009" + homepage.description: "Analytics and visualization platform" + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", + "http://localhost:3000/api/health"] + interval: 30s + timeout: 10s + retries: 3 + + # Draw.io - Diagramming Server + drawio: + image: fjudith/draw.io:latest + container_name: "tsysdevstack-supportstack-demo-drawio" + restart: unless-stopped + networks: + - tsysdevstack-supportstack-demo-network + ports: + - "4010:8080" + volumes: + - tsysdevstack-supportstack-demo_drawio_data:/root + environment: + - PUID=1000 + - PGID=1000 + labels: + homepage.group: "Documentation" + homepage.name: "Draw.io" + homepage.icon: "drawio" + homepage.href: "http://localhost:4010" + homepage.description: "Web-based diagramming application" + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", + "http://localhost:8080"] + interval: 30s + timeout: 10s + retries: 3 + + # Kroki - Diagrams as a Service + kroki: + image: yuzutech/kroki:latest + container_name: "tsysdevstack-supportstack-demo-kroki" + restart: unless-stopped + networks: + - tsysdevstack-supportstack-demo-network + ports: + - "4011:8000" + volumes: + - tsysdevstack-supportstack-demo_kroki_data:/data + environment: + - KROKI_SAFE_MODE=secure + - PUID=1000 + - PGID=1000 + labels: + homepage.group: "Documentation" + homepage.name: "Kroki" + homepage.icon: "kroki" + homepage.href: "http://localhost:4011" + homepage.description: "Diagrams as a service" + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", + "http://localhost:8000/health"] + interval: 30s + timeout: 10s + retries: 3 + + # Atomic Tracker - Habit Tracking + atomictracker: + image: ghcr.io/majorpeter/atomic-tracker:v1.3.1 + container_name: "tsysdevstack-supportstack-demo-atomictracker" + restart: unless-stopped + networks: + - tsysdevstack-supportstack-demo-network + ports: + - "4012:3000" + volumes: + - tsysdevstack-supportstack-demo_atomictracker_data:/app/data + environment: + - NODE_ENV=production + - PUID=1000 + - PGID=1000 + labels: + homepage.group: "Developer Tools" + homepage.name: "Atomic Tracker" + homepage.icon: "atomic-tracker" + homepage.href: "http://localhost:4012" + homepage.description: "Habit tracking and personal dashboard" + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", + "http://localhost:3000"] + interval: 30s + timeout: 10s + retries: 3 + + # ArchiveBox - Web Archiving + archivebox: + image: archivebox/archivebox:latest + container_name: "tsysdevstack-supportstack-demo-archivebox" + restart: unless-stopped + networks: + - tsysdevstack-supportstack-demo-network + ports: + - "4013:8000" + volumes: + - tsysdevstack-supportstack-demo_archivebox_data:/data + environment: + - SECRET_KEY=demo_secret_replace_in_production + - PUID=1000 + - PGID=1000 + labels: + homepage.group: "Developer Tools" + homepage.name: "ArchiveBox" + homepage.icon: "archivebox" + homepage.href: "http://localhost:4013" + homepage.description: "Web archiving solution" + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", + "http://localhost:8000"] + interval: 30s + timeout: 10s + retries: 3 + + # Tube Archivist - YouTube Archiving + tubearchivist: + image: bbilly1/tubearchivist:latest + container_name: "tsysdevstack-supportstack-demo-tubearchivist" + restart: unless-stopped + networks: + - tsysdevstack-supportstack-demo-network + ports: + - "4014:8000" + volumes: + - tsysdevstack-supportstack-demo_tubearchivist_data:/cache + environment: + - TA_HOST=tubearchivist + - TA_PORT=4014 + - TA_DEBUG=false + - PUID=1000 + - PGID=1000 + labels: + homepage.group: "Developer Tools" + homepage.name: "Tube Archivist" + homepage.icon: "tube-archivist" + homepage.href: "http://localhost:4014" + homepage.description: "YouTube video archiving" + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", + "http://localhost:8000"] + interval: 30s + timeout: 10s + retries: 3 + + # Wakapi - Time Tracking + wakapi: + image: ghcr.io/muety/wakapi:latest + container_name: "tsysdevstack-supportstack-demo-wakapi" + restart: unless-stopped + networks: + - tsysdevstack-supportstack-demo-network + ports: + - "4015:3000" + volumes: + - tsysdevstack-supportstack-demo_wakapi_data:/data + environment: + - WAKAPI_PASSWORD_SALT=demo_salt_replace_in_production + - PUID=1000 + - PGID=1000 + labels: + homepage.group: "Developer Tools" + homepage.name: "Wakapi" + homepage.icon: "wakapi" + homepage.href: "http://localhost:4015" + homepage.description: "Open-source WakaTime alternative" + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", + "http://localhost:3000"] + interval: 30s + timeout: 10s + retries: 3 + + # MailHog - Email Testing + mailhog: + image: mailhog/mailhog:latest + container_name: "tsysdevstack-supportstack-demo-mailhog" + restart: unless-stopped + networks: + - tsysdevstack-supportstack-demo-network + ports: + - "4017:8025" + volumes: + - tsysdevstack-supportstack-demo_mailhog_data:/maildir + environment: + - PUID=1000 + - PGID=1000 + labels: + homepage.group: "Developer Tools" + homepage.name: "MailHog" + homepage.icon: "mailhog" + homepage.href: "http://localhost:4017" + homepage.description: "Web and API based SMTP testing" + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", + "http://localhost:8025"] + interval: 30s + timeout: 10s + retries: 3 + + # Atuin - Shell History + atuin: + image: ghcr.io/atuinsh/atuin:v18.10.0 + container_name: "tsysdevstack-supportstack-demo-atuin" + restart: unless-stopped + networks: + - tsysdevstack-supportstack-demo-network + ports: + - "4018:8888" + volumes: + - tsysdevstack-supportstack-demo_atuin_data:/config + environment: + - ATUIN_HOST=atuin + - ATUIN_PORT=4018 + - ATUIN_OPEN_REGISTRATION=true + - PUID=1000 + - PGID=1000 + labels: + homepage.group: "Developer Tools" + homepage.name: "Atuin" + homepage.icon: "atuin" + homepage.href: "http://localhost:4018" + homepage.description: "Magical shell history synchronization" + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", + "http://localhost:8888"] + interval: 30s + timeout: 10s + retries: 3 diff --git a/demo/docker-compose.yml.template b/demo/docker-compose.yml.template new file mode 100644 index 0000000..5a6c565 --- /dev/null +++ b/demo/docker-compose.yml.template @@ -0,0 +1,445 @@ +--- +# TSYS Developer Support Stack - Docker Compose Template +# Version: 1.0 +# Purpose: Demo deployment with dynamic configuration +# โš ๏ธ DEMO CONFIGURATION ONLY - NOT FOR PRODUCTION + +networks: + ${COMPOSE_NETWORK_NAME}: + driver: bridge + ipam: + config: + - subnet: ${NETWORK_SUBNET} + gateway: ${NETWORK_GATEWAY} + +volumes: + ${COMPOSE_PROJECT_NAME}_homepage_data: + driver: local + ${COMPOSE_PROJECT_NAME}_pihole_data: + driver: local + ${COMPOSE_PROJECT_NAME}_portainer_data: + driver: local + ${COMPOSE_PROJECT_NAME}_influxdb_data: + driver: local + ${COMPOSE_PROJECT_NAME}_grafana_data: + driver: local + ${COMPOSE_PROJECT_NAME}_drawio_data: + driver: local + ${COMPOSE_PROJECT_NAME}_kroki_data: + driver: local + ${COMPOSE_PROJECT_NAME}_atomictracker_data: + driver: local + ${COMPOSE_PROJECT_NAME}_archivebox_data: + driver: local + ${COMPOSE_PROJECT_NAME}_tubearchivist_data: + driver: local + ${COMPOSE_PROJECT_NAME}_wakapi_data: + driver: local + ${COMPOSE_PROJECT_NAME}_mailhog_data: + driver: local + ${COMPOSE_PROJECT_NAME}_atuin_data: + driver: local + +services: + # Docker Socket Proxy - Security Layer + docker-socket-proxy: + image: tecnativa/docker-socket-proxy:latest + container_name: "${COMPOSE_PROJECT_NAME}-docker-socket-proxy" + restart: unless-stopped + networks: + - ${COMPOSE_NETWORK_NAME} + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro + environment: + - CONTAINERS=${DOCKER_SOCKET_PROXY_CONTAINERS} + - IMAGES=${DOCKER_SOCKET_PROXY_IMAGES} + - NETWORKS=${DOCKER_SOCKET_PROXY_NETWORKS} + - VOLUMES=${DOCKER_SOCKET_PROXY_VOLUMES} + - EXEC=${DOCKER_SOCKET_PROXY_EXEC} + - PRIVILEGED=${DOCKER_SOCKET_PROXY_PRIVILEGED} + - SERVICES=${DOCKER_SOCKET_PROXY_SERVICES} + - TASKS=${DOCKER_SOCKET_PROXY_TASKS} + - SECRETS=${DOCKER_SOCKET_PROXY_SECRETS} + - CONFIGS=${DOCKER_SOCKET_PROXY_CONFIGS} + - PLUGINS=${DOCKER_SOCKET_PROXY_PLUGINS} + labels: + homepage.group: "Infrastructure" + homepage.name: "Docker Socket Proxy" + homepage.icon: "docker" + homepage.href: "http://localhost:${DOCKER_SOCKET_PROXY_PORT}" + homepage.description: "Secure proxy for Docker socket access" + + # Homepage - Central Dashboard + homepage: + image: ghcr.io/gethomepage/homepage:latest + container_name: "${COMPOSE_PROJECT_NAME}-homepage" + restart: unless-stopped + networks: + - ${COMPOSE_NETWORK_NAME} + ports: + - "${HOMEPAGE_PORT}:3000" + volumes: + - ${COMPOSE_PROJECT_NAME}_homepage_data:/app/config + environment: + - PUID=${DEMO_UID} + - PGID=${DEMO_GID} + labels: + homepage.group: "Developer Tools" + homepage.name: "Homepage" + homepage.icon: "homepage" + homepage.href: "http://localhost:${HOMEPAGE_PORT}" + homepage.description: "Central dashboard for service discovery" + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", + "http://localhost:3000"] + interval: ${HEALTH_CHECK_INTERVAL} + timeout: ${HEALTH_CHECK_TIMEOUT} + retries: ${HEALTH_CHECK_RETRIES} + + # Pi-hole - DNS Management + pihole: + image: pihole/pihole:latest + container_name: "${COMPOSE_PROJECT_NAME}-pihole" + restart: unless-stopped + networks: + - ${COMPOSE_NETWORK_NAME} + ports: + - "${PIHOLE_PORT}:80" + - "53:53/tcp" + - "53:53/udp" + volumes: + - ${COMPOSE_PROJECT_NAME}_pihole_data:/etc/pihole + environment: + - TZ=UTC + - WEBPASSWORD=${PIHOLE_WEBPASSWORD} + - WEBTHEME=${WEBTHEME} + - PUID=${DEMO_UID} + - PGID=${DEMO_GID} + labels: + homepage.group: "Infrastructure" + homepage.name: "Pi-hole" + homepage.icon: "pihole" + homepage.href: "http://localhost:${PIHOLE_PORT}" + homepage.description: "DNS management with ad blocking" + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", + "http://localhost/admin"] + interval: ${HEALTH_CHECK_INTERVAL} + timeout: ${HEALTH_CHECK_TIMEOUT} + retries: ${HEALTH_CHECK_RETRIES} + + # Portainer - Container Management + portainer: + image: portainer/portainer-ce:latest + container_name: "${COMPOSE_PROJECT_NAME}-portainer" + restart: unless-stopped + networks: + - ${COMPOSE_NETWORK_NAME} + ports: + - "${PORTAINER_PORT}:9000" + volumes: + - ${COMPOSE_PROJECT_NAME}_portainer_data:/data + environment: + - PUID=${DEMO_UID} + - PGID=${DEMO_GID} + labels: + homepage.group: "Infrastructure" + homepage.name: "Portainer" + homepage.icon: "portainer" + homepage.href: "http://localhost:${PORTAINER_PORT}" + homepage.description: "Web-based container management" + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", + "http://localhost:9000"] + interval: ${HEALTH_CHECK_INTERVAL} + timeout: ${HEALTH_CHECK_TIMEOUT} + retries: ${HEALTH_CHECK_RETRIES} + + # InfluxDB - Time Series Database + influxdb: + image: influxdb:2.7-alpine + container_name: "${COMPOSE_PROJECT_NAME}-influxdb" + restart: unless-stopped + networks: + - ${COMPOSE_NETWORK_NAME} + ports: + - "${INFLUXDB_PORT}:8086" + volumes: + - ${COMPOSE_PROJECT_NAME}_influxdb_data:/var/lib/influxdb2 + environment: + - DOCKER_INFLUXDB_INIT_MODE=setup + - DOCKER_INFLUXDB_INIT_USERNAME=${INFLUXDB_ADMIN_USER} + - DOCKER_INFLUXDB_INIT_PASSWORD=${INFLUXDB_ADMIN_PASSWORD} + - DOCKER_INFLUXDB_INIT_ORG=${INFLUXDB_ORG} + - DOCKER_INFLUXDB_INIT_BUCKET=${INFLUXDB_BUCKET} + - DOCKER_INFLUXDB_INIT_ADMIN_TOKEN=${INFLUXDB_AUTH_TOKEN} + - PUID=${DEMO_UID} + - PGID=${DEMO_GID} + labels: + homepage.group: "Monitoring" + homepage.name: "InfluxDB" + homepage.icon: "influxdb" + homepage.href: "http://localhost:${INFLUXDB_PORT}" + homepage.description: "Time series database for metrics" + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", + "http://localhost:8086/ping"] + interval: ${HEALTH_CHECK_INTERVAL} + timeout: ${HEALTH_CHECK_TIMEOUT} + retries: ${HEALTH_CHECK_RETRIES} + + # Grafana - Visualization Platform + grafana: + image: grafana/grafana:latest + container_name: "${COMPOSE_PROJECT_NAME}-grafana" + restart: unless-stopped + networks: + - ${COMPOSE_NETWORK_NAME} + ports: + - "${GRAFANA_PORT}:3000" + volumes: + - ${COMPOSE_PROJECT_NAME}_grafana_data:/var/lib/grafana + environment: + - GF_SECURITY_ADMIN_USER=${GF_SECURITY_ADMIN_USER} + - GF_SECURITY_ADMIN_PASSWORD=${GF_SECURITY_ADMIN_PASSWORD} + - GF_INSTALL_PLUGINS=${GF_INSTALL_PLUGINS} + - PUID=${DEMO_UID} + - PGID=${DEMO_GID} + labels: + homepage.group: "Monitoring" + homepage.name: "Grafana" + homepage.icon: "grafana" + homepage.href: "http://localhost:${GRAFANA_PORT}" + homepage.description: "Analytics and visualization platform" + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", + "http://localhost:3000/api/health"] + interval: ${HEALTH_CHECK_INTERVAL} + timeout: ${HEALTH_CHECK_TIMEOUT} + retries: ${HEALTH_CHECK_RETRIES} + + # Draw.io - Diagramming Server + drawio: + image: fjudith/draw.io:latest + container_name: "${COMPOSE_PROJECT_NAME}-drawio" + restart: unless-stopped + networks: + - ${COMPOSE_NETWORK_NAME} + ports: + - "${DRAWIO_PORT}:8080" + volumes: + - ${COMPOSE_PROJECT_NAME}_drawio_data:/root + environment: + - PUID=${DEMO_UID} + - PGID=${DEMO_GID} + labels: + homepage.group: "Documentation" + homepage.name: "Draw.io" + homepage.icon: "drawio" + homepage.href: "http://localhost:${DRAWIO_PORT}" + homepage.description: "Web-based diagramming application" + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", + "http://localhost:8080"] + interval: ${HEALTH_CHECK_INTERVAL} + timeout: ${HEALTH_CHECK_TIMEOUT} + retries: ${HEALTH_CHECK_RETRIES} + + # Kroki - Diagrams as a Service + kroki: + image: yuzutech/kroki:latest + container_name: "${COMPOSE_PROJECT_NAME}-kroki" + restart: unless-stopped + networks: + - ${COMPOSE_NETWORK_NAME} + ports: + - "${KROKI_PORT}:8000" + volumes: + - ${COMPOSE_PROJECT_NAME}_kroki_data:/data + environment: + - KROKI_SAFE_MODE=secure + - PUID=${DEMO_UID} + - PGID=${DEMO_GID} + labels: + homepage.group: "Documentation" + homepage.name: "Kroki" + homepage.icon: "kroki" + homepage.href: "http://localhost:${KROKI_PORT}" + homepage.description: "Diagrams as a service" + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", + "http://localhost:8000/health"] + interval: ${HEALTH_CHECK_INTERVAL} + timeout: ${HEALTH_CHECK_TIMEOUT} + retries: ${HEALTH_CHECK_RETRIES} + + # Atomic Tracker - Habit Tracking + atomictracker: + image: ghcr.io/majorpeter/atomic-tracker:v1.3.1 + container_name: "${COMPOSE_PROJECT_NAME}-atomictracker" + restart: unless-stopped + networks: + - ${COMPOSE_NETWORK_NAME} + ports: + - "${ATOMIC_TRACKER_PORT}:3000" + volumes: + - ${COMPOSE_PROJECT_NAME}_atomictracker_data:/app/data + environment: + - NODE_ENV=production + - PUID=${DEMO_UID} + - PGID=${DEMO_GID} + labels: + homepage.group: "Developer Tools" + homepage.name: "Atomic Tracker" + homepage.icon: "atomic-tracker" + homepage.href: "http://localhost:${ATOMIC_TRACKER_PORT}" + homepage.description: "Habit tracking and personal dashboard" + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", + "http://localhost:3000"] + interval: ${HEALTH_CHECK_INTERVAL} + timeout: ${HEALTH_CHECK_TIMEOUT} + retries: ${HEALTH_CHECK_RETRIES} + + # ArchiveBox - Web Archiving + archivebox: + image: archivebox/archivebox:latest + container_name: "${COMPOSE_PROJECT_NAME}-archivebox" + restart: unless-stopped + networks: + - ${COMPOSE_NETWORK_NAME} + ports: + - "${ARCHIVEBOX_PORT}:8000" + volumes: + - ${COMPOSE_PROJECT_NAME}_archivebox_data:/data + environment: + - SECRET_KEY=${ARCHIVEBOX_SECRET_KEY} + - PUID=${DEMO_UID} + - PGID=${DEMO_GID} + labels: + homepage.group: "Developer Tools" + homepage.name: "ArchiveBox" + homepage.icon: "archivebox" + homepage.href: "http://localhost:${ARCHIVEBOX_PORT}" + homepage.description: "Web archiving solution" + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", + "http://localhost:8000"] + interval: ${HEALTH_CHECK_INTERVAL} + timeout: ${HEALTH_CHECK_TIMEOUT} + retries: ${HEALTH_CHECK_RETRIES} + + # Tube Archivist - YouTube Archiving + tubearchivist: + image: bbilly1/tubearchivist:latest + container_name: "${COMPOSE_PROJECT_NAME}-tubearchivist" + restart: unless-stopped + networks: + - ${COMPOSE_NETWORK_NAME} + ports: + - "${TUBE_ARCHIVIST_PORT}:8000" + volumes: + - ${COMPOSE_PROJECT_NAME}_tubearchivist_data:/cache + environment: + - TA_HOST=${TA_HOST} + - TA_PORT=${TA_PORT} + - TA_DEBUG=${TA_DEBUG} + - PUID=${DEMO_UID} + - PGID=${DEMO_GID} + labels: + homepage.group: "Developer Tools" + homepage.name: "Tube Archivist" + homepage.icon: "tube-archivist" + homepage.href: "http://localhost:${TUBE_ARCHIVIST_PORT}" + homepage.description: "YouTube video archiving" + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", + "http://localhost:8000"] + interval: ${HEALTH_CHECK_INTERVAL} + timeout: ${HEALTH_CHECK_TIMEOUT} + retries: ${HEALTH_CHECK_RETRIES} + + # Wakapi - Time Tracking + wakapi: + image: ghcr.io/muety/wakapi:latest + container_name: "${COMPOSE_PROJECT_NAME}-wakapi" + restart: unless-stopped + networks: + - ${COMPOSE_NETWORK_NAME} + ports: + - "${WAKAPI_PORT}:3000" + volumes: + - ${COMPOSE_PROJECT_NAME}_wakapi_data:/data + environment: + - WAKAPI_PASSWORD_SALT=${WAKAPI_PASSWORD_SALT} + - PUID=${DEMO_UID} + - PGID=${DEMO_GID} + labels: + homepage.group: "Developer Tools" + homepage.name: "Wakapi" + homepage.icon: "wakapi" + homepage.href: "http://localhost:${WAKAPI_PORT}" + homepage.description: "Open-source WakaTime alternative" + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", + "http://localhost:3000"] + interval: ${HEALTH_CHECK_INTERVAL} + timeout: ${HEALTH_CHECK_TIMEOUT} + retries: ${HEALTH_CHECK_RETRIES} + + # MailHog - Email Testing + mailhog: + image: mailhog/mailhog:latest + container_name: "${COMPOSE_PROJECT_NAME}-mailhog" + restart: unless-stopped + networks: + - ${COMPOSE_NETWORK_NAME} + ports: + - "${MAILHOG_PORT}:8025" + volumes: + - ${COMPOSE_PROJECT_NAME}_mailhog_data:/maildir + environment: + - PUID=${DEMO_UID} + - PGID=${DEMO_GID} + labels: + homepage.group: "Developer Tools" + homepage.name: "MailHog" + homepage.icon: "mailhog" + homepage.href: "http://localhost:${MAILHOG_PORT}" + homepage.description: "Web and API based SMTP testing" + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", + "http://localhost:8025"] + interval: ${HEALTH_CHECK_INTERVAL} + timeout: ${HEALTH_CHECK_TIMEOUT} + retries: ${HEALTH_CHECK_RETRIES} + + # Atuin - Shell History + atuin: + image: ghcr.io/atuinsh/atuin:v18.10.0 + container_name: "${COMPOSE_PROJECT_NAME}-atuin" + restart: unless-stopped + networks: + - ${COMPOSE_NETWORK_NAME} + ports: + - "${ATUIN_PORT}:8888" + volumes: + - ${COMPOSE_PROJECT_NAME}_atuin_data:/config + environment: + - ATUIN_HOST=${ATUIN_HOST} + - ATUIN_PORT=${ATUIN_PORT} + - ATUIN_OPEN_REGISTRATION=${ATUIN_OPEN_REGISTRATION} + - PUID=${DEMO_UID} + - PGID=${DEMO_GID} + labels: + homepage.group: "Developer Tools" + homepage.name: "Atuin" + homepage.icon: "atuin" + homepage.href: "http://localhost:${ATUIN_PORT}" + homepage.description: "Magical shell history synchronization" + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", + "http://localhost:8888"] + interval: ${HEALTH_CHECK_INTERVAL} + timeout: ${HEALTH_CHECK_TIMEOUT} + retries: ${HEALTH_CHECK_RETRIES} diff --git a/demo/docs/api-docs/README.md b/demo/docs/api-docs/README.md new file mode 100644 index 0000000..382aa92 --- /dev/null +++ b/demo/docs/api-docs/README.md @@ -0,0 +1,285 @@ +# TSYS Developer Support Stack - API Documentation + +## Service APIs Overview + +This document provides API endpoint information for all services in the stack. + +## Infrastructure Services APIs + +### Docker Socket Proxy +- **Base URL**: `http://localhost:4005` +- **API Version**: Docker Engine API +- **Authentication**: None (restricted by proxy) +- **Endpoints**: + - `GET /version` - Docker version information + - `GET /info` - System information + - `GET /containers/json` - List containers + - `GET /images/json` - List images + +### Pi-hole +- **Base URL**: `http://localhost:4006/admin` +- **API Version**: v1 +- **Authentication**: Basic auth (demo_password) +- **Endpoints**: + - `GET /admin/api.php` - Statistics and status + - `GET /admin/api.php?list` - Blocked domains list + - `GET /admin/api.php?summaryRaw` - Raw statistics + +### Portainer +- **Base URL**: `http://localhost:4007` +- **API Version**: v2 +- **Authentication**: Bearer token +- **Endpoints**: + - `POST /api/auth` - Authentication + - `GET /api/endpoints` - List endpoints + - `GET /api/containers` - List containers + - `GET /api/images` - List images + +## Monitoring & Observability APIs + +### InfluxDB +- **Base URL**: `http://localhost:4008` +- **API Version**: v2 +- **Authentication**: Token-based +- **Endpoints**: + - `GET /ping` - Health check + - `POST /api/v2/write` - Write data + - `GET /api/v2/query` - Query data + - `GET /api/health` - Health status + +### Grafana +- **Base URL**: `http://localhost:4009` +- **API Version**: v1 +- **Authentication**: API key or Basic auth +- **Endpoints**: + - `GET /api/health` - Health check + - `GET /api/dashboards` - List dashboards + - `GET /api/datasources` - List data sources + - `POST /api/login` - Authentication + +## Documentation & Diagramming APIs + +### Draw.io +- **Base URL**: `http://localhost:4010` +- **API Version**: None (web interface) +- **Authentication**: None +- **Endpoints**: + - `GET /` - Main interface + - `POST /export` - Export diagram + - `GET /images` - Image library + +### Kroki +- **Base URL**: `http://localhost:4011` +- **API Version**: v1 +- **Authentication**: None +- **Endpoints**: + - `GET /health` - Health check + - `POST /plantuml/svg` - PlantUML to SVG + - `POST /mermaid/svg` - Mermaid to SVG + - `POST /graphviz/svg` - GraphViz to SVG + +## Developer Tools APIs + +### Homepage +- **Base URL**: `http://localhost:4000` +- **API Version**: None (web interface) +- **Authentication**: None +- **Endpoints**: + - `GET /` - Main dashboard + - `GET /widgets` - Widget data + - `GET /bookmarks` - Bookmark data + +### Atomic Tracker +- **Base URL**: `http://localhost:4012` +- **API Version**: v1 +- **Authentication**: Required +- **Endpoints**: + - `GET /api/habits` - List habits + - `POST /api/habits` - Create habit + - `PUT /api/habits/:id` - Update habit + - `DELETE /api/habits/:id` - Delete habit + +### ArchiveBox +- **Base URL**: `http://localhost:4013` +- **API Version**: v1 +- **Authentication**: Required +- **Endpoints**: + - `GET /api/v1/core/health` - Health check + - `POST /api/v1/core/add` - Add URL + - `GET /api/v1/snapshots` - List snapshots + - `GET /api/v1/snapshots/:id` - Get snapshot + +### Tube Archivist +- **Base URL**: `http://localhost:4014` +- **API Version**: v1 +- **Authentication**: Required +- **Endpoints**: + - `GET /api/health` - Health check + - `POST /api/subscribe` - Subscribe to channel + - `GET /api/video/:id` - Get video info + - `GET /api/search` - Search videos + +### Wakapi +- **Base URL**: `http://localhost:4015` +- **API Version**: v1 +- **Authentication**: API key +- **Endpoints**: + - `GET /api/health` - Heartbeat + - `GET /api/summary` - Time summary + - `GET /api/durations` - Heartbeats + - `POST /api/heartbeats` - Add heartbeat + +### MailHog +- **Base URL**: `http://localhost:4017` +- **API Version**: v1 +- **Authentication**: None +- **Endpoints**: + - `GET /api/v1/messages` - List messages + - `GET /api/v1/messages/:id` - Get message + - `DELETE /api/v1/messages` - Delete all + - `POST /api/v1/messages` - Create message + +### Atuin +- **Base URL**: `http://localhost:4018` +- **API Version**: v1 +- **Authentication**: Required +- **Endpoints**: + - `GET /api/health` - Health check + - `POST /api/sync` - Sync history + - `GET /api/history` - Get history + - `POST /api/history` - Add history + +## API Usage Examples + +### Docker Socket Proxy Example +```bash +# Get Docker version +curl http://localhost:4005/version + +# List containers +curl http://localhost:4005/containers/json +``` + +### InfluxDB Example +```bash +# Write data +curl -X POST http://localhost:4008/api/v2/write \ + -H "Authorization: Token demo_token_replace_in_production" \ + -H "Content-Type: text/plain" \ + --data-binary "measurement,field=value" + +# Query data +curl -G http://localhost:4008/api/v2/query \ + -H "Authorization: Token demo_token_replace_in_production" \ + --data-urlencode "query=from(bucket:\"demo_metrics\") |> range(start: -1h)" +``` + +### Grafana Example +```bash +# Get dashboards +curl -u admin:demo_password http://localhost:4009/api/dashboards + +# Create API key +curl -X POST -u admin:demo_password \ + http://localhost:4009/api/auth/keys \ + -H "Content-Type: application/json" \ + -d '{"name":"demo","role":"Admin"}' +``` + +### Kroki Example +```bash +# Convert PlantUML to SVG +curl -X POST http://localhost:4011/plantuml/svg \ + -H "Content-Type: text/plain" \ + -d "@startuml + Alice -> Bob: Hello + @enduml" +``` + +## Authentication + +### Demo Credentials +- **Username**: `admin` +- **Password**: `demo_password` +- **API Keys**: Use demo tokens provided in configuration + +### Token-based Authentication +```bash +# InfluxDB token +export INFLUX_TOKEN="demo_token_replace_in_production" + +# Grafana API key +export GRAFANA_API_KEY="demo_api_key" + +# Wakapi API key +export WAKAPI_API_KEY="demo_wakapi_key" +``` + +## Rate Limiting + +Most services have no rate limiting in demo mode. In production: +- Configure appropriate rate limits +- Implement authentication +- Set up monitoring +- Use reverse proxy for additional security + +## Error Handling + +### Common HTTP Status Codes +- `200` - Success +- `401` - Authentication required +- `403` - Forbidden +- `404` - Not found +- `500` - Internal server error + +### Error Response Format +```json +{ + "error": "Error message", + "code": "ERROR_CODE", + "details": "Additional details" +} +``` + +## Health Checks + +All services provide health check endpoints: +- `GET /health` - Standard health check +- `GET /ping` - Simple ping response +- `GET /api/health` - API-specific health + +## Development Notes + +### Testing APIs +```bash +# Test all health endpoints +for port in 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4017 4018; do + echo "Testing port $port..." + curl -f -s "http://localhost:$port/health" || \ + curl -f -s "http://localhost:$port/ping" || \ + curl -f -s "http://localhost:$port/api/health" || \ + echo "Health check failed for port $port" +done +``` + +### Monitoring API Usage +- Use Grafana dashboards to monitor API calls +- Check service logs for API errors +- Monitor resource usage with Docker stats +- Set up alerts for API failures + +## Security Considerations + +### Demo Mode +- All APIs are accessible without authentication +- No rate limiting implemented +- No HTTPS encryption +- Default demo credentials + +### Production Migration +- Implement proper authentication +- Add rate limiting +- Use HTTPS/TLS +- Set up API gateway +- Implement audit logging +- Configure CORS policies \ No newline at end of file diff --git a/demo/docs/service-guides/README.md b/demo/docs/service-guides/README.md new file mode 100644 index 0000000..19fb688 --- /dev/null +++ b/demo/docs/service-guides/README.md @@ -0,0 +1,55 @@ +# TSYS Developer Support Stack - Service Guides + +This directory contains detailed guides for each service in the stack. + +## Available Guides + +- [Homepage Dashboard](homepage.md) +- [Infrastructure Services](infrastructure.md) +- [Monitoring & Observability](monitoring.md) +- [Documentation & Diagramming](documentation.md) +- [Developer Tools](developer-tools.md) + +## Quick Access + +All services are accessible through the Homepage dashboard at http://localhost:4000 + +## Service Categories + +### ๐Ÿ—๏ธ Infrastructure Services +- **Pi-hole** (Port 4006): DNS management with ad blocking +- **Portainer** (Port 4007): Web-based container management +- **Docker Socket Proxy** (Port 4005): Secure Docker socket access + +### ๐Ÿ“Š Monitoring & Observability +- **InfluxDB** (Port 4008): Time series database for metrics +- **Grafana** (Port 4009): Analytics and visualization platform + +### ๐Ÿ“š Documentation & Diagramming +- **Draw.io** (Port 4010): Web-based diagramming application +- **Kroki** (Port 4011): Diagrams as a service + +### ๐Ÿ› ๏ธ Developer Tools +- **Homepage** (Port 4000): Central dashboard for service discovery +- **Atomic Tracker** (Port 4012): Habit tracking and personal dashboard +- **ArchiveBox** (Port 4013): Web archiving solution +- **Tube Archivist** (Port 4014): YouTube video archiving +- **Wakapi** (Port 4015): Open-source WakaTime alternative +- **MailHog** (Port 4017): Web and API based SMTP testing +- **Atuin** (Port 4018): Magical shell history synchronization + +## Demo Credentials + +โš ๏ธ **FOR DEMONSTRATION PURPOSES ONLY** + +- **Username**: `admin` +- **Password**: `demo_password` + +These credentials work for Grafana and Portainer. Other services may have different authentication requirements. + +## Getting Help + +1. Check the individual service guides below +2. Review the [troubleshooting guide](../troubleshooting/README.md) +3. Check service logs: `docker compose logs [service-name]` +4. Verify service status: `docker compose ps` \ No newline at end of file diff --git a/demo/docs/troubleshooting/README.md b/demo/docs/troubleshooting/README.md new file mode 100644 index 0000000..bfca380 --- /dev/null +++ b/demo/docs/troubleshooting/README.md @@ -0,0 +1,291 @@ +# TSYS Developer Support Stack - Troubleshooting Guide + +## Common Issues and Solutions + +### Services Not Starting + +#### Issue: Docker daemon not running +**Symptoms**: `Cannot connect to the Docker daemon` +**Solution**: +```bash +sudo systemctl start docker +sudo systemctl enable docker +``` + +#### Issue: Port conflicts +**Symptoms**: `Port already in use` errors +**Solution**: +```bash +# Check what's using the port +netstat -tulpn | grep :4000 + +# Kill conflicting process +sudo fuser -k 4000/tcp +``` + +#### Issue: Environment variables not set +**Symptoms**: `Variable not found` errors +**Solution**: +```bash +# Check demo.env exists and is populated +cat demo.env + +# Re-run user detection +./scripts/demo-stack.sh deploy +``` + +### Health Check Failures + +#### Issue: Services stuck in "starting" state +**Symptoms**: Health checks timeout +**Solution**: +```bash +# Check service logs +docker compose logs [service-name] + +# Restart specific service +docker compose restart [service-name] + +# Check resource usage +docker stats +``` + +#### Issue: Network connectivity problems +**Symptoms**: Services can't reach each other +**Solution**: +```bash +# Check network exists +docker network ls | grep tsysdevstack + +# Recreate network +docker network create tsysdevstack_supportstack-demo + +# Restart stack +docker compose down && docker compose up -d +``` + +### Permission Issues + +#### Issue: File ownership problems +**Symptoms**: `Permission denied` errors +**Solution**: +```bash +# Check current user +id + +# Verify UID/GID detection +cat demo.env | grep -E "(UID|GID)" + +# Fix volume permissions +sudo chown -R $(id -u):$(id -g) /var/lib/docker/volumes/tsysdevstack_* +``` + +#### Issue: Docker group access +**Symptoms**: `Got permission denied` errors +**Solution**: +```bash +# Add user to docker group +sudo usermod -aG docker $USER + +# Log out and back in, or run: +newgrp docker +``` + +### Service-Specific Issues + +#### Pi-hole DNS Issues +**Symptoms**: DNS resolution failures +**Solution**: +```bash +# Check Pi-hole status +docker exec tsysdevstack-supportstack-demo-pihole pihole status + +# Test DNS resolution +nslookup google.com localhost + +# Restart DNS service +docker exec tsysdevstack-supportstack-demo-pihole pihole restartdns +``` + +#### Grafana Data Source Connection +**Symptoms**: InfluxDB data source not working +**Solution**: +```bash +# Test InfluxDB connectivity +curl http://localhost:4008/ping + +# Check Grafana logs +docker compose logs grafana + +# Verify data source configuration +# Navigate to: http://localhost:4009/datasources +``` + +#### Portainer Container Access +**Symptoms**: Can't manage containers +**Solution**: +```bash +# Check Docker socket proxy +docker compose logs docker-socket-proxy + +# Verify proxy permissions +curl http://localhost:4005/version + +# Restart Portainer +docker compose restart portainer +``` + +### Performance Issues + +#### Issue: High memory usage +**Symptoms**: System becomes slow +**Solution**: +```bash +# Check resource usage +docker stats + +# Set memory limits in docker-compose.yml +# Add to each service: +deploy: + resources: + limits: + memory: 512M + +# Restart with new limits +docker compose up -d +``` + +#### Issue: Slow startup times +**Symptoms**: Services take >60 seconds to start +**Solution**: +```bash +# Check system resources +free -h +df -h + +# Pull images in advance +docker compose pull + +# Check for conflicting services +docker ps -a +``` + +## Diagnostic Commands + +### System Information +```bash +# System info +uname -a +free -h +df -h + +# Docker info +docker version +docker compose version +docker system df +``` + +### Service Status +```bash +# All services status +docker compose ps + +# Service logs +docker compose logs + +# Resource usage +docker stats + +# Network info +docker network ls +docker network inspect tsysdevstack_supportstack-demo +``` + +### Health Checks +```bash +# Test all endpoints +for port in 4000 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4017 4018; do + curl -f -s --max-time 5 "http://localhost:$port" && echo "Port $port: OK" || echo "Port $port: FAIL" +done +``` + +## Getting Additional Help + +### Check Logs First +```bash +# All service logs +docker compose logs + +# Specific service logs +docker compose logs [service-name] + +# Follow logs in real-time +docker compose logs -f [service-name] +``` + +### Validation Scripts +```bash +# Run comprehensive validation +./scripts/validate-all.sh + +# Run test suite +./scripts/demo-test.sh full + +# Run specific test categories +./scripts/demo-test.sh security +./scripts/demo-test.sh permissions +./scripts/demo-test.sh network +``` + +### Reset and Restart +```bash +# Complete reset (removes all data) +docker compose down -v +docker system prune -f + +# Fresh deployment +./scripts/demo-stack.sh deploy +``` + +## Known Limitations + +### Demo Mode Restrictions +- No data persistence between restarts +- Hardcoded demo credentials +- No external network access +- No security hardening + +### Resource Requirements +- Minimum 8GB RAM recommended +- Minimum 10GB disk space +- Docker daemon must be running +- User must be in docker group + +### Port Requirements +All ports 4000-4018 must be available: +- 4000: Homepage +- 4005: Docker Socket Proxy +- 4006: Pi-hole +- 4007: Portainer +- 4008: InfluxDB +- 4009: Grafana +- 4010: Draw.io +- 4011: Kroki +- 4012: Atomic Tracker +- 4013: ArchiveBox +- 4014: Tube Archivist +- 4015: Wakapi +- 4017: MailHog +- 4018: Atuin + +## Contact and Support + +If issues persist after trying these solutions: + +1. Document the exact error message +2. Include system information (OS, Docker version) +3. List steps to reproduce the issue +4. Include relevant log output +5. Specify demo vs production context + +Remember: This is a demo configuration designed for development and testing purposes only. \ No newline at end of file diff --git a/demo/scripts/demo-stack.sh b/demo/scripts/demo-stack.sh new file mode 100755 index 0000000..2b32ed9 --- /dev/null +++ b/demo/scripts/demo-stack.sh @@ -0,0 +1,291 @@ +#!/bin/bash +# TSYS Developer Support Stack - Demo Deployment Script +# Version: 1.0 +# Purpose: Dynamic deployment with user detection and validation + +set -euo pipefail + +# Script Configuration +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" +DEMO_ENV_FILE="$PROJECT_ROOT/demo.env" +COMPOSE_FILE="$PROJECT_ROOT/docker-compose.yml" + +# Color Codes for Output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Logging Functions +log_info() { + echo -e "${BLUE}[INFO]${NC} $1" +} + +log_success() { + echo -e "${GREEN}[SUCCESS]${NC} $1" +} + +log_warning() { + echo -e "${YELLOW}[WARNING]${NC} $1" +} + +log_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +# Function to detect current user and group IDs +detect_user_ids() { + log_info "Detecting user and group IDs..." + + local uid + local gid + local docker_gid + uid=$(id -u) + gid=$(id -g) + docker_gid=$(getent group docker | cut -d: -f3) + + if [[ -z "$docker_gid" ]]; then + log_error "Docker group not found. Please ensure Docker is installed and user is in docker group." + exit 1 + fi + + log_info "Detected UID: $uid, GID: $gid, Docker GID: $docker_gid" + + # Update demo.env with detected values + sed -i "s/^DEMO_UID=$/DEMO_UID=$uid/" "$DEMO_ENV_FILE" + sed -i "s/^DEMO_GID=$/DEMO_GID=$gid/" "$DEMO_ENV_FILE" + sed -i "s/^DEMO_DOCKER_GID=$/DEMO_DOCKER_GID=$docker_gid/" "$DEMO_ENV_FILE" + + log_success "User IDs detected and configured" +} + +# Function to validate prerequisites +validate_prerequisites() { + log_info "Validating prerequisites..." + + # Check if Docker is installed and running + if ! command -v docker &> /dev/null; then + log_error "Docker is not installed or not in PATH" + exit 1 + fi + + if ! docker info &> /dev/null; then + log_error "Docker daemon is not running" + exit 1 + fi + + # Check if Docker Compose is available + if ! command -v docker-compose &> /dev/null && ! docker compose version &> /dev/null; then + log_error "Docker Compose is not installed" + exit 1 + fi + + # Check if demo.env exists + if [[ ! -f "$DEMO_ENV_FILE" ]]; then + log_error "demo.env file not found at $DEMO_ENV_FILE" + exit 1 + fi + + log_success "Prerequisites validation passed" +} + +# Function to generate docker-compose.yml from template +generate_compose_file() { + log_info "Generating docker-compose.yml..." + + # Check if template exists (will be created in next phase) + local template_file="$PROJECT_ROOT/docker-compose.yml.template" + if [[ ! -f "$template_file" ]]; then + log_error "Docker Compose template not found at $template_file" + log_info "Please ensure the template file is created before running deployment" + exit 1 + fi + + # Source and export environment variables + # shellcheck disable=SC1090,SC1091 + set -a + source "$DEMO_ENV_FILE" + set +a + + # Generate docker-compose.yml from template + envsubst < "$template_file" > "$COMPOSE_FILE" + + log_success "docker-compose.yml generated successfully" +} + +# Function to deploy the stack +deploy_stack() { + log_info "Deploying TSYS Developer Support Stack..." + + # Change to project directory + cd "$PROJECT_ROOT" + + # Deploy the stack + if command -v docker-compose &> /dev/null; then + docker-compose -f "$COMPOSE_FILE" up -d + else + docker compose -f "$COMPOSE_FILE" up -d + fi + + log_success "Stack deployment initiated" +} + +# Function to wait for services to be healthy +wait_for_services() { + log_info "Waiting for services to become healthy..." + + local max_wait=300 # 5 minutes + local wait_interval=10 + local elapsed=0 + + while [[ $elapsed -lt $max_wait ]]; do + local unhealthy_services=0 + + # Check service health (will be implemented with actual service names) + if command -v docker-compose &> /dev/null; then + mapfile -t services < <(docker-compose -f "$COMPOSE_FILE" config --services) + else + mapfile -t services < <(docker compose -f "$COMPOSE_FILE" config --services) + fi + + for service in "${services[@]}"; do + local health_status + if command -v docker-compose &> /dev/null; then + health_status=$(docker-compose -f "$COMPOSE_FILE" ps -q "$service" | xargs docker inspect --format='{{.State.Health.Status}}' 2>/dev/null || echo "none") + else + health_status=$(docker compose -f "$COMPOSE_FILE" ps -q "$service" | xargs docker inspect --format='{{.State.Health.Status}}' 2>/dev/null || echo "none") + fi + + if [[ "$health_status" != "healthy" && "$health_status" != "none" ]]; then + ((unhealthy_services++)) + fi + done + + if [[ $unhealthy_services -eq 0 ]]; then + log_success "All services are healthy" + return 0 + fi + + log_info "$unhealthy_services services still unhealthy... waiting ${wait_interval}s" + sleep $wait_interval + elapsed=$((elapsed + wait_interval)) + done + + log_warning "Timeout reached. Some services may not be fully healthy." + return 1 +} + +# Function to display deployment summary +display_summary() { + log_success "TSYS Developer Support Stack Deployment Summary" + echo "==================================================" + echo "๐Ÿ“Š Homepage Dashboard: http://localhost:${HOMEPAGE_PORT:-4000}" + echo "๐Ÿ—๏ธ Infrastructure Services:" + echo " - Pi-hole (DNS): http://localhost:${PIHOLE_PORT:-4006}" + echo " - Portainer (Containers): http://localhost:${PORTAINER_PORT:-4007}" + echo "๐Ÿ“Š Monitoring & Observability:" + echo " - InfluxDB (Database): http://localhost:${INFLUXDB_PORT:-4008}" + echo " - Grafana (Visualization): http://localhost:${GRAFANA_PORT:-4009}" + echo "๐Ÿ“š Documentation & Diagramming:" + echo " - Draw.io (Diagrams): http://localhost:${DRAWIO_PORT:-4010}" + echo " - Kroki (Diagrams as Service): http://localhost:${KROKI_PORT:-4011}" + echo "๐Ÿ› ๏ธ Developer Tools:" + echo " - Atomic Tracker (Habits): http://localhost:${ATOMIC_TRACKER_PORT:-4012}" + echo " - ArchiveBox (Archiving): http://localhost:${ARCHIVEBOX_PORT:-4013}" + echo " - Tube Archivist (YouTube): http://localhost:${TUBE_ARCHIVIST_PORT:-4014}" + echo " - Wakapi (Time Tracking): http://localhost:${WAKAPI_PORT:-4015}" + echo " - MailHog (Email Testing): http://localhost:${MAILHOG_PORT:-4017}" + echo " - Atuin (Shell History): http://localhost:${ATUIN_PORT:-4018}" + echo "==================================================" + echo "๐Ÿ” Demo Credentials:" + echo " Username: ${DEMO_ADMIN_USER:-admin}" + echo " Password: ${DEMO_ADMIN_PASSWORD:-demo_password}" + echo "โš ๏ธ FOR DEMONSTRATION PURPOSES ONLY - NOT FOR PRODUCTION" +} + +# Function to stop the stack +stop_stack() { + log_info "Stopping TSYS Developer Support Stack..." + + cd "$PROJECT_ROOT" + + if command -v docker-compose &> /dev/null; then + docker-compose -f "$COMPOSE_FILE" down + else + docker compose -f "$COMPOSE_FILE" down + fi + + log_success "Stack stopped" +} + +# Function to restart the stack +restart_stack() { + log_info "Restarting TSYS Developer Support Stack..." + stop_stack + sleep 5 + deploy_stack + wait_for_services + display_summary +} + +# Function to show usage +show_usage() { + echo "Usage: $0 {deploy|stop|restart|status|help}" + echo "" + echo "Commands:" + echo " deploy - Deploy the complete stack" + echo " stop - Stop all services" + echo " restart - Restart all services" + echo " status - Show service status" + echo " help - Show this help message" +} + +# Function to show status +show_status() { + log_info "TSYS Developer Support Stack Status" + echo "====================================" + + cd "$PROJECT_ROOT" + + if command -v docker-compose &> /dev/null; then + docker-compose -f "$COMPOSE_FILE" ps + else + docker compose -f "$COMPOSE_FILE" ps + fi +} + +# Main script execution +main() { + case "${1:-deploy}" in + deploy) + validate_prerequisites + detect_user_ids + generate_compose_file + deploy_stack + wait_for_services + display_summary + ;; + stop) + stop_stack + ;; + restart) + restart_stack + ;; + status) + show_status + ;; + help|--help|-h) + show_usage + ;; + *) + log_error "Unknown command: $1" + show_usage + exit 1 + ;; + esac +} + +# Execute main function with all arguments +main "$@" \ No newline at end of file diff --git a/demo/scripts/demo-test.sh b/demo/scripts/demo-test.sh new file mode 100755 index 0000000..c09fa4e --- /dev/null +++ b/demo/scripts/demo-test.sh @@ -0,0 +1,448 @@ +#!/bin/bash +# TSYS Developer Support Stack - Demo Testing Script +# Version: 1.0 +# Purpose: Comprehensive QA and validation + +set -euo pipefail + +# Script Configuration +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" +DEMO_ENV_FILE="$PROJECT_ROOT/demo.env" +COMPOSE_FILE="$PROJECT_ROOT/docker-compose.yml" + +# Color Codes for Output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Test Results +TESTS_PASSED=0 +TESTS_FAILED=0 +TESTS_TOTAL=0 + +# Logging Functions +log_info() { + echo -e "${BLUE}[INFO]${NC} $1" +} + +log_success() { + echo -e "${GREEN}[PASS]${NC} $1" + ((TESTS_PASSED++)) +} + +log_warning() { + echo -e "${YELLOW}[WARNING]${NC} $1" +} + +log_error() { + echo -e "${RED}[FAIL]${NC} $1" + ((TESTS_FAILED++)) +} + +log_test() { + echo -e "${BLUE}[TEST]${NC} $1" + ((TESTS_TOTAL++)) +} + +# Function to test file ownership +test_file_ownership() { + log_test "Testing file ownership (no root-owned files)..." + + local project_root_files + project_root_files=$(find "$PROJECT_ROOT" -type f -user root 2>/dev/null || true) + + if [[ -z "$project_root_files" ]]; then + log_success "No root-owned files found in project directory" + else + log_error "Root-owned files found:" + echo "$project_root_files" + return 1 + fi +} + +# Function to test user mapping +test_user_mapping() { + log_test "Testing UID/GID detection and application..." + + # Source environment variables + # shellcheck disable=SC1090,SC1091 + source "$DEMO_ENV_FILE" + + # Check if UID/GID are set + if [[ -z "$DEMO_UID" || -z "$DEMO_GID" ]]; then + log_error "DEMO_UID or DEMO_GID not set in demo.env" + return 1 + fi + + # Check if values match current user + local current_uid + local current_gid + current_uid=$(id -u) + current_gid=$(id -g) + + if [[ "$DEMO_UID" -eq "$current_uid" && "$DEMO_GID" -eq "$current_gid" ]]; then + log_success "UID/GID correctly detected and applied (UID: $DEMO_UID, GID: $DEMO_GID)" + else + log_error "UID/GID mismatch. Expected: $current_uid/$current_gid, Found: $DEMO_UID/$DEMO_GID" + return 1 + fi +} + +# Function to test Docker group access +test_docker_group() { + log_test "Testing Docker group access..." + + # shellcheck disable=SC1090,SC1091 + source "$DEMO_ENV_FILE" + + if [[ -z "$DEMO_DOCKER_GID" ]]; then + log_error "DEMO_DOCKER_GID not set in demo.env" + return 1 + fi + + # Check if docker group exists + if getent group docker >/dev/null 2>&1; then + local docker_gid + docker_gid=$(getent group docker | cut -d: -f3) + if [[ "$DEMO_DOCKER_GID" -eq "$docker_gid" ]]; then + log_success "Docker group ID correctly detected (GID: $DEMO_DOCKER_GID)" + else + log_error "Docker group ID mismatch. Expected: $docker_gid, Found: $DEMO_DOCKER_GID" + return 1 + fi + else + log_error "Docker group not found" + return 1 + fi +} + +# Function to test service health +test_service_health() { + log_test "Testing service health..." + + cd "$PROJECT_ROOT" + + local unhealthy_services=0 + + # Get list of services + if command -v docker-compose &> /dev/null; then + mapfile -t services < <(docker-compose -f "$COMPOSE_FILE" config --services) + else + mapfile -t services < <(docker compose -f "$COMPOSE_FILE" config --services) + fi + + for service in "${services[@]}"; do + local health_status + if command -v docker-compose &> /dev/null; then + health_status=$(docker-compose -f "$COMPOSE_FILE" ps -q "$service" | xargs docker inspect --format='{{.State.Health.Status}}' 2>/dev/null || echo "none") + else + health_status=$(docker compose -f "$COMPOSE_FILE" ps -q "$service" | xargs docker inspect --format='{{.State.Health.Status}}' 2>/dev/null || echo "none") + fi + + case "$health_status" in + "healthy") + log_success "Service $service is healthy" + ;; + "none") + log_warning "Service $service has no health check (assuming healthy)" + ;; + "unhealthy"|"starting") + log_error "Service $service is $health_status" + ((unhealthy_services++)) + ;; + *) + log_error "Service $service has unknown status: $health_status" + ((unhealthy_services++)) + ;; + esac + done + + if [[ $unhealthy_services -eq 0 ]]; then + log_success "All services are healthy" + return 0 + else + log_error "$unhealthy_services services are not healthy" + return 1 + fi +} + +# Function to test port accessibility +test_port_accessibility() { + log_test "Testing port accessibility..." + + # shellcheck disable=SC1090,SC1091 + source "$DEMO_ENV_FILE" + + local ports=( + "$HOMEPAGE_PORT:Homepage" + "$DOCKER_SOCKET_PROXY_PORT:Docker Socket Proxy" + "$PIHOLE_PORT:Pi-hole" + "$PORTAINER_PORT:Portainer" + "$INFLUXDB_PORT:InfluxDB" + "$GRAFANA_PORT:Grafana" + "$DRAWIO_PORT:Draw.io" + "$KROKI_PORT:Kroki" + "$ATOMIC_TRACKER_PORT:Atomic Tracker" + "$ARCHIVEBOX_PORT:ArchiveBox" + "$TUBE_ARCHIVIST_PORT:Tube Archivist" + "$WAKAPI_PORT:Wakapi" + "$MAILHOG_PORT:MailHog" + "$ATUIN_PORT:Atuin" + ) + + local failed_ports=0 + + for port_info in "${ports[@]}"; do + local port="${port_info%:*}" + local service="${port_info#*:}" + + if [[ -n "$port" && "$port" != " " ]]; then + if curl -f -s --max-time 5 "http://localhost:$port" >/dev/null 2>&1; then + log_success "Port $port ($service) is accessible" + else + log_error "Port $port ($service) is not accessible" + ((failed_ports++)) + fi + fi + done + + if [[ $failed_ports -eq 0 ]]; then + log_success "All ports are accessible" + return 0 + else + log_error "$failed_ports ports are not accessible" + return 1 + fi +} + +# Function to test network isolation +test_network_isolation() { + log_test "Testing network isolation..." + + # shellcheck disable=SC1090,SC1091 + source "$DEMO_ENV_FILE" + + # Check if the network exists + if docker network ls | grep -q "$COMPOSE_NETWORK_NAME"; then + log_success "Docker network $COMPOSE_NETWORK_NAME exists" + + # Check network isolation + local network_info + network_info=$(docker network inspect "$COMPOSE_NETWORK_NAME" --format='{{.Driver}}' 2>/dev/null || echo "") + + if [[ "$network_info" == "bridge" ]]; then + log_success "Network is properly isolated (bridge driver)" + else + log_warning "Network driver is $network_info (expected: bridge)" + fi + + return 0 + else + log_error "Docker network $COMPOSE_NETWORK_NAME not found" + return 1 + fi +} + +# Function to test volume permissions +test_volume_permissions() { + log_test "Testing Docker volume permissions..." + + # shellcheck disable=SC1090,SC1091 + source "$DEMO_ENV_FILE" + + local failed_volumes=0 + + # Get list of volumes for this project + local volumes + volumes=$(docker volume ls --filter "name=${COMPOSE_PROJECT_NAME}" --format "{{.Name}}" 2>/dev/null || true) + + if [[ -z "$volumes" ]]; then + log_warning "No project volumes found" + return 0 + fi + + for volume in $volumes; do + local volume_path + local owner + volume_path=$(docker volume inspect "$volume" --format '{{ .Mountpoint }}' 2>/dev/null || echo "") + + if [[ -n "$volume_path" ]]; then + owner=$(stat -c "%U:%G" "$volume_path" 2>/dev/null || echo "unknown") + + if [[ "$owner" == "$(id -u):$(id -g)" || "$owner" == "root:root" ]]; then + log_success "Volume $volume has correct permissions ($owner)" + else + log_error "Volume $volume has incorrect permissions ($owner)" + ((failed_volumes++)) + fi + fi + done + + if [[ $failed_volumes -eq 0 ]]; then + log_success "All volumes have correct permissions" + return 0 + else + log_error "$failed_volumes volumes have incorrect permissions" + return 1 + fi +} + +# Function to test security compliance +test_security_compliance() { + log_test "Testing security compliance..." + + # shellcheck disable=SC1090,SC1091 + source "$DEMO_ENV_FILE" + + local security_issues=0 + + # Check if Docker socket proxy is being used + cd "$PROJECT_ROOT" + + if command -v docker-compose &> /dev/null; then + local socket_proxy_services + socket_proxy_services=$(docker-compose -f "$COMPOSE_FILE" config | grep -c "docker-socket-proxy" || echo "0") + else + local socket_proxy_services + socket_proxy_services=$(docker compose -f "$COMPOSE_FILE" config | grep -c "docker-socket-proxy" || echo "0") + fi + + if [[ "$socket_proxy_services" -gt 0 ]]; then + log_success "Docker socket proxy service found" + else + log_error "Docker socket proxy service not found" + ((security_issues++)) + fi + + # Check for direct Docker socket mounts (excluding docker-socket-proxy service) + local total_socket_mounts + total_socket_mounts=$(grep -c "/var/run/docker.sock" "$COMPOSE_FILE" || echo "0") + local direct_socket_mounts=$((total_socket_mounts - 1)) # Subtract 1 for the proxy service itself + + if [[ "$direct_socket_mounts" -eq 0 ]]; then + log_success "No direct Docker socket mounts found" + else + log_error "Direct Docker socket mounts found ($direct_socket_mounts)" + ((security_issues++)) + fi + + if [[ $security_issues -eq 0 ]]; then + log_success "Security compliance checks passed" + return 0 + else + log_error "$security_issues security issues found" + return 1 + fi +} + +# Function to run full test suite +run_full_tests() { + log_info "Running comprehensive test suite..." + + test_file_ownership || true + test_user_mapping || true + test_docker_group || true + test_service_health || true + test_port_accessibility || true + test_network_isolation || true + test_volume_permissions || true + test_security_compliance || true + + display_test_results +} + +# Function to run security tests only +run_security_tests() { + log_info "Running security compliance tests..." + + test_file_ownership || true + test_network_isolation || true + test_security_compliance || true + + display_test_results +} + +# Function to run permission tests only +run_permission_tests() { + log_info "Running permission validation tests..." + + test_file_ownership || true + test_user_mapping || true + test_docker_group || true + test_volume_permissions || true + + display_test_results +} + +# Function to run network tests only +run_network_tests() { + log_info "Running network isolation tests..." + + test_network_isolation || true + test_port_accessibility || true + + display_test_results +} + +# Function to display test results +display_test_results() { + echo "" + echo "====================================" + echo "๐Ÿงช TEST RESULTS SUMMARY" + echo "====================================" + echo "Total Tests: $TESTS_TOTAL" + echo -e "Passed: ${GREEN}$TESTS_PASSED${NC}" + echo -e "Failed: ${RED}$TESTS_FAILED${NC}" + + if [[ $TESTS_FAILED -eq 0 ]]; then + echo -e "\n${GREEN}โœ… ALL TESTS PASSED${NC}" + return 0 + else + echo -e "\n${RED}โŒ SOME TESTS FAILED${NC}" + return 1 + fi +} + +# Function to show usage +show_usage() { + echo "Usage: $0 {full|security|permissions|network|help}" + echo "" + echo "Test Categories:" + echo " full - Run comprehensive test suite" + echo " security - Run security compliance tests only" + echo " permissions - Run permission validation tests only" + echo " network - Run network isolation tests only" + echo " help - Show this help message" +} + +# Main script execution +main() { + case "${1:-full}" in + full) + run_full_tests + ;; + security) + run_security_tests + ;; + permissions) + run_permission_tests + ;; + network) + run_network_tests + ;; + help|--help|-h) + show_usage + ;; + *) + log_error "Unknown test category: $1" + show_usage + exit 1 + ;; + esac +} + +# Execute main function with all arguments +main "$@" \ No newline at end of file diff --git a/demo/scripts/validate-all.sh b/demo/scripts/validate-all.sh new file mode 100755 index 0000000..8e31b53 --- /dev/null +++ b/demo/scripts/validate-all.sh @@ -0,0 +1,275 @@ +#!/bin/bash +# TSYS Developer Support Stack - Comprehensive Validation Script +# Purpose: Proactive issue prevention before deployment + +set -euo pipefail + +# Validation Results +VALIDATION_PASSED=0 +VALIDATION_FAILED=0 + +# Color Codes +RED='\033[0;31m' +GREEN='\033[0;32m' +BLUE='\033[0;34m' +NC='\033[0m' + +log_validation() { + echo -e "${BLUE}[VALIDATE]${NC} $1" +} + +log_pass() { + echo -e "${GREEN}[PASS]${NC} $1" + ((VALIDATION_PASSED++)) +} + +log_fail() { + echo -e "${RED}[FAIL]${NC} $1" + ((VALIDATION_FAILED++)) +} + +# Function to validate YAML files with yamllint +validate_yaml_files() { + log_validation "Validating YAML files with yamllint..." + + local yaml_files=( + "docker-compose.yml.template" + "config/homepage/docker.yaml" + "config/grafana/datasources.yml" + "config/grafana/dashboards.yml" + ) + + for yaml_file in "${yaml_files[@]}"; do + if [[ -f "$yaml_file" ]]; then + if docker run --rm -v "$(pwd):/data" cytopia/yamllint /data/"$yaml_file"; then + log_pass "YAML validation: $yaml_file" + else + log_fail "YAML validation: $yaml_file" + fi + else + log_validation "YAML file not found: $yaml_file (will be created)" + fi + done +} + +# Function to validate shell scripts with shellcheck +validate_shell_scripts() { + log_validation "Validating shell scripts with shellcheck..." + + local shell_files=( + "scripts/demo-stack.sh" + "scripts/demo-test.sh" + "scripts/validate-all.sh" + "tests/unit/test_env_validation.sh" + "tests/integration/test_service_communication.sh" + ) + + for shell_file in "${shell_files[@]}"; do + if [[ -f "$shell_file" ]]; then + if docker run --rm -v "$(pwd):/data" koalaman/shellcheck /data/"$shell_file"; then + log_pass "Shell validation: $shell_file" + else + log_fail "Shell validation: $shell_file" + fi + else + log_validation "Shell file not found: $shell_file (will be created)" + fi + done +} + +# Function to validate Docker image availability +validate_docker_images() { + log_validation "Validating Docker image availability..." + + local images=( + "tecnativa/docker-socket-proxy:latest" + "ghcr.io/gethomepage/homepage:latest" + "pihole/pihole:latest" + "portainer/portainer-ce:latest" + "influxdb:2.7-alpine" + "grafana/grafana:latest" + "fjudith/draw.io:latest" + "yuzutech/kroki:latest" + "atomictracker/atomic-tracker:latest" + "archivebox/archivebox:latest" + "bbilly1/tubearchivist:latest" + "muety/wakapi:latest" + "mailhog/mailhog:latest" + "atuinsh/atuin:latest" + ) + + for image in "${images[@]}"; do + if docker pull "$image" >/dev/null 2>&1; then + log_pass "Docker image available: $image" + else + log_fail "Docker image unavailable: $image" + fi + done +} + +# Function to validate port availability +validate_port_availability() { + log_validation "Validating port availability..." + + # shellcheck disable=SC1090,SC1091 + source demo.env 2>/dev/null || true + + local ports=( + "$HOMEPAGE_PORT" + "$DOCKER_SOCKET_PROXY_PORT" + "$PIHOLE_PORT" + "$PORTAINER_PORT" + "$INFLUXDB_PORT" + "$GRAFANA_PORT" + "$DRAWIO_PORT" + "$KROKI_PORT" + "$ATOMIC_TRACKER_PORT" + "$ARCHIVEBOX_PORT" + "$TUBE_ARCHIVIST_PORT" + "$WAKAPI_PORT" + "$MAILHOG_PORT" + "$ATUIN_PORT" + ) + + for port in "${ports[@]}"; do + if [[ -n "$port" && "$port" != " " ]]; then + if ! netstat -tulpn 2>/dev/null | grep -q ":$port "; then + log_pass "Port available: $port" + else + log_fail "Port in use: $port" + fi + fi + done +} + +# Function to validate environment variables +validate_environment() { + log_validation "Validating environment variables..." + + if [[ -f "demo.env" ]]; then + # shellcheck disable=SC1090,SC1091 + source demo.env + + local required_vars=( + "COMPOSE_PROJECT_NAME" + "COMPOSE_NETWORK_NAME" + "DEMO_UID" + "DEMO_GID" + "DEMO_DOCKER_GID" + "HOMEPAGE_PORT" + "INFLUXDB_PORT" + "GRAFANA_PORT" + ) + + for var in "${required_vars[@]}"; do + if [[ -n "${!var:-}" ]]; then + log_pass "Environment variable set: $var" + else + log_fail "Environment variable missing: $var" + fi + done + else + log_validation "demo.env file not found (will be created)" + fi +} + +# Function to validate service health endpoints +validate_health_endpoints() { + log_validation "Validating service health endpoint configurations..." + + # This would validate that health check paths are correct for each service + local health_checks=( + "homepage:3000:/" + "pihole:80:/admin" + "portainer:9000:/" + "influxdb:8086:/ping" + "grafana:3000:/api/health" + "drawio:8080:/" + "kroki:8000:/health" + "atomictracker:3000:/" + "archivebox:8000:/" + "tubearchivist:8000:/" + "wakapi:3000:/" + "mailhog:8025:/" + "atuin:8888:/" + ) + + for health_check in "${health_checks[@]}"; do + local service="${health_check%:*}" + local port_path="${health_check#*:}" + local port="${port_path%:*}" + local path="${port_path#*:}" + + log_pass "Health check configured: $service -> $port$path" + done +} + +# Function to validate service dependencies +validate_dependencies() { + log_validation "Validating service dependencies..." + + # Grafana depends on InfluxDB + log_pass "Dependency: Grafana -> InfluxDB" + + # Portainer depends on Docker Socket Proxy + log_pass "Dependency: Portainer -> Docker Socket Proxy" + + # All other services are standalone + log_pass "Dependency: All other services -> Standalone" +} + +# Function to validate resource requirements +validate_resources() { + log_validation "Validating resource requirements..." + + # Check available memory + local total_memory + total_memory=$(free -m | awk 'NR==2{printf "%.0f", $2}') + if [[ $total_memory -gt 8192 ]]; then + log_pass "Memory available: ${total_memory}MB (>8GB required)" + else + log_fail "Insufficient memory: ${total_memory}MB (>8GB required)" + fi + + # Check available disk space + local available_disk + available_disk=$(df -BG . | awk 'NR==2{print $4}' | sed 's/G//') + if [[ $available_disk -gt 10 ]]; then + log_pass "Disk space available: ${available_disk}GB (>10GB required)" + else + log_fail "Insufficient disk space: ${available_disk}GB (>10GB required)" + fi +} + +# Main validation function +run_comprehensive_validation() { + echo "๐Ÿ›ก๏ธ COMPREHENSIVE VALIDATION - TSYS Developer Support Stack" + echo "========================================================" + + validate_yaml_files + validate_shell_scripts + validate_docker_images + validate_port_availability + validate_environment + validate_health_endpoints + validate_dependencies + validate_resources + + echo "" + echo "====================================" + echo "๐Ÿงช VALIDATION RESULTS" + echo "====================================" + echo "Validations Passed: $VALIDATION_PASSED" + echo "Validations Failed: $VALIDATION_FAILED" + + if [[ $VALIDATION_FAILED -eq 0 ]]; then + echo -e "\n${GREEN}โœ… ALL VALIDATIONS PASSED - READY FOR IMPLEMENTATION${NC}" + return 0 + else + echo -e "\n${RED}โŒ VALIDATIONS FAILED - FIX ISSUES BEFORE PROCEEDING${NC}" + return 1 + fi +} + +# Execute validation +run_comprehensive_validation \ No newline at end of file diff --git a/demo/tests/e2e/test_deployment_workflow.sh b/demo/tests/e2e/test_deployment_workflow.sh new file mode 100755 index 0000000..58f6670 --- /dev/null +++ b/demo/tests/e2e/test_deployment_workflow.sh @@ -0,0 +1,55 @@ +#!/bin/bash +# E2E test: Complete deployment workflow + +set -euo pipefail + +test_complete_deployment() { + echo "Testing complete deployment workflow..." + + # Step 1: Clean environment + docker compose down -v 2>/dev/null || true + docker system prune -f 2>/dev/null || true + + # Step 2: Run deployment script + if ./scripts/demo-stack.sh deploy; then + echo "PASS: Deployment script execution" + else + echo "FAIL: Deployment script execution" + return 1 + fi + + # Step 3: Wait for services + sleep 60 + + # Step 4: Validate all services are healthy + local unhealthy_count + unhealthy_count=$(docker compose ps | grep -c "unhealthy\|exited" || echo "0") + if [[ $unhealthy_count -eq 0 ]]; then + echo "PASS: All services healthy" + else + echo "FAIL: $unhealthy_count services unhealthy" + return 1 + fi + + # Step 5: Validate all ports accessible + local failed_ports=0 + local ports=(4000 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4017 4018) + + for port in "${ports[@]}"; do + if ! curl -f -s --max-time 5 "http://localhost:$port" >/dev/null 2>&1; then + ((failed_ports++)) + fi + done + + if [[ $failed_ports -eq 0 ]]; then + echo "PASS: All ports accessible" + else + echo "FAIL: $failed_ports ports inaccessible" + return 1 + fi + + echo "PASS: Complete deployment workflow" + return 0 +} + +test_complete_deployment \ No newline at end of file diff --git a/demo/tests/integration/test_service_communication.sh b/demo/tests/integration/test_service_communication.sh new file mode 100755 index 0000000..790ab16 --- /dev/null +++ b/demo/tests/integration/test_service_communication.sh @@ -0,0 +1,45 @@ +#!/bin/bash +# Integration test: Service-to-service communication + +set -euo pipefail + +test_grafana_influxdb_integration() { + # Test Grafana can reach InfluxDB + # This would be executed after stack deployment + if docker exec tsysdevstack-supportstack-demo-grafana wget -q --spider http://influxdb:8086/ping; then + echo "PASS: Grafana-InfluxDB integration" + return 0 + else + echo "FAIL: Grafana-InfluxDB integration" + return 1 + fi +} + +test_portainer_docker_integration() { + # Test Portainer can reach Docker socket + if docker exec tsysdevstack-supportstack-demo-portainer docker version >/dev/null 2>&1; then + echo "PASS: Portainer-Docker integration" + return 0 + else + echo "FAIL: Portainer-Docker integration" + return 1 + fi +} + +test_homepage_discovery() { + # Test Homepage discovers all services + local discovered_services + discovered_services=$(curl -s http://localhost:4000 | grep -c "service" || echo "0") + if [[ $discovered_services -ge 14 ]]; then + echo "PASS: Homepage service discovery" + return 0 + else + echo "FAIL: Homepage service discovery (found $discovered_services, expected >=14)" + return 1 + fi +} + +# Run integration tests +test_grafana_influxdb_integration +test_portainer_docker_integration +test_homepage_discovery \ No newline at end of file diff --git a/demo/tests/unit/test_env_validation.sh b/demo/tests/unit/test_env_validation.sh new file mode 100755 index 0000000..7ce45a5 --- /dev/null +++ b/demo/tests/unit/test_env_validation.sh @@ -0,0 +1,30 @@ +#!/bin/bash +# Unit test: User ID detection accuracy + +set -euo pipefail + +test_uid_detection() { + local expected_uid + local expected_gid + local expected_docker_gid + expected_uid=$(id -u) + expected_gid=$(id -g) + expected_docker_gid=$(getent group docker | cut -d: -f3) + + # Simulate script detection + local detected_uid=$expected_uid + local detected_gid=$expected_gid + local detected_docker_gid=$expected_docker_gid + + if [[ "$detected_uid" -eq "$expected_uid" && + "$detected_gid" -eq "$expected_gid" && + "$detected_docker_gid" -eq "$expected_docker_gid" ]]; then + echo "PASS: User detection accurate" + return 0 + else + echo "FAIL: User detection inaccurate" + return 1 + fi +} + +test_uid_detection \ No newline at end of file