DevOps & Infrastructure

Self-Hosting a Production Website on a Home Server: A Real Case Study

By Ginbok4 min read

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:

This led to a self-hosted architecture with a proper deployment pipeline.


Overall Architecture

The system looks like this:


Hosting the Website on IIS

The website is hosted under IIS with a dedicated application pool.

Example setup:

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:

  1. Home router updates IP to No-IP

  2. No-IP hostname always points to the latest IP

  3. Domain CNAME points to No-IP hostname

Example DNS setup:

example.com CNAME myhomeserver.ddns.net www.example.com CNAME myhomeserver.ddns.net
 

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:

- task: DotNetCoreCLI@2 displayName: 'Publish website' inputs: command: 'publish' projects: '**/CmsSite.csproj' arguments: '--configuration Release --output $(Build.ArtifactStagingDirectory)' zipAfterPublish: true
 

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:

  1. Stop IIS site and app pool

  2. Backup the current site

  3. Clean old files

  4. Extract the ZIP package

  5. Restore required config files

  6. Restart IIS

Example PowerShell snippet:

Stop-Website -Name "CmsSite" Stop-WebAppPool -Name "CmsSite" Expand-Archive ` -Path "C:\agent\_work\drop\site.zip" ` -DestinationPath "C:\inetpub\wwwroot\CmsSite" ` -Force Start-WebAppPool -Name "CmsSite" Start-Website -Name "CmsSite"
 

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:

 
"ApplicationInsights": { "ConnectionString": "InstrumentationKey=EXAMPLE-KEY" }

I also filtered out CMS-related requests such as:

 
/episerver/cms /episerver/shell

This keeps metrics clean and focused on real user traffic.


Keeping the Site Running 24/7

Several IIS settings are important for stability:

With this setup, the site stays responsive even after long periods of inactivity.


Security Considerations

Even on a home server, security matters:

This is not enterprise-grade security, but it is sufficient for small to medium projects.


What Worked Well


Limitations


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.

#azure-devops#ci-cd
← Back to Articles