[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"technology-en-caddy":3,"technology-projects-en-caddy":30,"mdc--7b8d6d-key":146},{"id":4,"title":5,"category":6,"content":7,"description":8,"extension":9,"faq":10,"icon":11,"links":12,"meta":21,"projects":22,"since":26,"stem":27,"updated":28,"__hash__":29},"technologies_en\u002Fen\u002Ftechnologies\u002Fcaddy.yml","Caddy","infrastructure","Caddy is a web server and reverse proxy that I use to route requests to my SaaS applications. It sits in front of services such as VetSpace and DigiPulse, connecting public domains to applications running in Docker.\n\n## How I use Caddy\n\n- **Request routing** — forward traffic to the application or container responsible for a domain.\n- **HTTPS** — automate certificate issuance and renewal for configured domains.\n- **Readable configuration** — keep proxy rules in a Caddyfile so I can review changes alongside application deployments.\n\n## HTTPS and tenant routing\n\nAutomatic HTTPS depends on correct DNS, certificate validation and persistent certificate storage. Certificate failures still need monitoring. The application must also identify the clinic and enforce access permissions; a reverse proxy does not provide tenant isolation on its own.\n\n## Where Caddy fits\n\nFor my Docker deployments, Caddy provides a manageable entry point without a large proxy configuration. I still plan timeouts, forwarded headers and access logging around the needs of each service. Those details matter when tracing a failed booking request across the proxy and Laravel API.\n","Caddy reverse proxy for SaaS applications: automatic HTTPS, domain routing and container access in my self-managed infrastructure.","yml",null,"i-simple-icons-caddy",[13,18],{"label":14,"to":15,"color":16,"icon":17},"caddyserver.com","https:\u002F\u002Fcaddyserver.com","neutral","i-heroicons-arrow-top-right-on-square",{"label":19,"to":20,"color":16,"icon":17},"Technical reference","https:\u002F\u002Fcaddyserver.com\u002Fdocs\u002Fautomatic-https",{},[23,24,25],"vetspace","digipulse","netpostpanel","2022","en\u002Ftechnologies\u002Fcaddy","2026-09-20","pUkuJTmyWQIPOUTTPXOGpDXt0QWkpbPBED9DI8SLlLo",[31,79,116],{"id":32,"title":33,"content":34,"date":35,"description":36,"extension":9,"featured":37,"image":38,"links":39,"meta":54,"stack":55,"stem":74,"tags":75,"url":42,"__hash__":78},"projects_en\u002Fen\u002Fprojects\u002Fvetspace.yml","VetSpace","A two-sided veterinary platform — an SEO clinic catalog and a subscription-based CRM with appointments and patient records. A public clinic catalog built for SEO-first customer acquisition, and a subscription-based CRM (appointments, visits, patient records) as separate Vue\u002FNuxt apps on top of a single Laravel API. Database-per-tenant architecture, Stripe subscriptions via Cashier, GraphQL + REST, and AI-assisted visit analysis through a dedicated Go microservice.\n\n## Key Features\n\n- **Two-sided funnel** - an SEO-first public catalog acquires clinics; the subscription CRM (appointments, patient records) retains them\n- **True tenant isolation** - database-per-tenant keeps every clinic's data separate and makes GDPR export\u002Fdelete a per-database operation\n- **Dual API surface** - GraphQL for complex catalog queries, REST for the CRM — one Laravel codebase\n- **Billing built-in** - Stripe subscriptions via Cashier: trials, plan changes, dunning\n- **AI where it helps** - visit analysis runs in a dedicated Go microservice, keeping the main API unburdened\n\n## Tech Stack\n\n- **Backend**: Laravel (API)\n- **Frontend**: Vue\u002FNuxt (separate apps)\n- **Architecture**: Database-per-tenant multi-tenancy\n- **Payments**: Stripe via Cashier\n- **API**: GraphQL + REST\n- **AI**: Go microservice for visit analysis\n","2026-09-19","A two-sided veterinary platform — an SEO clinic catalog and a subscription-based CRM with appointments and patient records",true,"\u002Fhero\u002Fvetspace.avif",[40,44,48,51],{"label":41,"to":42,"color":43,"icon":17},"Live Demo","https:\u002F\u002Fvetspace.pro","primary",{"label":45,"to":46,"color":16,"icon":47},"API Overview","https:\u002F\u002Fgithub.com\u002FYurij2015\u002Fvetspace-api","i-simple-icons-github",{"label":49,"to":50,"color":16,"icon":47},"Frontend Overview","https:\u002F\u002Fgithub.com\u002FYurij2015\u002Fvetspace-frontend",{"label":52,"to":53,"color":16,"icon":47},"VetCard Overview","https:\u002F\u002Fgithub.com\u002FYurij2015\u002Fvetspace-vetcard",{},[56,59,62,65,68,71],{"name":57,"icon":58},"Laravel","i-simple-icons-laravel",{"name":60,"icon":61},"Vue","i-simple-icons-vuedotjs",{"name":63,"icon":64},"Nuxt","i-simple-icons-nuxtdotjs",{"name":66,"icon":67},"Stripe","i-simple-icons-stripe",{"name":69,"icon":70},"GraphQL","i-simple-icons-graphql",{"name":72,"icon":73},"AI","i-heroicons-sparkles","en\u002Fprojects\u002Fvetspace",[76,57,60,77,66,72],"SaaS","Multi-tenant","NDJ-cDU24m4uCf7HzSeTbCgbh0MGVh5P5HASDymy0wA",{"id":80,"title":81,"content":82,"date":83,"description":84,"extension":9,"featured":37,"image":85,"links":86,"meta":92,"stack":93,"stem":111,"tags":112,"url":88,"__hash__":115},"projects_en\u002Fen\u002Fprojects\u002Fdigipulse.yml","DigiPulse","Uptime monitoring SaaS — 60-second checks, SSL expiry tracking, Telegram and email notifications. The admin panel and core backend are built with Laravel (Octane, Reverb websockets) and Filament, while the monitoring engine is a separate Go service. Includes Google OAuth sign-in and Cloudflare Turnstile integration, plus an MCP server that exposes monitoring data directly to AI assistants. Self-hosted on Proxmox.\n\n## Key Features\n\n- **Dedicated Go engine** - availability checks run in a separate Go service, so constant 60-second polling never slows down the Laravel app\n- **Real-time dashboard** - Reverb websockets push status changes to the UI live, no manual refresh\n- **Octane + Filament** - resident-memory Laravel with a full admin panel for monitors, contacts and alert rules\n- **MCP server** - monitors and incidents are queryable from AI assistants (Claude, Cursor) via the Model Context Protocol\n- **Google OAuth + Turnstile** - passwordless sign-in and bot protection on public forms\n- **Self-hosted** - deployed on a Proxmox homelab I manage end-to-end\n\n## Tech Stack\n\n- **Backend**: Laravel (Octane, Reverb websockets)\n- **Admin Panel**: Filament\n- **Monitoring Engine**: Go (separate service)\n- **Database**: PostgreSQL\n- **AI Integration**: MCP server\n- **Infrastructure**: Self-hosted on Proxmox\n","2026-04-17","Uptime monitoring SaaS: event-driven architecture — Laravel (Octane, Reverb) + Filament dispatch checks through Redis to a lightweight Go worker; an MCP server exposes monitoring data to AI assistants; Telegram\u002Femail alerts","\u002Fhero\u002Fdigipulse.avif",[87,89],{"label":41,"to":88,"color":43,"icon":17},"https:\u002F\u002Fdigipulse.cloud",{"label":90,"to":91,"color":16,"icon":47},"GitHub","https:\u002F\u002Fgithub.com\u002FYurij2015\u002Fdigipulse-backend",{},[94,95,98,101,104,107,108],{"name":57,"icon":58},{"name":96,"icon":97},"Filament","i-simple-icons-filament",{"name":99,"icon":100},"Go","i-simple-icons-go",{"name":102,"icon":103},"PostgreSQL","i-simple-icons-postgresql",{"name":105,"icon":106},"Redis","i-simple-icons-redis",{"name":60,"icon":61},{"name":109,"icon":110},"MCP","i-heroicons-cpu-chip","en\u002Fprojects\u002Fdigipulse",[76,57,99,113,109,105,114],"Monitoring","Event-driven","b7hu-_otqukg-JY_hPBvmlUYk5jVOx42XpCotH6Cvqo",{"id":117,"title":118,"content":119,"date":120,"description":121,"extension":9,"featured":37,"image":122,"links":123,"meta":127,"stack":128,"stem":140,"tags":141,"url":144,"__hash__":145},"projects_en\u002Fen\u002Fprojects\u002Fnetpostpanel.yml","NetPostPanel","An internal AI content-operations platform that turns topic research into publishable content: a full RAG pipeline (Google Custom Search + RSS → scraping → multi-provider generation → vectorization), plus a versioned external API that powers content workflows in other projects, including the DigiSpace blog pipeline.\n\n## Key Features\n\n- **External API** - a versioned `POST \u002Fapi\u002Fv1\u002Fgenerate` + `\u002Ftranslate` API with per-client keys and rate limits exposes the whole pipeline to other apps, sync or async with callbacks\n- **Auto Pilot** - scheduled daily runs generate content from new inspiration items or custom topics, fully unattended\n- **Provider-agnostic AI** - Gemini and OpenAI sit behind a driver abstraction, so swapping models is config, not refactoring\n- **Semantic pipeline** - Qdrant vector search deduplicates and clusters incoming stories before they reach generation\n- **Autonomous aggregation** - RSS auto-discovery and Google Custom Search plus scraping turn a bare topic into a self-feeding content source\n- **Observable LLM calls** - every generation is traced in Langfuse: tokens, latency, cost\n- **Role-based access** - admin\u002Fcontent manager\u002Feditor roles, with every query scoped to its owner unless admin\n\n## Tech Stack\n\n- **Backend**: Laravel, `laravel\u002Fai` agents\n- **Frontend**: Inertia.js + Vue 3 (Search & Creation SPA, TipTap editor)\n- **AI**: Multi-provider (Gemini\u002FOpenAI) behind a driver abstraction\n- **Research**: Google Custom Search + RSS aggregation, page scraping\n- **Vector DB**: Qdrant for semantic search\n- **Observability**: Langfuse for LLM tracing\n- **Queue**: Laravel Horizon\n- **Tests**: PHPUnit\u002FPest + Cypress E2E\n","2024-11-10","AI content-operations platform — a RAG pipeline (research → scrape → generate → vectorize), an external API other apps call, and Auto Pilot for unattended scheduled generation","\u002Fhero\u002Fnetpostpanel.avif",[124],{"label":125,"to":126,"color":16,"icon":47},"Overview","https:\u002F\u002Fgithub.com\u002FYurij2015\u002Fnet-post-panel-overview",{},[129,130,131,134,137],{"name":57,"icon":58},{"name":72,"icon":73},{"name":132,"icon":133},"Qdrant","i-simple-icons-qdrant",{"name":135,"icon":136},"Langfuse","i-heroicons-chart-bar",{"name":138,"icon":139},"Horizon","i-simple-icons-laravelhorizon","en\u002Fprojects\u002Fnetpostpanel",[72,57,142,143,132,138],"RAG","External API","https:\u002F\u002Fnet-post-panel.digispace.pro","9F27sKWiICL9ugPIbYmr3dQH8lYynDHYMUcKPSIVVGQ",{"data":147,"body":148},{},{"type":149,"children":150},"root",[151,159,166,202,208,213,219],{"type":152,"tag":153,"props":154,"children":155},"element","p",{},[156],{"type":157,"value":158},"text","Caddy is a web server and reverse proxy that I use to route requests to my SaaS applications. It sits in front of services such as VetSpace and DigiPulse, connecting public domains to applications running in Docker.",{"type":152,"tag":160,"props":161,"children":163},"h2",{"id":162},"how-i-use-caddy",[164],{"type":157,"value":165},"How I use Caddy",{"type":152,"tag":167,"props":168,"children":169},"ul",{},[170,182,192],{"type":152,"tag":171,"props":172,"children":173},"li",{},[174,180],{"type":152,"tag":175,"props":176,"children":177},"strong",{},[178],{"type":157,"value":179},"Request routing",{"type":157,"value":181}," — forward traffic to the application or container responsible for a domain.",{"type":152,"tag":171,"props":183,"children":184},{},[185,190],{"type":152,"tag":175,"props":186,"children":187},{},[188],{"type":157,"value":189},"HTTPS",{"type":157,"value":191}," — automate certificate issuance and renewal for configured domains.",{"type":152,"tag":171,"props":193,"children":194},{},[195,200],{"type":152,"tag":175,"props":196,"children":197},{},[198],{"type":157,"value":199},"Readable configuration",{"type":157,"value":201}," — keep proxy rules in a Caddyfile so I can review changes alongside application deployments.",{"type":152,"tag":160,"props":203,"children":205},{"id":204},"https-and-tenant-routing",[206],{"type":157,"value":207},"HTTPS and tenant routing",{"type":152,"tag":153,"props":209,"children":210},{},[211],{"type":157,"value":212},"Automatic HTTPS depends on correct DNS, certificate validation and persistent certificate storage. Certificate failures still need monitoring. The application must also identify the clinic and enforce access permissions; a reverse proxy does not provide tenant isolation on its own.",{"type":152,"tag":160,"props":214,"children":216},{"id":215},"where-caddy-fits",[217],{"type":157,"value":218},"Where Caddy fits",{"type":152,"tag":153,"props":220,"children":221},{},[222],{"type":157,"value":223},"For my Docker deployments, Caddy provides a manageable entry point without a large proxy configuration. I still plan timeouts, forwarded headers and access logging around the needs of each service. Those details matter when tracing a failed booking request across the proxy and Laravel API."]