📄 A First Post!

Published on 2025-07-01

Building a Hybrid Web Architecture: Static AWS + Dynamic Home Lab

So I wanted to build myself a personal website, but I also wanted to mess around with different tech without breaking the bank. What I ended up with is kind of a weird hybrid setup that splits things between AWS (for the boring static stuff) and my home server (for the fun experimental bits).

The Architecture Overview

The Two-Domain Strategy

The architecture centers around two distinct domains, each serving a different purpose:

1. chrisziemba.dev - The Static Site (AWS)

This is my main professional presence - a static site hosted entirely on AWS infrastructure. It's fast, reliable, and costs very little to operate. The content is served through CloudFront's global CDN network, ensuring quick load times.

2. bits.chrisziemba.dev - The Dynamic Lab (Home Network)

This subdomain points to my server IP address and hosts my experimental applications. It's where I can deploy Next.js applications, test out tech, and run interactive demos without worrying about AWS costs or limitations.

AWS Infrastructure: How the Static Stuff Works

Route 53 DNS Management

I chose Route 53 for DNS because it integrates seamlessly with other AWS services and provides reliable global DNS resolution. The DNS configuration is straightforward:

  • chrisziemba.dev points to a CloudFront distribution
  • bits.chrisziemba.dev points to my home IP address

CloudFront + S3: A Classic Combo

For the static site, I'm using the tried-and-true combination of CloudFront as the CDN and S3 as the origin. This setup provides:

  • Global edge caching for fast content delivery
  • HTTPS termination with AWS Certificate Manager
  • URL rewriting to handle routing (e.g., /web/* gets rewritten to /*)
  • Cost efficiency - S3 storage is cheap, and CloudFront's free tier is generous

The S3 bucket serves as a simple file store for the static HTML, CSS, and JavaScript files. CloudFront handles all the heavy lifting of global distribution and caching.

Home Lab: The Home-Server Powerhouse

Why Host at Home?

Running dynamic applications on AWS can get expensive quickly, especially for experimental projects. By hosting on a home-server, I get:

  • Zero hosting costs (beyond electricity)
  • Full control over the environment
  • Easy SSH access for debugging and deployment
  • No limits or usage restrictions

The Network Stack

Router/Firewall Configuration

Traffic hits my router first, where I've configured:

  • Port forwarding for HTTPS (443) traffic to the home-server
  • Dynamic DNS to handle IP address changes from my ISP
  • Basic firewall rules to allow only necessary traffic

NGINX as Reverse Proxy

NGINX runs on the home-server and serves as both a web server and reverse proxy. It handles:

  • SSL termination using Let's Encrypt certificates
  • Virtual host routing based on the Host header
  • Load balancing (for when I run multiple application instances)
  • Security headers and basic DDoS protection

The NGINX configuration checks the incoming Host header and routes bits.chrisziemba.dev requests to the Next.js application running on localhost:3001.

Next.js Application

The heart of the dynamic site is a Next.js application that showcases various experiments and projects. It's built with:

  • React 19 for the frontend
  • TypeScript for type safety
  • Tailwind CSS for styling
  • MDX for content management
  • WebAssembly modules for performance-critical features

Process Management with PM2

To keep the Next.js application running reliably, I use PM2 as a process manager:

module.exports = {
  apps: [{
    name: "my-web-ui",
    script: "node_modules/next/dist/bin/next",
    args: "start -p 3001",
    env: {
      NODE_ENV: "production"
    },
    max_restarts: 10
  }]
}

PM2 handles:

  • Automatic restarts if the application crashes
  • Log management for debugging
  • Process monitoring and health checks
  • Zero-downtime deployments during updates

Key Architectural Decisions

1. Separation of Concerns

By splitting static and dynamic content, I can optimize each for its specific use case. Static content benefits from AWS's global infrastructure, while dynamic content gets the flexibility of a home lab environment.

2. Cost Optimization

The AWS side costs less than $5/month thanks to the free tiers and efficient resource usage. The home lab has zero ongoing costs beyond electricity.

3. Security Through Obscurity (Partially)

While not a security strategy by itself, running dynamic applications on a non-standard port behind NGINX provides some protection against automated attacks targeting common application ports.

4. Scalability Considerations

The static site scales automatically through CloudFront. The dynamic site is limited by my home internet connection and Pi resources, but that's perfectly adequate for experimental and demo purposes.

5. Development Workflow

This setup allows me to:

  • Deploy static content via AWS CDK or simple S3 uploads
  • Push dynamic applications directly to the home-server via SSH
  • Test changes locally before deploying to production
  • Run resource-intensive experiments without cloud costs

Lessons Learned so far...

What Works Well

  • Hybrid approach provides the best of both worlds
  • Low operational costs make experimentation affordable
  • Full control over the dynamic environment enables creative projects
  • Reliable infrastructure keeps the static site always available

What Could Be Improved

  • Single point of failure - the home-server going down takes the dynamic site offline. I will probably move long-lived, dynamic pages to a cloud host at some point.
  • Limited bandwidth for the home connection; not an issue (yet)
  • Limited performance for the dynamic applications. Mitigated by limiting the number of pages using server-side rendering.
  • Manual SSL certificate management I predict the home cert will lapse at some point because I forgot to update it...

Conclusion

So far, this setup has been working great. I get the best of both worlds; AWS handles the boring static stuff reliably and cheaply, while my home-server lets me mess around with whatever I want without worrying about costs or restrictions.

If you're thinking about something similar, the main thing is to not overthink it. Static stuff goes where it's cheap and fast (AWS), dynamic stuff goes where you have control (home lab). Simple as that.

I'm sure I'll keep tweaking this as I break things and learn new stuff. That's half the fun of running your own infrastructure; you can experiment locally and learn from your mistakes!