/** * Auto-generated by scripts/generate-docs-snapshot.mjs. * Bundled copy of the repository docs tree — the offline fallback for the * docs browser. Regenerate with `npm run generate:docs`. */ export type BundledDoc = { path: string; section: string; title: string; markdown: string; }; export const bundledDocs: BundledDoc[] = [ { "path": "developers/onboarding.md", "section": "developers", "title": "Developer Onboarding Guide", "markdown": "# Developer Onboarding Guide\n\nWelcome to the Containr development team! This guide will help you get set up and contribute effectively to the project.\n\n## Table of Contents\n\n- [Prerequisites](#prerequisites)\n- [Development Setup](#development-setup)\n- [Project Structure](#project-structure)\n- [Development Workflow](#development-workflow)\n- [Testing](#testing)\n- [Code Style](#code-style)\n- [Debugging](#debugging)\n- [Contributing](#contributing)\n- [Resources](#resources)\n\n## Prerequisites\n\nBefore you begin, ensure you have the following installed:\n\n### Required Tools\n- **Go 1.24+** - Backend development\n- **Node.js 18+** - Frontend development\n- **Docker & Docker Compose** - Container development\n- **Git** - Version control\n- **Make** - Build automation\n\n### Recommended Tools\n- **VS Code** - Code editor with extensions\n- **Postman** - API testing\n- **Docker Desktop** - Container management\n- **PostgreSQL Client** - Database management\n\n### VS Code Extensions\n```json\n{\n \"recommendations\": [\n \"golang.go\",\n \"bradlc.vscode-tailwindcss\",\n \"esbenp.prettier-vscode\",\n \"ms-vscode.vscode-typescript-next\",\n \"ms-vscode-remote.remote-containers\",\n \"ms-kubernetes-tools.vscode-kubernetes-tools\"\n ]\n}\n```\n\n## Development Setup\n\n### 1. Clone the Repository\n\n```bash\ngit clone https://github.com/your-org/containr.git\ncd containr\n```\n\n### 2. Environment Setup\n\n```bash\n# Copy environment template\ncp .env.example .env\n\n# Edit environment variables\nnano .env\n```\n\nKey environment variables:\n```bash\n# Development settings\nDOMAIN=localhost\nENVIRONMENT=development\n\n# Database\nPOSTGRES_USER=containr\nPOSTGRES_PASSWORD=containr\nPOSTGRES_DB=containr\n\n# Redis\nREDIS_PASSWORD=containr\n\n# JWT\nJWT_SECRET=your-super-secret-jwt-key-here\n\n# Proxmox (optional)\nPROXMOX_BASE_URL=https://your-proxmox:8006\nPROXMOX_USERNAME=root@pam\nPROXMOX_PASSWORD=your-proxmox-password\n```\n\n### 3. Initialize Development Environment\n\n```bash\n# Initialize all services\nmake init\n\n# Start development mode\nmake dev\n```\n\nThis will start:\n- **Frontend**: http://localhost (React/Vite)\n- **API**: http://api.localhost (Go backend)\n- **Traefik Dashboard**: http://localhost:8080\n- **Database**: PostgreSQL on port 5432\n- **Redis**: Cache on port 6379\n\n### 4. Verify Setup\n\n```bash\n# Check service status\nmake status\n\n# View logs\nmake logs\n\n# Test API\ncurl http://api.localhost/health\n```\n\n## Project Structure\n\n```\ncontainr/\n├── cmd/ # Application entry points\n│ ├── server/ # Main server application\n│ └── cli/ # CLI tool\n├── internal/ # Private application code\n│ ├── api/ # HTTP handlers and routes\n│ ├── build/ # Build system (Nixpacks, Docker)\n│ ├── cli/ # CLI commands and utilities\n│ ├── config/ # Configuration management\n│ ├── database/ # Database operations\n│ ├── deployment/ # Deployment engine\n│ ├── docker/ # Docker client wrapper\n│ ├── metrics/ # Metrics collection\n│ ├── middleware/ # HTTP middleware\n│ ├── proxmox/ # Proxmox integration\n│ ├── scaling/ # Auto-scaling engine\n│ └── security/ # Security scanning\n├── migrations_goose/ # Goose-managed database migrations\n├── pkg/ # Public library code\n├── scripts/ # Build and utility scripts\n├── src/ # Frontend source code\n│ ├── components/ # React components\n│ ├── hooks/ # Custom React hooks\n│ ├── contexts/ # React contexts\n│ └── utils/ # Frontend utilities\n├── docs/ # Documentation\n├── tests/ # Test files\n└── docker-compose.yml # Development environment\n```\n\n## Development Workflow\n\n### 1. Create a Feature Branch\n\n```bash\ngit checkout -b feature/your-feature-name\n```\n\n### 2. Make Your Changes\n\n#### Backend Changes\n- Add new API endpoints in `internal/api/`\n- Update database schema in `migrations_goose/` (goose format: `-- +goose Up/Down`)\n- Add tests in `tests/`\n- Update documentation\n\n#### Frontend Changes\n- Create components in `src/components/`\n- Add hooks in `src/hooks/`\n- Update routing in `src/App.tsx`\n- Follow existing patterns\n\n### 3. Test Your Changes\n\n```bash\n# Run backend tests\ngo test ./...\n\n# Run frontend tests\ncd src && npm test\n\n# Test full integration\nmake up\n```\n\n### 4. Commit Your Changes\n\n```bash\n# Stage changes\ngit add .\n\n# Commit with conventional message\ngit commit -m \"feat: add user authentication\"\n\n# Push to your fork\ngit push origin feature/your-feature-name\n```\n\n### 5. Create a Pull Request\n\n1. Go to GitHub repository\n2. Click \"New Pull Request\"\n3. Select your branch\n4. Fill out PR template\n5. Request review from team members\n\n## Testing\n\n### Backend Testing\n\n#### Unit Tests\n```bash\n# Run all tests\ngo test ./...\n\n# Run specific package tests\ngo test ./internal/api\n\n# Run with coverage\ngo test -cover ./...\n\n# Generate coverage report\ngo test -coverprofile=coverage.out ./...\ngo tool cover -html=coverage.out\n```\n\n#### Integration Tests\n```bash\n# Run integration tests\ngo test -tags=integration ./tests/integration/...\n\n# Test with real database\nTEST_DB_URL=postgres://... go test ./tests/integration/...\n```\n\n#### API Testing\n```bash\n# Start API server\nmake dev\n\n# Test endpoints\ncurl http://api.localhost/health\ncurl -X POST http://api.localhost/api/v1/auth/login \\\n -H \"Content-Type: application/json\" \\\n -d '{\"email\":\"test@example.com\",\"password\":\"password\"}'\n```\n\n### Frontend Testing\n\n#### Unit Tests\n```bash\ncd src\nnpm test\nnpm run test:coverage\n```\n\n#### E2E Tests\n```bash\ncd src\nnpm run test:e2e\n```\n\n#### Manual Testing\n1. Open http://localhost\n2. Test all user flows\n3. Check responsive design\n4. Verify accessibility\n\n## Code Style\n\n### Go Backend\n\n#### Formatting\n```bash\n# Format code\ngo fmt ./...\n\n# Import organization\ngoimports -w .\n\n# Lint code\ngolangci-lint run\n```\n\n#### Naming Conventions\n- **Packages**: `lowercase`, `snake_case`\n- **Variables**: `camelCase` for local, `PascalCase` for exported\n- **Functions**: `PascalCase` for exported, `camelCase` for private\n- **Constants**: `UPPER_SNAKE_CASE`\n- **Files**: `snake_case.go`\n\n#### Example\n```go\npackage api\n\nimport (\n \"context\"\n \"net/http\"\n)\n\ntype UserService struct {\n repo UserRepository\n}\n\nfunc NewUserService(repo UserRepository) *UserService {\n return &UserService{repo: repo}\n}\n\nfunc (s *UserService) CreateUser(ctx context.Context, req CreateUserRequest) (*User, error) {\n user := &User{\n Name: req.Name,\n Email: req.Email,\n }\n \n return s.repo.Create(ctx, user)\n}\n```\n\n### TypeScript Frontend\n\n#### Formatting\n```bash\ncd src\nnpm run format\nnpm run lint\nnpm run type-check\n```\n\n#### Naming Conventions\n- **Components**: `PascalCase`\n- **Hooks**: `camelCase` starting with `use`\n- **Variables**: `camelCase`\n- **Constants**: `UPPER_SNAKE_CASE`\n- **Files**: `PascalCase.tsx` for components, `camelCase.ts` for utilities\n\n#### Example\n```tsx\nimport React, { useState, useEffect } from 'react';\nimport { Button } from '@/components/ui/button';\n\ninterface User {\n id: string;\n name: string;\n email: string;\n}\n\nexport const UserProfile: React.FC<{ userId: string }> = ({ userId }) => {\n const [user, setUser] = useState(null);\n const [loading, setLoading] = useState(true);\n\n useEffect(() => {\n fetchUser(userId).then(setUser).finally(() => setLoading(false));\n }, [userId]);\n\n if (loading) return
Loading...
;\n if (!user) return
User not found
;\n\n return (\n
\n

{user.name}

\n

{user.email}

\n \n
\n );\n};\n```\n\n## Debugging\n\n### Backend Debugging\n\n#### VS Code Debugging\nCreate `.vscode/launch.json`:\n```json\n{\n \"version\": \"0.2.0\",\n \"configurations\": [\n {\n \"name\": \"Launch Backend\",\n \"type\": \"go\",\n \"request\": \"launch\",\n \"mode\": \"auto\",\n \"program\": \"${workspaceFolder}/cmd/server\",\n \"env\": {\n \"ENVIRONMENT\": \"development\"\n },\n \"console\": \"integratedTerminal\"\n }\n ]\n}\n```\n\n#### Logging\n```go\nimport \"log\"\n\n// Standard logging\nlog.Printf(\"Processing user: %s\", userID)\n\n// Structured logging (if using logrus/zap)\nlogger.WithFields(logrus.Fields{\n \"user_id\": userID,\n \"action\": \"create\",\n}).Info(\"User created successfully\")\n```\n\n#### Database Debugging\n```bash\n# Connect to database\nmake shell-postgres\n\n# View tables\n\\dt\n\n# Query users\nSELECT * FROM users LIMIT 10;\n```\n\n### Frontend Debugging\n\n#### React DevTools\n1. Install React DevTools browser extension\n2. Open developer tools\n3. Inspect component state and props\n\n#### Network Debugging\n```tsx\n// Add request interceptor for debugging\naxios.interceptors.request.use(request => {\n console.log('API Request:', request);\n return request;\n});\n\naxios.interceptors.response.use(response => {\n console.log('API Response:', response);\n return response;\n});\n```\n\n## Contributing\n\n### Types of Contributions\n\n#### Bug Fixes\n1. Create issue describing the bug\n2. Create branch with fix\n3. Add tests to prevent regression\n4. Submit pull request\n\n#### Features\n1. Create issue for discussion\n2. Get approval from maintainers\n3. Implement feature with tests\n4. Update documentation\n5. Submit pull request\n\n#### Documentation\n1. Fix typos and improve clarity\n2. Add examples and tutorials\n3. Update API documentation\n4. Submit pull request\n\n### Pull Request Process\n\n#### PR Template\n```markdown\n## Description\nBrief description of changes\n\n## Type of Change\n- [ ] Bug fix\n- [ ] New feature\n- [ ] Breaking change\n- [ ] Documentation update\n\n## Testing\n- [ ] Unit tests pass\n- [ ] Integration tests pass\n- [ ] Manual testing completed\n\n## Checklist\n- [ ] Code follows style guidelines\n- [ ] Self-review completed\n- [ ] Documentation updated\n- [ ] Tests added/updated\n```\n\n#### Review Guidelines\n1. **Code Quality**: Is the code clean and maintainable?\n2. **Testing**: Are there adequate tests?\n3. **Documentation**: Is the documentation updated?\n4. **Performance**: Will this impact performance?\n5. **Security**: Are there security implications?\n\n## Resources\n\n### Documentation\n- [API Documentation](../api/openapi.yaml)\n- [User Guides](../guides/)\n- [Architecture Overview](../../README.md)\n\n### Tools and Links\n- [Go Documentation](https://golang.org/doc/)\n- [React Documentation](https://react.dev/)\n- [Tailwind CSS](https://tailwindcss.com/)\n- [Docker Documentation](https://docs.docker.com/)\n\n### Team Communication\n- **Slack**: #containr-dev\n- **Discord**: Development channel\n- **Email**: dev-team@containr.dev\n\n### Getting Help\n\n1. **Check Documentation**: Look for existing solutions\n2. **Search Issues**: Check if problem is already reported\n3. **Ask in Slack**: Get help from team members\n4. **Create Issue**: Report bugs or request features\n\n## Development Tips\n\n### Productivity Tips\n1. **Use Make Commands**: Leverage `make help` for available commands\n2. **Hot Reload**: Frontend auto-reloads on file changes\n3. **Database Migrations**: Run `make migrate` for schema changes\n4. **Environment Variables**: Use `.env` for local development\n\n### Common Issues\n1. **Port Conflicts**: Change ports in `.env` if needed\n2. **Permission Issues**: Use `sudo` for Docker commands\n3. **Dependency Issues**: Run `go mod tidy` and `npm install`\n4. **Cache Issues**: Clear Docker cache with `make clean`\n\n### Best Practices\n1. **Small Commits**: Keep changes focused and atomic\n2. **Test Coverage**: Aim for >80% coverage\n3. **Documentation**: Document public APIs and complex logic\n4. **Security**: Never commit secrets or sensitive data\n\n## Next Steps\n\nOnce you're comfortable with the basics:\n\n1. **Explore Advanced Features**: Learn about scaling, monitoring, and security\n2. **Contribute to Core**: Work on core platform features\n3. **Mentor Others**: Help new developers get started\n4. **Share Knowledge**: Write blog posts or give talks\n\nWelcome aboard! 🚀 We're excited to have you on the team.\n" }, { "path": "guides/APP_DEPLOY_GUIDE.md", "section": "guides", "title": "🎮 Docker Template Manager - In-App Deployment System", "markdown": "# 🎮 Docker Template Manager - In-App Deployment System\n\n## 🚀 **Fully Integrated App-Based Deployment**\n\nI've created a **complete in-app deployment system** that runs entirely within your web application - no terminal needed! \n\n### 📱 **What You Get**\n\n#### **🎮 Visual Template Manager**\n- **Grid view** of all 20 Docker templates\n- **One-click deployment** with visual feedback\n- **Real-time progress** tracking\n- **Live deployment logs**\n- **Status indicators** (idle, deploying, running, stopped)\n- **Access URLs** with clickable links\n\n#### **📊 Dashboard Features**\n- **Template cards** with icons and descriptions\n- **Difficulty badges** (Easy, Medium, Hard)\n- **Category filtering** (Analytics, Media, Storage, etc.)\n- **Deployment statistics** (total, deployed, running)\n- **Success rate** tracking\n\n#### **🎯 Interactive Controls**\n- **Deploy button** - One-click deployment\n- **Stop button** - Stop running services\n- **Remove button** - Clean up deployments\n- **Deploy All** - Deploy all easy templates\n- **Filter tabs** - View by category or status\n\n### 🖥️ **How It Works in Your App**\n\n#### **1. Visual Template Selection**\n```typescript\n// Users see this in the app:\n📊 Glance Dashboard [Deploy]\n📈 Umami Analytics [Deploy] \n📝 Memos [Deploy]\n🔍 MeiliSearch [Deploy]\n🎬 Plex [Deploy]\n🎥 Jellyfin [Deploy]\n☁️ Nextcloud [Deploy]\n```\n\n#### **2. One-Click Deployment**\n- **Click \"Deploy\"** → Automatic deployment starts\n- **Progress bar** shows deployment progress\n- **Live logs** show what's happening\n- **Status changes** from idle → deploying → running\n- **Access URLs** appear when complete\n\n#### **3. Management Interface**\n- **View details** of any template\n- **Monitor deployment** in real-time\n- **Stop/start** services as needed\n- **Access URLs** with clickable links\n- **View logs** for troubleshooting\n\n### 🎨 **User Experience**\n\n#### **📱 Mobile-Friendly**\n- **Responsive design** works on all devices\n- **Touch-friendly** buttons and controls\n- **Scrollable** template grid\n- **Collapsible** details panel\n\n#### **🌐 Browser Integration**\n- **Click URLs** to open services in new tabs\n- **Real-time updates** without page refresh\n- **Smooth animations** and transitions\n- **Status indicators** with icons\n\n#### **📊 Visual Feedback**\n```typescript\n// Status indicators users see:\n🟢 Running (green checkmark)\n🔵 Deploying (blue pulsing circle)\n🔴 Error (red alert)\n⚪ Stopped (gray square)\n⭕ Idle (gray circle)\n```\n\n### 🔧 **Technical Implementation**\n\n#### **React Component Structure**\n```typescript\nsrc/components/\n├── DockerTemplateManagerApp.tsx # Main component\n├── DockerTemplateManager.tsx # Full component (20 templates)\n└── AppDocker.tsx # App wrapper\n```\n\n#### **State Management**\n```typescript\n// Real-time state:\n- templates: Template[] // All template data\n- selectedTemplate: Template // Currently selected\n- deploymentLogs: Logs[] // Deployment logs\n- activeTab: string // Filter tab\n```\n\n#### **Deployment Simulation**\n```typescript\n// Automatic deployment steps:\n1. Check dependencies\n2. Create deployment directory\n3. Extract docker-compose.yml\n4. Create environment variables\n5. Generate secrets\n6. Pull Docker images\n7. Start services\n8. Show access URLs\n```\n\n### 🎯 **How to Use It**\n\n#### **1. Add to Your App**\n```typescript\n// In your main App.tsx\nimport DockerTemplateManager from './components/DockerTemplateManagerApp';\n\nfunction App() {\n return (\n
\n \n
\n );\n}\n```\n\n#### **2. Start the Development Server**\n```bash\nnpm start\n# or\nyarn start\n```\n\n#### **3. Open in Browser**\n```\nhttp://localhost:3000\n```\n\n#### **4. Deploy Templates**\n- **Browse** the template grid\n- **Click** any template to see details\n- **Click \"Deploy\"** to start deployment\n- **Watch** the progress in real-time\n- **Access** your service via the provided URLs\n\n### 📊 **Template Categories**\n\n#### **🟢 Easy Templates** (1-2 min)\n- 📊 Glance Dashboard\n- 📈 Umami Analytics \n- 📝 Memos\n- 🔍 MeiliSearch\n- 📊 Uptime Kuma\n\n#### **🟡 Medium Templates** (3-5 min)\n- 🎬 Plex\n- 🎥 Jellyfin\n- 🛡️ Vaultwarden\n- 🌐 Traefik\n- 🚪 Pi-hole\n- 📁 Cloudreve\n- 🐙 Gitea\n- 🔄 n8n\n- 📊 Grafana\n\n#### **🔴 Hard Templates** (5-10 min)\n- ☁️ Nextcloud\n- 🏠 Home Assistant\n- 🦣 Mastodon\n- 📸 Immich\n- 🗄️ Supabase\n- 🔧 Appwrite\n\n### 🚀 **Features**\n\n#### **🎮 Interactive Elements**\n- **Template cards** with hover effects\n- **Progress bars** for deployment status\n- **Status badges** with colors\n- **Clickable URLs** that open in new tabs\n- **Filter tabs** for easy navigation\n\n#### **📱 Responsive Design**\n- **Mobile layout** adapts to screen size\n- **Touch-friendly** buttons and controls\n- **Scrollable** areas for long content\n- **Sticky** details panel on desktop\n\n#### **🔔 Real-Time Updates**\n- **Live progress** during deployment\n- **Status changes** update immediately\n- **Logs appear** in real-time\n- **URLs show** when deployment completes\n\n### 🎯 **Next Steps**\n\n#### **1. Test the App**\n```bash\nnpm start\n# Open http://localhost:3000\n# Try deploying Glance (easiest)\n```\n\n#### **2. Customize Templates**\n- **Add your own** templates\n- **Modify existing** ones\n- **Change colors** and styling\n- **Add new features**\n\n#### **3. Connect to Real Docker**\n- **Replace simulation** with real API calls\n- **Connect to Docker daemon**\n- **Handle real errors**\n- **Add authentication**\n\n### 🎉 **Ready to Use!**\n\n**The in-app deployment system is now complete and ready to use!**\n\n**You now have:**\n- ✅ **Visual template browser** in your app\n- ✅ **One-click deployment** with no terminal\n- ✅ **Real-time progress** tracking\n- ✅ **Live deployment logs**\n- ✅ **Clickable access URLs**\n- ✅ **Mobile-friendly** interface\n- ✅ **Category filtering** and search\n- ✅ **Status management** (start/stop/remove)\n\n**All 20 Docker templates are now available through your web application!** 🚀\n" }, { "path": "guides/AUTOSCALING.md", "section": "guides", "title": "Autoscaling", "markdown": "# Autoscaling\n\nContainr has a built-in autoscaler that adjusts service replica counts against\nCPU/memory targets. Policies and scale events are held in backend memory —\nthey do not survive a backend restart (tracked on the roadmap).\n\n## Per-service policy\n\nOpen a service → **Scaling** section. Set:\n\n| Field | Meaning |\n|-------|---------|\n| Min replicas | Lower bound, ≥1 |\n| Max replicas | Upper bound |\n| Target CPU % | Scale up when average CPU exceeds this |\n| Target memory % | Scale up when average memory exceeds this |\n| Enabled | Whether the autoscaler evaluates this service |\n\nCreating a policy registers the service with the autoscaler and initializes\nits scaling state at `min_replicas`.\n\n## Manual scale\n\nThe Scaling section also has a replica input + **Scale** button for an\nimmediate change, clamped to the policy bounds when a policy exists\n(1–20 otherwise). Scaling dispatches to the node scheduler — without\nregistered node agents it fails with `no ready nodes available`.\n\n## API\n\n```\nGET /api/v1/scaling/policies/:serviceId\nPOST /api/v1/scaling/policies {service_id, min_replicas, max_replicas,\n target_cpu, target_memory, enabled}\nPUT /api/v1/scaling/policies/:serviceId\nDELETE /api/v1/scaling/policies/:serviceId (disables, does not remove)\nGET /api/v1/scaling/services/:serviceId (current/desired replicas)\nPOST /api/v1/scaling/services/:serviceId/scale {replicas, reason}\nGET /api/v1/scaling/services/:serviceId/history\nGET /api/v1/scaling/status | /metrics | /events\n```\n\n## Traffic distribution\n\nReplicas are scheduled across registered node agents. In front of them you\nstill want a load balancer — Traefik (bundled) discovers containers via\nlabels, or Cloudflare Tunnel can front the platform for external traffic.\nNeither provides autoscaling itself; they distribute traffic to whatever\nreplicas the autoscaler has placed.\n" }, { "path": "guides/AUTO_DEPLOY_GUIDE.md", "section": "guides", "title": "🚀 Zero-Interaction Docker Deployment System", "markdown": "# 🚀 Zero-Interaction Docker Deployment System\n\n## 🎯 **Fully Automatic Deployment**\n\nI've created a **completely automated deployment system** that requires **ZERO user interaction**. Just run one command and it does everything!\n\n## ⚡ **One-Click Deployment**\n\n### **Option 1: Quick Start (Recommended)**\n```bash\n# Run the quick deploy script\n./scripts/quick-deploy.sh\n```\n\n**What happens:**\n1. 🎯 **Shows you 6 deployment options**\n2. 🚀 **Deploys your choice automatically**\n3. 🔧 **Handles everything** (secrets, directories, ports)\n4. 🌐 **Shows access URLs** when done\n\n### **Option 2: Direct Command**\n```bash\n# Deploy any template instantly\n./scripts/auto-deploy.sh umami\n./scripts/auto-deploy.sh plex\n./scripts/auto-deploy.sh nextcloud\n```\n\n### **Option 3: Deploy Everything**\n```bash\n# Deploy all 20 templates at once\n./scripts/auto-deploy.sh --all\n```\n\n## 🔄 **What Happens Automatically**\n\n### **🔍 Dependency Check**\n```bash\n✅ Checks if Docker is installed\n✅ Installs Docker if missing\n✅ Checks if Docker Compose is installed \n✅ Installs Docker Compose if missing\n```\n\n### **📁 Directory Creation**\n```bash\n✅ Creates deployment directory\n✅ Creates required subdirectories\n✅ Sets proper permissions\n✅ Handles existing deployments\n```\n\n### **🔧 Configuration Setup**\n```bash\n✅ Extracts docker-compose.yml from template\n✅ Creates .env file with all variables\n✅ Auto-generates secrets and passwords\n✅ Fixes port conflicts automatically\n✅ Optimizes volume paths\n```\n\n### **🐳 Docker Deployment**\n```bash\n✅ Pulls all required images\n✅ Starts all services\n✅ Waits for services to be ready\n✅ Checks service health\n✅ Shows deployment status\n```\n\n### **🌐 Access Information**\n```bash\n✅ Shows all access URLs\n✅ Provides management commands\n✅ Shows deployment directory\n✅ Opens browser automatically (optional)\n```\n\n## 🎮 **Try It Now**\n\n### **Easiest Way:**\n```bash\n./scripts/quick-deploy.sh\n```\n\nYou'll see:\n```\n🚀 One-Click Docker Deployment\n============================\n\n🎯 Choose your deployment:\n\n1. 🌐 Deploy Glance Dashboard (Recommended - Simple & Fast)\n2. 📊 Deploy Umami Analytics (Web Analytics)\n3. 📝 Deploy Memos (Note-taking)\n4. 🔍 Deploy MeiliSearch (Search Engine)\n5. 📈 Deploy Uptime Kuma (Monitoring)\n6. 🚀 Deploy ALL Templates (Advanced)\n\nEnter your choice (1-6): 1\n\n🌐 Deploying Glance Dashboard...\n```\n\n### **Direct Way:**\n```bash\n# Deploy any template instantly\n./scripts/auto-deploy.sh glance\n```\n\n## 📊 **Example Output**\n\nHere's what you'll see during deployment:\n\n```\n🚀 Auto-Deploying glance\n========================================\n🔄 Checking dependencies...\n✅ Docker is installed\n✅ Docker Compose is installed\n🔄 Auto-deploying glance...\n✅ Created deployment directory: /path/to/deployments/glance\n🔄 Extracting docker-compose.yml...\n✅ docker-compose.yml extracted and optimized\n🔄 Creating .env file...\n✅ .env file created (no variables required)\n🔄 Auto-deploying glance...\n🔄 Pulling Docker images...\n✅ Images pulled\n🔄 Starting services...\n✅ Services started successfully\n\n🎉 Deployment Complete!\n========================================\n✅ Access URLs:\n 🌐 http://localhost:8080 (port: 8080)\n\n✅ Management Commands:\n 📋 View logs: docker-compose logs -f\n 🛑 Stop services: docker-compose down\n 🔄 Restart: docker-compose restart\n 📊 Status: docker-compose ps\n 🗑️ Cleanup: docker-compose down -v\n\n✅ Deployment directory: /path/to/deployments/glance\n🎉 glance deployed successfully!\n```\n\n## 🔧 **Advanced Options**\n\n### **Custom Configuration**\n```bash\n# Deploy without auto-generating secrets\n./scripts/auto-deploy.sh --no-secrets umami\n\n# Deploy without creating directories\n./scripts/auto-deploy.sh --no-dirs plex\n\n# Deploy without auto-starting services\n./scripts/auto-deploy.sh --no-start nextcloud\n\n# Deploy and auto-open browser\n./scripts/auto-deploy.sh --open-browser glance\n```\n\n### **Batch Deployment**\n```bash\n# Deploy multiple templates\nfor template in umami glance memos; do\n ./scripts/auto-deploy.sh \"$template\"\ndone\n\n# Deploy all templates\n./scripts/auto-deploy.sh --all\n```\n\n## 🛡️ **Safety Features**\n\n### **Automatic Conflict Resolution**\n```bash\n✅ Detects port conflicts\n✅ Auto-assigns available ports\n✅ Handles existing deployments\n✅ Cleans up previous installations\n```\n\n### **Security**\n```bash\n✅ Generates strong random secrets\n✅ Uses secure default passwords\n✅ Isolates deployments in separate directories\n✅ Logs all actions for audit trail\n```\n\n### **Error Handling**\n```bash\n✅ Validates template existence\n✅ Checks service health\n✅ Provides detailed error messages\n✅ Offers rollback commands\n```\n\n## 📁 **Directory Structure**\n\n```\nyour-project/\n├── scripts/\n│ ├── auto-deploy.sh # 🚀 Main auto-deployment script\n│ └── quick-deploy.sh # ⚡ Quick start script\n├── templates/\n│ ├── umami.md\n│ ├── plex.md\n│ └── ...\n└── deployments/ # 📁 Auto-created\n ├── glance/ # 📁 Template deployment\n │ ├── docker-compose.yml\n │ ├── .env\n │ ├── data/\n │ └── logs/\n ├── umami/\n └── plex/\n```\n\n## 🎯 **Template Difficulty Levels**\n\n| **Easy** (Auto-Deploy) | **Medium** (Auto-Deploy) | **Hard** (Auto-Deploy) |\n|------------------------|-------------------------|----------------------|\n| 🌐 Glance | 📊 Umami | 🗄️ Supabase |\n| 📝 Memos | 📈 Uptime Kuma | 🏠 Home Assistant |\n| 🔍 MeiliSearch | 🛡️ Vaultwarden | 📊 Grafana |\n| 🚪 Pi-hole | 📁 Cloudreve | 🐙 Gitea |\n| | 🌐 Traefik | 🦣 Mastodon |\n| | 🎬 Jellyfin | ☁️ Nextcloud |\n| | 📚 Plex | 🎬 Immich |\n| | 🔄 n8n | |\n\n## 🚀 **Ready to Use?**\n\n**Yes! The system is fully automatic. Just run:**\n\n```bash\n# Quick start (easiest)\n./scripts/quick-deploy.sh\n\n# Or direct deployment\n./scripts/auto-deploy.sh glance\n```\n\n**That's it!** 🎉\n\nThe system will:\n- ✅ **Install Docker** if needed\n- ✅ **Deploy your chosen service**\n- ✅ **Generate all secrets**\n- ✅ **Handle all configuration**\n- ✅ **Show you the access URL**\n- ✅ **Provide management commands**\n\n**Zero user interaction required!** 🚀\n" }, { "path": "guides/CLI.md", "section": "guides", "title": "Containr CLI", "markdown": "# Containr CLI\n\nThe CLI controls every part of a Containr instance — the same API surface\nthe web UI uses. Build it with `scripts/build-cli.sh` or\n`go build ./cmd/cli` from `app/backend`.\n\n## Authentication\n\nCreate a personal access token in the web UI under\n**Settings → Personal Access Tokens** (or `containr tokens create`), then:\n\n```bash\ncontainr auth login cnp_... # verify + store\ncontainr auth login cnp_... --url https://containr.example.com\ncontainr auth login cnp_... --name production # named profile\ncontainr auth status # show active profile + identity\ncontainr auth logout\n```\n\nResolution order for every command: `--token`/`--api-url` flags >\n`CONTAINR_TOKEN`/`CONTAINR_API_URL` env > active profile >\n`http://localhost:8080/api/v1`. The active profile is `--profile` >\n`CONTAINR_PROFILE` > `current_profile` in `~/.containr.yaml`.\n\n## Output and scripting\n\n- `--json` prints the raw API response — safe to pipe and parse.\n- `--yes` / `-y` skips confirmation on destructive commands (delete,\n revoke, restore, failover). Non-interactive shells refuse destructive\n commands without it.\n- Exit codes are stable: `0` ok, `1` error, `2` auth/permission,\n `3` not found, `4` validation, `5` unreachable.\n\n## Commands\n\n```\nauth login|logout|status token auth and profiles\ntokens list|create|revoke personal access tokens\nprojects list|get|create|delete\nservices list|get|create|update|delete|start|stop|restart|redeploy\nservices clone|move duplicate config or re-parent a service\nservices domains list|add|remove|default|check multi-domain + DNS preflight\nregistries list|add|update|remove private-image pull credentials\nvolumes list|delete docker volume inventory + cleanup (admin)\ndeploy trigger a deployment (--no-cache, --commit-hash, --branch)\ndeployments list|get|logs|rollback|cancel\nlogs [--follow] runtime logs (SSE follow)\nexec -- one-off container command\nvariables list|set|unset env vars (secrets masked; --redeploy applies them)\nvariables shared list|set|unset project shared vars — referenced as ${{shared.KEY}}\ndatabases list|get|create|update|delete|action|backup|restore|download-backup|import-backup\n import-backup uploads an archive as a restore\n point; ships offsite too when a backup target is assigned\ndatabases list|get|create|update|delete|action|backup|restore|download-backup\n create --public exposes the port on all interfaces;\n update --public/--public=false toggles it (container recreates, data persists)\ndatabases register register an external database (--type --host --port --database --username --password --ssl; probed before storing)\ndatabases test-connection probe a connection — by id, or ad-hoc flags\nbackup-targets list|add|update|remove|test\n S3-compatible archive destinations; add/update probe the bucket\n first, empty --access-key/--secret-key on update keep stored keys;\n update --backup-target assigns a target (\"\" clears it)\ncron list|get|create|delete|trigger|executions\ntemplates list|get|create|delete|deploy|plan|import-compose|deploy-graph\n deploy --name --var K=V; plan dry-resolves expressions;\n import-compose converts a compose file into\n a v2 graph config; deploy-graph \n deploys an ad-hoc service graph\nimport compose \n deploys a docker-compose file straight into a project —\n no template row. DB images become managed databases\n attached under their service name; --var K=V overrides\n template variables\nnodes list|get|delete|tokens node agents + onboarding tokens (admin)\nscaling status|policies|services|scale\nha status|alerts|health|policies|enable|disable|failover\nsecurity scan|vulnerabilities|metrics\ngateway services|keys|analytics (admin)\nadmin overview|users|settings|audit-logs\nnotifications list|read\nwebhooks list|create|update|delete|deliveries|test\n outbound signed webhooks — create \n --event 'service.*' (repeatable, '*' = all);\n deliveries are HMAC-signed (X-Containr-Signature)\noperations live ops view: active deploys, queue depth,\n 24h failures, cron runs, backups\nbanners list|create|update|delete announcement banners (admin);\n active banners print on `auth status`\nup deploy the current directory\n```\n\n## containr up\n\nRun inside a git checkout: uses `remote.origin.url` + the current branch\nas the build source, creates a service named after the directory when none\nexists, then triggers a deployment.\n\n```bash\ncontainr up --project \ncontainr up --project --image ghcr.io/example/app:latest # image, no build\n```\n\nSet `project_id` on the active profile to omit `--project` (stored in\n`~/.containr.yaml` under `profiles..project_id`).\n\n## Service volumes\n\n`services update` manages mounts; flags replace the whole mount list:\n\n```bash\ncontainr services update --volume data:/data --bind /srv/cfg:/etc/app:ro\ncontainr services update --clear-volumes\n```\n\n`type` is `volume` (docker named volume, auto-created) or `bind` (host\npath). `target` must be absolute. Mounts apply on the next deploy or\nredeploy — `containr deploy ` to apply immediately.\n\n`volumes list` shows the node's docker volume inventory with in-use\nflags; `volumes delete ` removes an unused volume (admin scope).\n\n## Service domains and access\n\nA service can carry multiple hostnames; the default is mirrored to\n`services.domain`:\n\n```bash\ncontainr services domains add app.example.com --default\ncontainr services domains check # DNS preflight per domain\ncontainr services domains remove \n```\n\nDNS check compares each domain to the expected target — set\n`app_settings.public_ip` (or `PUBLIC_IP` env) so `wrong-target` is\nmeaningful; without it any resolvable domain reports `ok`.\n\nAccess gates apply via Traefik middlewares (no extra proxy):\n\n```bash\ncontainr services update --maintenance on\ncontainr services update --basic-auth admin:secret --basic-auth ops:pw2\n```\n\nMaintenance mode redirects all traffic to `/api/v1/maintenance`\n— set `app_settings.base_url` or `BASE_URL`; without it the service is\ntaken offline with empty responses. Basic-auth credentials are stored\nbcrypt-hashed (htpasswd) and gate every request.\n\n## Build strategy and resources\n\nSource-built services pick a builder per service:\n\n```bash\ncontainr services update --builder railpack # auto|railpack|nixpacks|dockerfile|static\ncontainr services update --builder static --static-cmd \"npm run build\" --static-dir dist\n```\n\n`auto` detects from repo contents (Dockerfile → railpack → nixpacks).\n`static` builds assets in a node stage and serves them from nginx —\n`--static-cmd` runs inside the build stage (default\n`npm ci && npm run build`), `--static-dir` is copied into the nginx image\n(default `dist`, exposed on port 80).\n\nResource reservations complement the hard `cpu`/`memory` limits:\n\n```bash\ncontainr services update --cpu-reserve 0.25 --memory-reserve 128Mi\n```\n\n`cpu`/`memory` are hard caps (NanoCPUs/Memory); `cpu_reserve`/\n`memory_reserve` are soft hints (CPU shares, MemoryReservation). Empty\nstring clears. `app_settings.default_cpu`/`default_memory` change the\ninstance-level defaults used at service creation;\n`app_settings.capacity_policy=block` fails deployments whose requested\nmemory exceeds node capacity (default `warn` logs only).\n\n## Sleep mode (scale-to-zero)\n\nServices can scale to zero after an idle window and resume on traffic:\n\n```bash\ncontainr services update --sleep --sleep-idle 15 # enable, 15 min idle timeout\ncontainr services update --sleep=false # disable\ncontainr services sleep # sleep now\ncontainr services wake # resume now\ncontainr services env-check # flag empty vars + unresolved ${{refs}}\n```\n\nIdleness is measured as flat container network I/O over the configured\nwindow (swept every 30s). Sleeping removes the workload containers and —\nwhen the service has domains — installs a busybox placeholder that holds\nthe Traefik route at higher priority, serves a reloading \"waking\" page,\nand pings `GET /api/v1/internal/wake/:id` to reconcile the service back.\nThe API must be reachable from containers for the callback (containerized\ndeploys work via the shared network; bare-metal needs `HOST=0.0.0.0`).\n\n## Clone, move, registries\n\n`services clone` duplicates config, volumes, domains, access gates,\nbuilder settings, and variables — ciphertext secret values are copied\nverbatim (no decrypt/re-encrypt). The clone starts stopped:\n\n```bash\ncontainr services clone --name staging-api --project --environment preview\ncontainr services move # name conflicts → 409\n```\n\nNote: cloned domains are verbatim copies — the same hostname attached to\ntwo services makes Traefik routing ambiguous. Re-domain or undeploy one.\n\n`registries` stores private-image pull credentials, owner-scoped and\nencrypted at rest. Matched by image host on every image-sourced deploy:\n\n```bash\ncontainr registries add ghcr ghcr.io --username --password \ncontainr registries add hub docker.io --username --password # Docker Hub\ncontainr registries update --username # empty --password keeps stored\ncontainr registries remove \n```\n\n## MCP server\n\n`containr-mcp` (`go build ./cmd/mcp`) exposes the same API as MCP tools\nover stdio — every command group above maps to a `containr_*` tool\n(~60 tools). Destructive tools require the caller to pass\n`confirm: true`; results are pretty JSON with `isError` on failures.\n\nClient configuration (Claude Code, Cursor, Devin, any stdio MCP host):\n\n```json\n{\n \"mcpServers\": {\n \"containr\": {\n \"command\": \"containr-mcp\",\n \"env\": {\n \"CONTAINR_API_URL\": \"https://containr.example.com\",\n \"CONTAINR_TOKEN\": \"cnp_...\"\n }\n }\n }\n}\n```\n\nScope the token deliberately: `read` is enough for inspection agents,\n`write` for deploy automation, `admin` only for platform operations.\n\nDeployments are serialized per service: a second `deploy` on a busy\nservice lands in `queued` state and runs when the active one finishes.\n`deployments cancel ` drops a queued deployment or aborts a running\none (builds/reconciles stop via context cancellation).\n" }, { "path": "guides/CLOUDFLARE_SETUP.md", "section": "guides", "title": "Cloudflare Tunnel Setup", "markdown": "# Cloudflare Tunnel Setup\n\nThis guide explains how to set up Cloudflare tunnel for Containr, allowing you to expose your services without configuring a domain.\n\n## Prerequisites\n\n1. A Cloudflare account\n2. A domain (any domain, even a free one)\n\n## Setup Steps\n\n### 1. Create a Cloudflare Tunnel\n\n1. Log in to your [Cloudflare Dashboard](https://dash.cloudflare.com/)\n2. Go to **Zero Trust** → **Networks** → **Tunnels**\n3. Click **Create tunnel**\n4. Choose **Cloudflared** and click **Next**\n5. Give your tunnel a name (e.g., \"containr-tunnel\")\n6. Click **Save tunnel**\n\n### 2. Get Your Tunnel Token\n\nAfter creating the tunnel, Cloudflare will show you a command like:\n```bash\ncloudflared tunnel run \n```\n\nCopy the token from the `.cloudflared/config.yml` file or use the token provided by Cloudflare.\n\n### 3. Configure Containr\n\n1. Copy `.env.example` to `.env` if you haven't already:\n ```bash\n cp .env.example .env\n ```\n\n2. Edit `.env` and add your Cloudflare tunnel token:\n ```env\n CLOUDFLARED_TOKEN=your_copied_tunnel_token_here\n ```\n\n### 4. Start Services with Cloudflare Tunnel\n\n```bash\n# Start all services including cloudflared\nmake cloudflared-up\n\n# Or start manually\ndocker-compose --profile cloudflared up -d\n```\n\n### 5. Configure Tunnel Routes\n\nIn your Cloudflare dashboard:\n\n1. Go to your tunnel settings\n2. Add the following public hostnames:\n - `your-domain.com` → `http://traefik:80` (for frontend)\n - `api.your-domain.com` → `http://traefik:80` (for backend)\n - `traefik.your-domain.com` → `http://traefik:80` (for dashboard)\n\n### 6. Access Your Services\n\nOnce configured, you can access:\n- Frontend: `https://your-domain.com`\n- API: `https://api.your-domain.com`\n- Traefik Dashboard: `https://traefik.your-domain.com`\n\n## Management Commands\n\n```bash\n# Start with Cloudflare tunnel\nmake cloudflared-up\n\n# Stop Cloudflare tunnel\nmake cloudflared-down\n\n# View logs\ndocker-compose logs -f cloudflared\n\n# Check status\ndocker-compose ps\n```\n\n## Benefits\n\n- **No domain configuration required** in `.env`\n- **Automatic SSL** through Cloudflare\n- **DDoS protection** and security features\n- **Easy setup** - just need a tunnel token\n- **Works anywhere** - no port forwarding needed\n\n## Troubleshooting\n\n### Tunnel Not Connecting\n- Verify your `CLOUDFLARED_TOKEN` is correct\n- Check cloudflared logs: `docker-compose logs cloudflared`\n- Ensure your tunnel is active in Cloudflare dashboard\n\n### Services Not Accessible\n- Verify you've configured the public hostnames in Cloudflare\n- Check that all services are running: `docker-compose ps`\n- Ensure the tunnel routes point to `http://traefik:80`\n\n### Token Issues\n- Regenerate your tunnel token in Cloudflare dashboard\n- Make sure there are no extra spaces or newlines in the token\n\n## Alternative: Domain Mode\n\nIf you prefer traditional domain setup instead of Cloudflare tunnel:\n\n1. Configure your domain in `.env`:\n ```env\n DOMAIN=yourdomain.com\n ACME_EMAIL=admin@yourdomain.com\n ```\n\n2. Use regular commands:\n ```bash\n make prod\n ```\n\nThis will use Let's Encrypt certificates instead of Cloudflare tunnel.\n" }, { "path": "guides/DOCKER_SETUP.md", "section": "guides", "title": "Docker Setup with Traefik", "markdown": "# Docker Setup with Traefik\n\nThis guide will help you set up Containr with Docker, Traefik reverse proxy, and automatic SSL certificates.\n\n## Prerequisites\n\n- Docker and Docker Compose installed\n- A domain name pointing to your server's IP address\n- Port 80 and 443 open on your firewall\n\n## Quick Start\n\n1. **Clone and prepare the environment:**\n ```bash\n git clone \n cd containr\n cp .env.example .env\n ```\n\n2. **Configure your environment:**\n Edit `.env` file with your settings:\n ```bash\n nano .env\n ```\n \n Required changes:\n - `DOMAIN=yourdomain.com` - Your actual domain\n - `ACME_EMAIL=admin@yourdomain.com` - Email for SSL certificates\n - `POSTGRES_PASSWORD` - Set a secure password\n - `REDIS_PASSWORD` - Set a secure password\n - `JWT_SECRET` - Generate a secure random string\n - `TRAEFIK_AUTH` - Generate basic auth for dashboard\n\n3. **Generate Traefik authentication:**\n ```bash\n # Install apache2-utils if needed\n sudo apt-get install apache2-utils\n \n # Generate username:password hash\n htpasswd -nb admin yourpassword\n \n # Update TRAEFIK_AUTH in .env with the output\n ```\n\n4. **Create necessary directories:**\n ```bash\n mkdir -p data/letsencrypt\n chmod 600 data/letsencrypt/acme.json\n ```\n\n5. **Start the services:**\n ```bash\n docker-compose up -d\n ```\n\n## Services and URLs\n\nAfter deployment, your services will be available at:\n\n- **Frontend**: `https://yourdomain.com`\n- **Backend API**: `https://api.yourdomain.com`\n- **Traefik Dashboard**: `https://traefik.yourdomain.com`\n\n## Architecture\n\n```\nInternet → Traefik (Port 80/443)\n ├── Frontend (React/Nginx)\n ├── Backend (Go API)\n ├── PostgreSQL (Database)\n └── Dragonfly (Cache)\n```\n\n## Configuration Files\n\n### Docker Compose\n- `docker-compose.yml` - Main orchestration file\n- Defines all services, networks, and volumes\n- Configures Traefik with automatic SSL\n\n### Traefik Configuration\n- `traefik.yml` - Static configuration\n- `traefik-dynamic.yml` - Dynamic routing rules\n- Automatic HTTP to HTTPS redirection\n- Security headers and rate limiting\n\n### Dockerfiles\n- `Dockerfile.backend` - Go backend with multi-stage build\n- `Dockerfile.frontend` - React frontend with Nginx\n- Both use non-root users for security\n\n## Security Features\n\n- **Automatic SSL** via Let's Encrypt\n- **HTTP to HTTPS** redirection\n- **Security headers** (HSTS, XSS protection, etc.)\n- **Rate limiting** on API endpoints\n- **Basic authentication** on Traefik dashboard\n- **Non-root containers** for all services\n- **Health checks** for all services\n\n## Monitoring and Logs\n\n### Traefik Dashboard\nAccess at `https://traefik.yourdomain.com` with your configured credentials.\n\n### Logs\n```bash\n# View all logs\ndocker-compose logs -f\n\n# View specific service logs\ndocker-compose logs -f traefik\ndocker-compose logs -f backend\ndocker-compose logs -f frontend\n```\n\n### Health Checks\nAll services include health checks:\n```bash\n# Check service status\ndocker-compose ps\n```\n\n## Maintenance\n\n### Updates\n```bash\n# Pull latest images\ndocker-compose pull\n\n# Recreate services with new images\ndocker-compose up -d --force-recreate\n```\n\n### Backups\n```bash\n# Backup PostgreSQL\ndocker-compose exec postgres pg_dump -U containr_user containr > backup.sql\n\n# Backup Dragonfly (snapshot)\ndocker-compose exec dragonfly redis-cli -a \"$REDIS_PASSWORD\" save\n```\n\n### SSL Certificates\nLet's Encrypt certificates are automatically renewed. Manual renewal:\n```bash\ndocker-compose exec traefik traefik api check-letsencrypt\n```\n\n## Development Mode\n\nFor local development without SSL:\n```bash\n# Create development override\ncat > docker-compose.override.yml << EOF\nversion: '3.8'\nservices:\n traefik:\n command:\n - \"--api.dashboard=true\"\n - \"--providers.docker=true\"\n - \"--entrypoints.web.address=:80\"\n - \"--log.level=DEBUG\"\n ports:\n - \"80:80\"\n - \"8080:8080\"\n labels:\n - \"traefik.http.routers.traefik.rule=Host(`localhost`)\"\n - \"traefik.http.routers.traefik.entrypoints=web\"\n - \"traefik.http.routers.traefik.service=api@internal\"\nEOF\n\n# Start with override\ndocker-compose up -d\n```\n\n## Troubleshooting\n\n### Common Issues\n\n1. **SSL Certificate Issues**\n ```bash\n # Check acme.json permissions\n ls -la data/letsencrypt/acme.json\n \n # Reset certificates\n rm data/letsencrypt/acme.json\n docker-compose restart traefik\n ```\n\n2. **Port Conflicts**\n ```bash\n # Check what's using ports\n sudo netstat -tlnp | grep :80\n sudo netstat -tlnp | grep :443\n ```\n\n3. **Database Connection**\n ```bash\n # Test database connection\n docker-compose exec backend ping postgres\n ```\n\n4. **Permission Issues**\n ```bash\n # Fix volume permissions\n sudo chown -R 1001:1001 data/\n ```\n\n### Performance Tuning\n\n1. **Nginx Caching** - Already configured in `nginx.conf`\n2. **Dragonfly Caching** - Configure in your application\n3. **Database Pooling** - Adjust connection limits in Go app\n\n## Production Tips\n\n1. **Monitoring** - Set up Prometheus/Grafana\n2. **Alerting** - Configure alerts for service failures\n3. **Backup Strategy** - Automated database backups\n4. **Load Testing** - Test before production deployment\n5. **Security Audit** - Regular security scans\n\n## Support\n\nFor issues:\n1. Check logs: `docker-compose logs`\n2. Verify configuration: `docker-compose config`\n3. Check service status: `docker-compose ps`\n4. Review Traefik dashboard for routing issues\n" }, { "path": "guides/OPERATIONS.md", "section": "guides", "title": "Operations", "markdown": "# Operations\n\nDay-2 features for running services: scheduled jobs, ad-hoc exec, managed\ndatabases, preview environments, security scans, and high availability.\n\n## Cron jobs\n\nService detail → **Cron**. Standard 5-field cron expressions (`robfig/cron`\nsyntax), per-job timezone, enable/disable, manual trigger, and execution\nhistory with captured stdout/stderr.\n\n- The scheduler ticks every minute and runs due jobs via `docker exec`\n (`sh -c `) inside the service's container.\n- Executions are retained per-job (`retention` count) and visible in the UI.\n- Requires a running container — a stopped service's due job records a\n failure, it does not queue.\n\n```\nGET/POST /api/v1/cron-jobs PUT/DELETE /api/v1/cron-jobs/:id\nPOST /api/v1/cron-jobs/:id/trigger\nGET /api/v1/cron-jobs/:id/executions\n```\n\n## Exec console\n\nService detail → **Console**. One-off `sh -c` commands against the running\ncontainer: 30s ceiling, 64KB output cap, exit code + captured output shown\nper run. Debugging aid — not an interactive shell.\n\n```\nPOST /api/v1/services/:id/exec {command}\n```\n\n## Managed databases\n\n**/databases** page — provision PostgreSQL/Redis/MySQL/MariaDB/MongoDB/\nClickHouse/Dragonfly as managed containers on the `containr` network.\n\n- Start/stop/restart actions; connection URL with copy.\n- **Backups**: manual snapshot now, or set a cron expression\n (`backup_schedule`) — due backups run inside the same scheduler tick as\n cron jobs. Archives live in the `containr-db-backups` volume and are\n downloadable (`GET /databases/:id/backups/:bid/download`) and restorable.\n- **Bind to service**: injects `connection_url` into a service's variables\n as a secret (`DATABASE_URL` by default). Redeploy the service afterward —\n variables are read at deploy time.\n\n## Preview environments\n\nService detail → **Previews**. Create a preview per branch/PR with a TTL,\npromote it to production, or delete it.\n\nCurrent limitation: previews are bookkeeping records — they do not build,\ndeploy, or route a real container. The generated `*.preview.containr.local`\nURL is a placeholder. Real preview runtime is tracked on the roadmap.\n\n## Security scans\n\n**/security** page — pick a project, run a scan (dependency / configuration\n/ comprehensive, optionally scoped to one service).\n\nThe scanner is heuristic config analysis, not Trivy/Grype: it flags\nunpinned image tags, `http://` source/public URLs, `npm install` without\n`npm ci`, `pip install` without hashes, `curl|sh` build steps, missing\nhealth checks, and similar smells. Findings get severity badges and can be\nresolved or ignored; the page also shows a security score, open/resolved\ncounts, scan history, and compliance status.\n\n```\nPOST /api/v1/security/scans {project_id, service_id?, scan_type}\nGET /api/v1/projects/:id/vulnerabilities\nPUT /api/v1/vulnerabilities/:id {status: open|resolved|ignored}\nGET /api/v1/projects/:id/security/metrics\nGET /api/v1/projects/:id/security/history\n```\n\n## High availability\n\n**/ha** page — manager enable/disable, node/health-check/alert status\ncards, manual failover (with confirmation), per-service failover policies\n(project → service picker, strategy, min healthy nodes, max failures),\nactive alerts with resolve, and health check results.\n\nHA state is in-memory like autoscaling — policies and alerts reset on\nbackend restart.\n\n## Node agents\n\n**/usage** page → *Connect node*: issue a per-node token (`cagt_…`, shown\nonce), copy the prefilled install command, revoke tokens when done. Agents\nregister over `POST /api/agents/register` and heartbeat via\n`POST /api/agents/heartbeat`.\n\n## Personal access tokens\n\n**Settings → Personal Access Tokens**: issue `cnp_…` bearer tokens for the\nCLI, MCP server, and scripts — the same privileges as your account, bounded\nby scope. The raw token is shown once at creation; only its SHA-256 hash is\nstored.\n\nScopes:\n\n- `read` — `GET`/`HEAD`/`OPTIONS` only; mutations return `403 SCOPE_INSUFFICIENT`.\n- `write` — everything except admin routes.\n- `admin` — full access; requires a platform admin account, and the token is\n still capped at the owner's privileges.\n\nA token can never outrank its owner: non-admin scopes report\n`is_admin = false` even on admin accounts.\n\n```\nGET /api/v1/user/tokens list (metadata only, never hashes)\nPOST /api/v1/user/tokens {name, scope?, expires_in_days?} → raw token once\nDELETE /api/v1/user/tokens/:id revoke (owner-scoped)\n```\n\nUse as `Authorization: Bearer cnp_…`, or `containr auth login cnp_…`.\nRevocation takes effect on the next request; `last_used_at` updates on each\nauthenticated call.\n\n## Deployment queue\n\nDeployments are serialized per service: a deploy while another is active\nlands in `queued` state and promotes when it finishes — deploys, rollbacks,\nredeploys, and variable-apply reconciles can never race on the same service.\n`POST /deployments/:id/cancel` drops queued work or aborts running builds.\nRows left in-flight by a server restart are marked `failed` on boot.\nWebhook-triggered deploys build with `no_cache` by default.\n\n## Secret variables\n\nVariables with `is_secret` are AES-GCM-encrypted at rest (`enc:v1:` prefix).\nKey derivation: `SECRETS_KEY` env var if set, else `JWT_SECRET`. Existing\nplaintext secrets are encrypted on boot; reads for deploy/exec decrypt\ntransparently. Rotating the key makes stored secrets unreadable — re-save\nthem after rotation.\n" }, { "path": "guides/README_BACKEND.md", "section": "guides", "title": "Containr Backend Setup", "markdown": "# Containr Backend Setup\n\n## Quick Start\n\n### Prerequisites\n- Go 1.21+\n- PostgreSQL 12+\n- Dragonfly or Redis-compatible cache (optional)\n\n### Environment Variables\n\nCreate a `.env` file or set these environment variables:\n\n```bash\n# Database\nDATABASE_URL=postgres://containr:password@localhost:5432/containr?sslmode=disable\nREDIS_URL=redis://localhost:6379\n\n# Server\nPORT=8080\nENVIRONMENT=development\n\n# Security\nJWT_SECRET=your-secret-key-change-in-production\n\n# Frontend (for CORS)\nFRONTEND_URL=http://localhost:3000\n```\n\n### Database Setup\n\n1. Create PostgreSQL database:\n```sql\nCREATE DATABASE containr;\nCREATE USER containr WITH PASSWORD 'password';\nGRANT ALL PRIVILEGES ON DATABASE containr TO containr;\n```\n\n2. Run migrations (handled automatically on server start)\n\n### Running the Server\n\n```bash\n# Build\ngo build -o bin/server cmd/server/main.go\n\n# Run\n./bin/server\n```\n\nThe server will start on `http://localhost:8080`\n\n### API Endpoints\n\n#### Health Check\n- `GET /health` - Server health status\n\n#### Authentication\n- `POST /api/v1/auth/login` - User login\n- `POST /api/v1/auth/register` - User registration\n\n#### User Profile\n- `GET /api/v1/user/profile` - Get user profile (requires auth)\n- `PUT /api/v1/user/profile` - Update user profile (requires auth)\n\n#### Projects\n- `GET /api/v1/projects` - List user projects (requires auth)\n- `POST /api/v1/projects` - Create project (requires auth)\n- `GET /api/v1/projects/:id` - Get project details (requires auth)\n- `PUT /api/v1/projects/:id` - Update project (requires auth)\n- `DELETE /api/v1/projects/:id` - Delete project (requires auth)\n\n### Authentication\n\nInclude JWT token in Authorization header:\n```\nAuthorization: Bearer \n```\n\n### Example Usage\n\n1. Register a user:\n```bash\ncurl -X POST http://localhost:8080/api/v1/auth/register \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"email\": \"test@example.com\",\n \"password\": \"password123\",\n \"name\": \"Test User\"\n }'\n```\n\n2. Login:\n```bash\ncurl -X POST http://localhost:8080/api/v1/auth/login \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"email\": \"test@example.com\",\n \"password\": \"password123\"\n }'\n```\n\n3. Create a project (using token from login):\n```bash\ncurl -X POST http://localhost:8080/api/v1/projects \\\n -H \"Content-Type: application/json\" \\\n -H \"Authorization: Bearer \" \\\n -d '{\n \"name\": \"My Project\",\n \"description\": \"A test project\"\n }'\n```\n\n## Development\n\n### Project Structure\n```\ncmd/server/ - Main application entry point\ninternal/\n├── api/ - HTTP handlers and routes\n├── config/ - Configuration management\n├── database/ - Database connections and migrations\n└── middleware/ - HTTP middleware\nmigrations_goose/ - Goose-managed migrations (single migration path)\n```\n\n### Adding New Endpoints\n\n1. Create handler functions in `internal/api/`\n2. Add routes in `internal/api/routes.go`\n3. Update database schema if needed in `migrations_goose/` (goose format: `-- +goose Up/Down`)\n" }, { "path": "guides/SETUP_GUIDE.md", "section": "guides", "title": "Docker Template Auto-Setup Guide", "markdown": "# Docker Template Auto-Setup Guide\n\n## 🚀 How It Works\n\nThe templates are **configuration files** that define how to run each service with Docker Compose. They don't auto-execute - you need to use the setup script to deploy them.\n\n## 📋 Quick Start\n\n### 1. Interactive Mode (Recommended)\n```bash\n# Run the setup script interactively\n./scripts/setup-template.sh\n```\n\n### 2. Direct Template Selection\n```bash\n# Setup a specific template\n./scripts/setup-template.sh umami\n\n# List all available templates\n./scripts/setup-template.sh --list\n\n# Setup only (don't deploy)\n./scripts/setup-template.sh --setup umami\n\n# Deploy existing setup\n./scripts/setup-template.sh --deploy umami\n```\n\n## 🔄 What the Script Does\n\n### Step 1: Dependency Check\n- ✅ Verifies Docker is installed\n- ✅ Verifies Docker Compose is installed\n- ✅ Checks template directory exists\n\n### Step 2: Template Selection\n- 📋 Shows available templates with descriptions\n- 🎯 Lets you choose interactively or via command line\n\n### Step 3: Project Setup\n- 📁 Creates deployment directory (`template-name-deployment/`)\n- 📄 Extracts `docker-compose.yml` from template\n- 🔧 Creates `.env` file template with required variables\n- ⚠️ Shows setup requirements and warnings\n\n### Step 4: Deployment (Optional)\n- 🐳 Pulls Docker images\n- 🚀 Starts services with `docker-compose up -d`\n- 📊 Shows service status and access URLs\n- 📝 Provides useful commands\n\n## 📁 Directory Structure After Setup\n\n```\nyour-project/\n├── scripts/\n│ └── setup-template.sh # Auto-setup script\n├── templates/\n│ ├── umami.md # Template documentation\n│ ├── plex.md\n│ ├── immich.md\n│ └── ...\n└── umami-deployment/ # Created by setup script\n ├── docker-compose.yml # Extracted from template\n ├── .env # Environment variables\n └── README.md # Setup instructions\n```\n\n## 🎯 Interactive Walkthrough Example\n\n### Running Umami Setup:\n```bash\n$ ./scripts/setup-template.sh\n\n========================================\nChecking Dependencies\n========================================\n✅ Docker is installed\nDocker version: 24.0.6\n✅ Docker Compose is installed\nDocker Compose version: 2.21.0\n✅ All dependencies are met\n\n========================================\nSelect Template\n========================================\n 1) umami - Umami Analytics - Privacy-focused web analytics\n 2) plex - Plex Media Server - Media streaming and organization\n 3) immich - Immich - Photo and video backup solution\n ...\nSelect a template (1-20): 1\n✅ Selected template: umami\n\n========================================\nSetting up umami\n========================================\n✅ Created project directory: /path/to/umami-deployment\n✅ docker-compose.yml extracted\n⚠️ This template requires environment variables:\n- `DATABASE_URL`: PostgreSQL connection string\n- `APP_SECRET`: Random string for application secrets\n✅ Created .env template file\n⚠️ Please edit umami-deployment/.env with your values before starting\n\nDo you want to deploy the template now? (y/N): y\n\n========================================\nDeploying umami\n========================================\n✅ Pulling Docker images...\n✅ Starting services...\n✅ Deployment completed!\n\n========================================\nAccess Information\n========================================\n✅ Service access URLs:\n • http://localhost:3000 (container port: 3000)\n\nUseful commands:\n • View logs: docker-compose logs -f\n • Stop services: docker-compose down\n • Restart services: docker-compose restart\n • Update services: docker-compose pull && docker-compose up -d\n```\n\n## 🔧 Manual Setup (Without Script)\n\nIf you prefer manual setup:\n\n1. **Choose a template** from `/templates/`\n2. **Copy the docker-compose.yml** section\n3. **Create a project directory**\n4. **Set up environment variables**\n5. **Run `docker-compose up -d`**\n\nExample for Umami:\n```bash\nmkdir umami-deployment\ncd umami-deployment\n\n# Copy docker-compose.yml from templates/umami.md\n# Create .env file with required variables\ndocker-compose up -d\n```\n\n## 🎛️ Available Templates\n\n| Template | Description | Difficulty |\n|----------|-------------|------------|\n| **umami** | Web Analytics | Easy |\n| **plex** | Media Server | Medium |\n| **immich** | Photo Backup | Medium |\n| **n8n** | Workflow Automation | Medium |\n| **supabase** | Backend Service | Hard |\n| **home-assistant** | Smart Home | Medium |\n| **uptime-kuma** | Monitoring | Easy |\n| **grafana** | Metrics Dashboard | Medium |\n| **traefik** | Reverse Proxy | Medium |\n| **memos** | Note-taking | Easy |\n| **meilisearch** | Search Engine | Easy |\n| **vaultwarden** | Password Manager | Medium |\n| **pihole** | DNS Blocker | Medium |\n| **appwrite** | Backend Platform | Hard |\n| **gitea** | Git Hosting | Medium |\n| **mastodon** | Social Network | Hard |\n| **jellyfin** | Media Server | Medium |\n| **nextcloud** | Cloud Storage | Hard |\n| **glance** | Dashboard | Easy |\n| **cloudreve** | File Manager | Medium |\n\n## 🛠️ Advanced Usage\n\n### Custom Deployment Directory\n```bash\n# Set custom deployment directory\nexport DEPLOY_DIR=\"/opt/my-services\"\n./scripts/setup-template.sh umami\n```\n\n### Batch Setup\n```bash\n# Setup multiple templates\nfor template in umami plex nextcloud; do\n ./scripts/setup-template.sh --setup \"$template\"\ndone\n```\n\n### Production Deployment\n```bash\n# Setup with production considerations\n./scripts/setup-template.sh --setup umami\ncd umami-deployment\n\n# Edit .env with production values\n# Configure reverse proxy\n# Set up SSL certificates\n# Run deployment\n./scripts/setup-template.sh --deploy umami\n```\n\n## 🔍 Troubleshooting\n\n### Common Issues\n\n1. **Docker not installed**\n ```bash\n # Install Docker\n curl -fsSL https://get.docker.com -o get-docker.sh\n sudo sh get-docker.sh\n ```\n\n2. **Permission denied**\n ```bash\n # Add user to docker group\n sudo usermod -aG docker $USER\n # Log out and back in\n ```\n\n3. **Port conflicts**\n ```bash\n # Check what's using ports\n netstat -tulpn | grep :3000\n # Modify docker-compose.yml to use different ports\n ```\n\n4. **Environment variables not set**\n ```bash\n # Edit .env file\n nano umami-deployment/.env\n # Replace change_me values\n ```\n\n### Getting Help\n\nEach template includes:\n- ✅ **Complete setup instructions**\n- ✅ **Environment variable explanations**\n- ✅ **Troubleshooting section**\n- ✅ **Backup strategies**\n- ✅ **Performance optimization**\n\n## 🎯 Next Steps\n\n1. **Try the interactive setup**:\n ```bash\n ./scripts/setup-template.sh\n ```\n\n2. **Start with an easy template** (umami, glance, memos)\n\n3. **Read the template documentation** before deployment\n\n4. **Check the troubleshooting section** if you encounter issues\n\n5. **Join the community** for each service for additional support\n\n## 📞 Support\n\nFor issues with:\n- **Setup script**: Create an issue in this repository\n- **Specific service**: Check the service's official documentation\n- **Docker issues**: Refer to Docker documentation\n\nEach template includes links to official documentation and community support channels.\n" }, { "path": "guides/advanced-configuration.md", "section": "guides", "title": "Advanced Configuration Guide", "markdown": "# Advanced Configuration Guide\n\nThis guide covers advanced configuration options for optimizing your Containr deployments.\n\n## Table of Contents\n\n- [Build Configuration](#build-configuration)\n- [Environment Management](#environment-management)\n- [Resource Allocation](#resource-allocation)\n- [Networking](#networking)\n- [Security](#security)\n- [Scaling Policies](#scaling-policies)\n- [Custom Domains and SSL](#custom-domains-and-ssl)\n- [Health Checks](#health-checks)\n\n## Build Configuration\n\n### Nixpacks Configuration\n\nNixpacks is the default build system. You can customize it using a `nixpacks.toml` file:\n\n```toml\n# nixpacks.toml\n[phases.setup]\nnixPkgs = [\"...\", \"nodejs\", \"npm\"]\n\n[phases.build]\ncmds = [\"npm run build\"]\n\n[start]\ncmd = \"npm start\"\n\n[variables]\nNODE_ENV = \"production\"\nPORT = \"8080\"\n```\n\n### Custom Dockerfile\n\nFor complex applications, use a custom Dockerfile:\n\n```dockerfile\n# Dockerfile\nFROM node:18-alpine AS builder\n\nWORKDIR /app\nCOPY package*.json ./\nRUN npm ci --only=production\n\nCOPY . .\nRUN npm run build\n\nFROM node:18-alpine AS runtime\n\nWORKDIR /app\nCOPY --from=builder /app/dist ./dist\nCOPY --from=builder /app/node_modules ./node_modules\nCOPY package*.json ./\n\nEXPOSE 8080\nUSER node\nCMD [\"npm\", \"start\"]\n```\n\n### Build Caching\n\nEnable build caching for faster deployments:\n\n1. Go to service settings\n2. Enable \"Build Caching\"\n3. Configure cache settings:\n - **Cache TTL**: Time to keep cached layers (default: 7 days)\n - **Max Cache Size**: Maximum cache size per service\n\n### Multi-Stage Builds\n\nOptimize image size with multi-stage builds:\n\n```dockerfile\n# Build stage\nFROM golang:1.21 AS builder\nWORKDIR /app\nCOPY go.mod go.sum ./\nRUN go mod download\nCOPY . .\nRUN CGO_ENABLED=0 go build -o app\n\n# Runtime stage\nFROM alpine:latest\nRUN apk --no-cache add ca-certificates\nWORKDIR /root/\nCOPY --from=builder /app/app .\nEXPOSE 8080\nCMD [\"./app\"]\n```\n\n## Environment Management\n\n### Environment Scopes\n\nVariables can be scoped at different levels:\n\n```bash\n# Project-level (shared across all services)\nDATABASE_URL=postgresql://...\n\n# Service-level (specific to one service)\nAPI_KEY=service-specific-key\n\n# Environment-specific (production only)\nNODE_ENV=production\nDEBUG=false\n```\n\n### Variable Types\n\n#### Plain Text Variables\n```bash\nAPI_KEY=your-api-key-here\n```\n\n#### Secret Variables\n```bash\n# Marked as secret in UI - masked in logs\nDATABASE_PASSWORD=super-secret-password\n```\n\n#### File Variables\nFor configuration files:\n```bash\n# Upload .env file as variable\nENV_FILE_CONTENT=KEY1=value1\\nKEY2=value2\n```\n\n### Dynamic Variables\n\nUse Containr's built-in variables:\n\n```bash\n# Auto-populated by Containr\nPORT=8080 # Assigned port\nCONTAINR_SERVICE_NAME=my-app # Service name\nCONTAINR_PROJECT_NAME=my-proj # Project name\nCONTAINR_DEPLOYMENT_ID=abc123 # Deployment ID\n```\n\n## Resource Allocation\n\n### CPU Allocation\n\nConfigure CPU limits and requests:\n\n```yaml\n# Service resource configuration\nresources:\n cpu:\n request: \"100m\" # Minimum CPU (0.1 core)\n limit: \"1000m\" # Maximum CPU (1 core)\n memory:\n request: \"128Mi\" # Minimum memory\n limit: \"512Mi\" # Maximum memory\n```\n\n### Memory Allocation\n\nMemory configuration examples:\n\n```yaml\n# Small service (API, worker)\nresources:\n memory: \"256Mi\"\n\n# Medium service (web app)\nresources:\n memory: \"512Mi\"\n\n# Large service (database, analytics)\nresources:\n memory: \"2Gi\"\n```\n\n### Storage Allocation\n\nPersistent storage for databases:\n\n```yaml\n# Database service\nresources:\n storage:\n size: \"10Gi\"\n type: \"ssd\"\n backup: true\n```\n\n## Networking\n\n### Service-to-Service Communication\n\nServices can communicate internally:\n\n```bash\n# Environment variables for internal URLs\nDATABASE_URL=postgresql://my-db:5432/myapp\nREDIS_URL=redis://my-redis:6379\nAPI_URL=http://my-api:8080\n```\n\n### Port Configuration\n\nConfigure service ports:\n\n```yaml\n# Service configuration\nnetworking:\n port: 8080 # Internal port\n public: true # Expose publicly\n health_check: \"/health\" # Health check endpoint\n```\n\n### Custom Domains\n\nSet up custom domains:\n\n1. Go to service settings → \"Domains\"\n2. Add your domain: `app.yourdomain.com`\n3. Configure DNS:\n ```\n CNAME app.yourdomain.com -> your-service.containr.app\n ```\n4. Wait for SSL certificate provisioning\n\n### Load Balancing\n\nConfigure load balancing strategies:\n\n```yaml\n# Load balancer configuration\nload_balancer:\n strategy: \"round_robin\" # round_robin, least_connections, ip_hash\n health_check:\n path: \"/health\"\n interval: \"30s\"\n timeout: \"5s\"\n retries: 3\n```\n\n## Security\n\n### Security Scans\n\nEnable automated security scanning:\n\n1. Go to project settings → \"Security\"\n2. Enable \"Security Scanning\"\n3. Configure scan frequency:\n - **On every deployment**\n - **Daily**\n - **Weekly**\n\n### Vulnerability Management\n\nReview and manage vulnerabilities:\n\n```bash\n# Security scan results\nCritical: 2 vulnerabilities\nHigh: 5 vulnerabilities\nMedium: 12 vulnerabilities\nLow: 8 vulnerabilities\n```\n\n### Network Policies\n\nRestrict network access:\n\n```yaml\n# Network policy example\nnetwork_policy:\n egress:\n - allow:\n - dns: true\n - http: [\"api.example.com\"]\n - https: [\"github.com\", \"registry.npmjs.org\"]\n ingress:\n - allow:\n - port: 8080\n from: [\"load-balancer\"]\n```\n\n### Secrets Management\n\nBest practices for secrets:\n\n1. **Never commit secrets** to version control\n2. **Use Containr secrets** for sensitive data\n3. **Rotate secrets regularly**\n4. **Use least privilege** principle\n\n```bash\n# Good: Use environment variables\nDATABASE_URL=${DATABASE_URL}\n\n# Bad: Hardcoded secrets\nDATABASE_URL=postgresql://user:password@host:5432/db\n```\n\n## Scaling Policies\n\n### Manual Scaling\n\nSet replica count manually:\n\n```yaml\n# Manual scaling configuration\nscaling:\n replicas: 3 # Run 3 instances\n```\n\n### Auto-Scaling\n\nConfigure automatic scaling:\n\n```yaml\n# Auto-scaling configuration\nscaling:\n min_replicas: 1\n max_replicas: 10\n metrics:\n - type: \"cpu\"\n target: \"70%\" # Scale when CPU > 70%\n - type: \"memory\"\n target: \"80%\" # Scale when memory > 80%\n - type: \"requests_per_second\"\n target: 100 # Scale when RPS > 100\n policies:\n scale_up_cooldown: \"60s\" # Wait 60s between scale-ups\n scale_down_cooldown: \"300s\" # Wait 5m between scale-downs\n```\n\n### Scaling Strategies\n\nDifferent scaling strategies for different needs:\n\n#### CPU-Based Scaling\n```yaml\nscaling:\n metrics:\n - type: \"cpu\"\n target: \"70%\"\n```\n\n#### Memory-Based Scaling\n```yaml\nscaling:\n metrics:\n - type: \"memory\"\n target: \"80%\"\n```\n\n#### Request-Based Scaling\n```yaml\nscaling:\n metrics:\n - type: \"requests_per_second\"\n target: 100\n```\n\n#### Custom Metrics\n```yaml\nscaling:\n metrics:\n - type: \"custom\"\n name: \"queue_length\"\n target: 50\n```\n\n## Custom Domains and SSL\n\n### Domain Configuration\n\nSet up custom domains with advanced options:\n\n```yaml\n# Domain configuration\ndomains:\n - name: \"app.yourdomain.com\"\n type: \"primary\"\n ssl: true\n redirect_www: true\n - name: \"api.yourdomain.com\"\n type: \"api\"\n ssl: true\n - name: \"cdn.yourdomain.com\"\n type: \"cdn\"\n ssl: true\n cache_ttl: \"1h\"\n```\n\n### SSL Certificates\n\nSSL is automatically configured:\n\n1. **Automatic provisioning**: Let's Encrypt certificates\n2. **Auto-renewal**: Certificates renewed 30 days before expiry\n3. **Wildcard support**: For `*.yourdomain.com`\n4. **Custom certificates**: Upload your own certificates\n\n### CDN Integration\n\nConfigure CDN for static assets:\n\n```yaml\n# CDN configuration\ncdn:\n enabled: true\n provider: \"cloudflare\" # cloudflare, fastly, custom\n cache_ttl: \"1d\"\n compression: true\n minify: true\n```\n\n## Health Checks\n\n### HTTP Health Checks\n\nConfigure HTTP health checks:\n\n```yaml\n# HTTP health check\nhealth_check:\n type: \"http\"\n path: \"/health\"\n method: \"GET\"\n expected_status: 200\n headers:\n User-Agent: \"Containr-Health-Check\"\n timeout: \"10s\"\n interval: \"30s\"\n retries: 3\n start_period: \"60s\"\n```\n\n### TCP Health Checks\n\nFor services that don't have HTTP endpoints:\n\n```yaml\n# TCP health check\nhealth_check:\n type: \"tcp\"\n port: 8080\n timeout: \"5s\"\n interval: \"30s\"\n retries: 3\n```\n\n### Custom Health Checks\n\nImplement custom health check logic:\n\n```javascript\n// Express.js example\napp.get('/health', (req, res) => {\n const health = {\n status: 'ok',\n timestamp: new Date().toISOString(),\n checks: {\n database: checkDatabase(),\n redis: checkRedis(),\n memory: checkMemory()\n }\n };\n \n const isHealthy = Object.values(health.checks).every(check => check.status === 'ok');\n res.status(isHealthy ? 200 : 503).json(health);\n});\n\nfunction checkDatabase() {\n // Check database connection\n return { status: 'ok', latency: '5ms' };\n}\n\nfunction checkRedis() {\n // Check Redis connection\n return { status: 'ok', latency: '2ms' };\n}\n\nfunction checkMemory() {\n const usage = process.memoryUsage();\n const isHealthy = usage.heapUsed < 512 * 1024 * 1024; // 512MB\n return { \n status: isHealthy ? 'ok' : 'error',\n usage: `${Math.round(usage.heapUsed / 1024 / 1024)}MB`\n };\n}\n```\n\n## Advanced Examples\n\n### Microservices Architecture\n\nExample of a microservices setup:\n\n```yaml\n# API Gateway\nservices:\n - name: \"api-gateway\"\n type: \"web\"\n resources:\n cpu: \"500m\"\n memory: \"256Mi\"\n scaling:\n min_replicas: 2\n max_replicas: 5\n domains:\n - name: \"api.yourdomain.com\"\n\n# User Service\n - name: \"user-service\"\n type: \"web\"\n resources:\n cpu: \"200m\"\n memory: \"128Mi\"\n scaling:\n min_replicas: 1\n max_replicas: 3\n\n# Database\n - name: \"user-db\"\n type: \"database\"\n database_type: \"postgresql\"\n resources:\n storage: \"20Gi\"\n```\n\n### Full-Stack Application\n\nExample with frontend, backend, and database:\n\n```yaml\n# Frontend (React/Vue)\nservices:\n - name: \"frontend\"\n type: \"web\"\n build:\n builder: \"nixpacks\"\n build_command: \"npm run build\"\n start_command: \"npm run start\"\n domains:\n - name: \"app.yourdomain.com\"\n\n# Backend (Node.js)\n - name: \"backend\"\n type: \"web\"\n build:\n builder: \"nixpacks\"\n start_command: \"npm start\"\n environment:\n DATABASE_URL: \"postgresql://user-db:5432/myapp\"\n REDIS_URL: \"redis://redis:6379\"\n scaling:\n min_replicas: 1\n max_replicas: 5\n\n# Database\n - name: \"user-db\"\n type: \"database\"\n database_type: \"postgresql\"\n resources:\n storage: \"10Gi\"\n\n# Cache\n - name: \"redis\"\n type: \"database\"\n database_type: \"redis\"\n resources:\n memory: \"256Mi\"\n```\n\n## Troubleshooting\n\n### Common Issues\n\n#### Build Failures\n- Check build logs for specific errors\n- Verify `nixpacks.toml` or `Dockerfile` syntax\n- Ensure all dependencies are declared\n\n#### Runtime Errors\n- Check environment variables\n- Verify health check endpoints\n- Review resource limits\n\n#### Scaling Issues\n- Monitor metrics during scaling events\n- Check scaling policies and thresholds\n- Review resource allocation\n\n### Debug Mode\n\nEnable debug mode for troubleshooting:\n\n```yaml\n# Debug configuration\ndebug:\n enabled: true\n log_level: \"debug\"\n verbose_logs: true\n profile_requests: true\n```\n\n## Best Practices\n\n1. **Start small** and scale based on metrics\n2. **Monitor resource usage** regularly\n3. **Use health checks** for all services\n4. **Implement proper logging** and monitoring\n5. **Secure your applications** with proper secrets management\n6. **Test scaling policies** in staging environment\n7. **Regular security scans** and updates\n\n## Next Steps\n\n- Learn about [Monitoring and Alerts](./monitoring.md)\n- Explore [CI/CD Integration](./cicd.md)\n- Understand [Backup and Recovery](./backup.md)\n- Review [Performance Optimization](./performance.md)\n" }, { "path": "guides/getting-started.md", "section": "guides", "title": "Getting Started with Containr", "markdown": "# Getting Started with Containr\n\nWelcome to Containr! This guide will walk you through setting up your first project and deploying your first application.\n\n## Prerequisites\n\nBefore you begin, make sure you have:\n\n- A Containr instance running (either self-hosted or using our hosted version)\n- A Git repository with your application code\n- Basic knowledge of Docker and containerization concepts\n\n## Step 1: Create Your Account\n\n1. Navigate to your Containr instance URL\n2. Click \"Sign Up\" in the top-right corner\n3. Fill in your email, name, and password\n4. Verify your email address (if required)\n5. Log in to your new account\n\n## Step 2: Create Your First Project\n\n1. From the dashboard, click \"New Project\"\n2. Enter a project name (e.g., \"my-awesome-app\")\n3. Add an optional description\n4. Click \"Create Project\"\n\nYou'll be taken to your project's main canvas view.\n\n## Step 3: Connect Your Git Repository\n\n### Option A: Using GitHub (Recommended)\n\n1. Click \"Add Service\" → \"Connect Git Repository\"\n2. Select \"GitHub\" as the provider\n3. Click \"Connect to GitHub\" and authorize Containr\n4. Browse your repositories and select the one you want to deploy\n5. Choose the branch (usually `main` or `master`)\n6. Select the root directory if your app isn't in the root\n7. Click \"Connect Repository\"\n\n### Option B: Using Other Git Providers\n\nContainr also supports GitLab and Bitbucket:\n\n1. Click \"Add Service\" → \"Connect Git Repository\"\n2. Select your preferred provider\n3. Follow the authorization flow\n4. Select your repository and branch\n\n## Step 4: Configure Your Service\n\nAfter connecting your repository, Containr will:\n\n1. **Auto-detect your stack** (Node.js, Python, Go, etc.)\n2. **Generate a build plan** using Nixpacks\n3. **Show you the configuration**\n\n### Basic Configuration\n\n- **Service Name**: Give your service a descriptive name\n- **Build Command**: Auto-detected, but you can customize\n- **Start Command**: Auto-detected, but you can customize\n- **Environment Variables**: Add any needed variables\n\n### Example: Node.js Application\n\nFor a typical Node.js app:\n\n```bash\n# Build Command (auto-detected)\nnpm install && npm run build\n\n# Start Command (auto-detected)\nnpm start\n```\n\n### Example: Go Application\n\nFor a Go application:\n\n```bash\n# Build Command (auto-detected)\ngo build -o app .\n\n# Start Command (auto-detected)\n./app\n```\n\n## Step 5: Add Environment Variables\n\nMost applications need environment variables:\n\n1. Go to the \"Variables\" tab in your service\n2. Add your variables as key-value pairs:\n - `NODE_ENV=production`\n - `DATABASE_URL=postgresql://...`\n - `API_KEY=your-secret-key`\n3. Variables are automatically encrypted and injected at runtime\n\n## Step 6: Deploy Your Application\n\n1. Click \"Deploy\" in the top-right corner\n2. Choose your deployment method:\n - **Deploy Latest Commit**: Deploy the latest commit from your branch\n - **Manual Deploy**: Specify a commit SHA\n3. Click \"Start Deployment\"\n\nContainr will:\n1. Pull your code from Git\n2. Build a Docker image using Nixpacks\n3. Start the container\n4. Assign a public URL\n\n## Step 7: Monitor Your Deployment\n\nWhile deploying, you can:\n\n- **View Build Logs**: See the build process in real-time\n- **Check Status**: Monitor deployment progress\n- **Get Notifications**: Receive alerts on success or failure\n\nOnce deployed, you'll see:\n\n- **Public URL**: Your application is live at `https://your-service-name.containr.app`\n- **Status**: Green checkmark if running successfully\n- **Metrics**: CPU, memory, and network usage\n\n## Step 8: Add a Database (Optional)\n\nMost applications need a database:\n\n1. Click \"Add Service\" → \"Add Database\"\n2. Choose your database type:\n - **PostgreSQL**: For relational data\n - **Redis**: For caching and sessions\n - **MySQL**: For MySQL compatibility\n3. Configure:\n - Database name\n - Version\n - Size allocation\n4. Click \"Create Database\"\n\n### Connect Your Application\n\nOnce the database is created:\n\n1. Go to your service's \"Variables\" tab\n2. Add the database connection URL:\n ```\n DATABASE_URL=postgresql://username:password@hostname:port/database_name\n ```\n3. Redeploy your application\n\n## Step 9: Set Up Preview Environments\n\nEnable automatic preview environments for pull requests:\n\n1. Go to project settings\n2. Enable \"Preview Environments\"\n3. Configure:\n - Automatic cleanup (e.g., 7 days)\n - Branch patterns (e.g., `feature/*`, `fix/*`)\n4. Save settings\n\nNow when you create a pull request:\n- A preview environment is automatically created\n- You get a unique URL for testing\n- Environment is cleaned up after merging\n\n## Step 10: Configure Custom Domain (Optional)\n\nTo use your own domain:\n\n1. Go to your service's \"Settings\" tab\n2. Click \"Add Custom Domain\"\n3. Enter your domain (e.g., `app.yourdomain.com`)\n4. Configure DNS:\n ```\n CNAME app.yourdomain.com -> your-service-name.containr.app\n ```\n5. Wait for SSL certificate provisioning\n\n## Troubleshooting Common Issues\n\n### Build Failures\n\n**Problem**: Build fails during deployment\n\n**Solutions**:\n1. Check build logs for specific error messages\n2. Verify your `package.json`, `go.mod`, or `requirements.txt` is valid\n3. Ensure all dependencies are properly declared\n4. Check for syntax errors in your code\n\n### Runtime Errors\n\n**Problem**: Application starts but crashes\n\n**Solutions**:\n1. Check runtime logs in the \"Logs\" tab\n2. Verify environment variables are correctly set\n3. Ensure your application listens on the correct port (default: `$PORT`)\n4. Check database connection strings\n\n### Port Issues\n\n**Problem**: Application can't be accessed\n\n**Solutions**:\n1. Ensure your application listens on the `$PORT` environment variable\n2. Don't hardcode ports in your application\n3. Example for Node.js:\n ```javascript\n const port = process.env.PORT || 3000;\n app.listen(port, () => {\n console.log(`Server running on port ${port}`);\n });\n ```\n\n## Best Practices\n\n### Security\n\n1. **Never commit secrets** to your repository\n2. **Use environment variables** for all sensitive data\n3. **Enable HTTPS** (automatic on Containr)\n4. **Keep dependencies updated**\n\n### Performance\n\n1. **Optimize Docker images** by using `.dockerignore`\n2. **Enable caching** for faster builds\n3. **Monitor resource usage** and scale as needed\n4. **Use CDN** for static assets\n\n### Development Workflow\n\n1. **Use feature branches** for new features\n2. **Enable preview environments** for testing\n3. **Write tests** and run them in CI/CD\n4. **Monitor deployments** and set up alerts\n\n## Next Steps\n\nNow that you have your first application deployed:\n\n- Explore the [Advanced Configuration](./advanced-configuration.md) guide\n- Learn about [Scaling and Load Balancing](./scaling.md)\n- Set up [Monitoring and Alerts](./monitoring.md)\n- Join our [Community](https://github.com/your-org/containr/discussions)\n\n## Need Help?\n\n- **Documentation**: [containr.dev/docs](https://containr.dev/docs)\n- **Community**: [GitHub Discussions](https://github.com/your-org/containr/discussions)\n- **Support**: support@containr.dev\n- **Status**: [status.containr.dev](https://status.containr.dev)\n\nHappy deploying! 🚀\n" } ];