Files
Containr/app/frontend/src/generated/docs-snapshot.ts
T
Tomas Dvorak f499678964 feat: outbound webhooks — signed event delivery + delivery log
Every audited action now emits a "resource.action" event (bare actions
get resource-qualified; already-qualified actions like service.clone
pass through). Webhooks subscribe per-user with exact names, resource.*
wildcards, or *.

- schema: outbound_webhooks + webhook_deliveries (sqlc + goose)
- dispatcher: 4 workers, 512-queue, 3 attempts with backoff, 10s timeout;
  deliveries record status/http-code/body(4KiB)/duration
- signing: X-Containr-Signature sha256=<hmac> over raw body;
  X-Containr-Event + X-Containr-Delivery headers; custom headers per hook
- api: CRUD + /deliveries + /test (ping) under authed group
- fix: SetAuditDB never called — LogAudit was a silent no-op at every
  call site; now wired at boot
- coverage: service create/delete audited (previously uninstrumented)
- cli: containr webhooks list|create|update|delete|deliveries|test
- mcp: 6 tools, delete requires confirm
- frontend: /settings/webhooks page — list/create/expand-deliveries/
  test/disable/delete, secret-shown-once banner; nav + account menu
- openapi + regenerated types; CLI.md + docs snapshot; roadmap ticks
2026-10-09 09:44:08 +02:00

88 lines
84 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 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\":\"[email protected]\",\"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<User | null>(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 <div>Loading...</div>;\n if (!user) return <div>User not found</div>;\n\n return (\n <div>\n <h1>{user.name}</h1>\n <p>{user.email}</p>\n <Button onClick={() => console.log('Edit user')}>\n Edit Profile\n </Button>\n </div>\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**: [email protected]\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 <div className=\"min-h-screen bg-gray-50\">\n <DockerTemplateManager />\n </div>\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 <service-id> trigger a deployment (--no-cache, --commit-hash, --branch)\ndeployments list|get|logs|rollback|cancel\nlogs <service-id> [--follow] runtime logs (SSE follow)\nexec <service-id> -- <cmd> 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 <id> <file.tar.gz|-> 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 <id> --public/--public=false toggles it (container recreates, data persists)\ndatabases register <name> 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 <db-id> --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 <compose.yml|-> converts a compose file into\n a v2 graph config; deploy-graph <project-id> <config.json|->\n deploys an ad-hoc service graph\nimport compose <project-id> <compose.yml|->\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 <name> <url>\n --event 'service.*' (repeatable, '*' = all);\n deliveries are HMAC-signed (X-Containr-Signature)\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 <id>\ncontainr up --project <id> --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.<name>.project_id`).\n\n## Service volumes\n\n`services update` manages mounts; flags replace the whole mount list:\n\n```bash\ncontainr services update <id> --volume data:/data --bind /srv/cfg:/etc/app:ro\ncontainr services update <id> --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 <id>` to apply immediately.\n\n`volumes list` shows the node's docker volume inventory with in-use\nflags; `volumes delete <name>` 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 <id> app.example.com --default\ncontainr services domains check <id> # DNS preflight per domain\ncontainr services domains remove <id> <domain-id>\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 <id> --maintenance on\ncontainr services update <id> --basic-auth admin:secret --basic-auth ops:pw2\n```\n\nMaintenance mode redirects all traffic to `<BASE_URL>/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 <id> --builder railpack # auto|railpack|nixpacks|dockerfile|static\ncontainr services update <id> --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 <id> --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 <id> --sleep --sleep-idle 15 # enable, 15 min idle timeout\ncontainr services update <id> --sleep=false # disable\ncontainr services sleep <id> # sleep now\ncontainr services wake <id> # resume now\ncontainr services env-check <id> # 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 <id> --name staging-api --project <other-project-id> --environment preview\ncontainr services move <id> <project-id> # 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 <user> --password <pat>\ncontainr registries add hub docker.io --username <user> --password <pw> # Docker Hub\ncontainr registries update <id> --username <new-user> # empty --password keeps stored\ncontainr registries remove <id>\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 <id>` 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 <tunnel-id>\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 [email protected]\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 <your-repo>\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 - `[email protected]` - 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 <command>`) 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 <your-jwt-token>\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\": \"[email protected]\",\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\": \"[email protected]\",\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 <token>\" \\\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**: [email protected]\n- **Status**: [status.containr.dev](https://status.containr.dev)\n\nHappy deploying! 🚀\n"
}
];