📄 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 distributionbits.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!