Project Background
Running a website does not always require expensive cloud services. In this post, I want to share a real case study of how I built, deployed, and hosted a production website using my own home server, Azure DevOps CI/CD, IIS, and Dynamic DNS.
The only recurring cost in this setup is the domain name.
This is not a theoretical guide. Everything described here has been implemented and is currently running.
Background and Motivation
I was working on a website built with Optimizely CMS 12 and Commerce 14, running on .NET and hosted on IIS.
Instead of deploying to Azure App Service or Kubernetes from the beginning, I wanted to:
-
Fully control the infrastructure
-
Learn CI/CD deeply
-
Reduce hosting cost to nearly zero
-
Understand how far a home server setup can go
This led to a self-hosted architecture with a proper deployment pipeline.
Overall Architecture
The system looks like this:
-
Home server (Windows)
-
IIS hosting the website
-
Azure DevOps for CI/CD
-
Self-hosted Azure DevOps agent
-
Dynamic DNS (No-IP)
-
Domain pointing to Dynamic DNS
-
Optional Cloudflare for DNS and protection
Hosting the Website on IIS
The website is hosted under IIS with a dedicated application pool.
Example setup:
-
Website name:
CmsSite -
Physical path:
-
Application Pool:
-
.NET CLR: No Managed Code
-
Pipeline mode: Integrated
-
Start Mode: AlwaysRunning
-
Idle Time-out: Disabled
-
This configuration ensures the site does not fall into an idle state.
Making the Website Public with Dynamic DNS
Because the home network does not have a static IP, I used Dynamic DNS.
The flow is simple:
-
Home router updates IP to No-IP
-
No-IP hostname always points to the latest IP
-
Domain CNAME points to No-IP hostname
Example DNS setup:
From the outside, the site behaves like any normal public website.
CI/CD with Azure DevOps
Build Pipeline (Cloud Agent)
The build pipeline restores packages, builds the solution, runs tests, and publishes the site as a ZIP artifact.
Example publish step:
This produces a deployable ZIP file.
Deploy Pipeline (Self-Hosted Agent)
The deploy stage runs on a self-hosted agent installed directly on the home server.
Key responsibilities of the deploy script:
-
Stop IIS site and app pool
-
Backup the current site
-
Clean old files
-
Extract the ZIP package
-
Restore required config files
-
Restart IIS
Example PowerShell snippet:
This makes deployments repeatable and safe.
Application Insights and Monitoring
To monitor the application, I integrated Azure Application Insights.
Configuration is injected via environment variables during deployment:
I also filtered out CMS-related requests such as:
This keeps metrics clean and focused on real user traffic.
Keeping the Site Running 24/7
Several IIS settings are important for stability:
-
Application Pool:
-
AlwaysRunning
-
Idle timeout disabled
-
-
Website:
-
Preload Enabled
-
-
Windows:
-
Prevent sleep mode
-
Scheduled reboot avoided
-
With this setup, the site stays responsive even after long periods of inactivity.
Security Considerations
Even on a home server, security matters:
-
RDP is restricted by firewall rules
-
IIS runs with least privilege
-
HTTPS is enforced (via reverse proxy or SSL binding)
-
Cloudflare can be added for DDoS and WAF protection
This is not enterprise-grade security, but it is sufficient for small to medium projects.
What Worked Well
-
Full control over deployment and hosting
-
Extremely low cost
-
CI/CD experience identical to professional environments
-
Easy debugging because everything is accessible
Limitations
-
Hardware is a single point of failure
-
Internet stability matters
-
Scaling requires manual effort
-
Not suitable for high-traffic systems
Conclusion
This setup proves that hosting a real production website does not always require cloud infrastructure.
With the right CI/CD pipeline, IIS configuration, and monitoring, a home server can reliably host a modern .NET-based CMS website.
For learning, personal projects, and small businesses, this approach is surprisingly effective.