Portfolio Architecture

A deep dive into how this portfolio is built as a production-grade Rails application

System Overview

This portfolio is not a static site. It's a full-stack Ruby on Rails application with authentication, database persistence, analytics, admin dashboard, and automated deployment pipeline. Built to demonstrate production-ready development practices and cloud infrastructure skills.

Client Request
HTTPS • tannermyers.dev
CloudFlare CDN
SSL/TLS termination, DDoS protection, edge caching
AWS EC2 Application Server
Puma web server running Rails 7.1
Public Application
• Homepage, About, Projects
• Contact form with spam filtering
• Architecture documentation
• Responsive design with dark mode
Admin Dashboard
• Secure authentication (Devise + 2FA)
• Content management system
• Analytics dashboard (Chartkick)
• Spam review and management
PostgreSQL (AWS RDS)
Managed relational database: Users, Projects, Contacts, Analytics (Ahoy)
AWS S3 + CloudFront
Static assets, deployment artifacts
GitHub Actions CI/CD
Automated build, test, deploy pipeline (~2min)
~2min
Deploy
99.9%
Uptime
<200ms
Response
A+
SSL

Technology Stack

Backend

  • Ruby on Rails 7.1: MVC framework with Turbo for SPA-like experience
  • PostgreSQL: Relational database on AWS RDS
  • Devise: Authentication with custom 2FA implementation
  • Ahoy: Analytics tracking for visitor insights
  • ROTP: Time-based one-time passwords for 2FA

Frontend

  • Tailwind CSS 3: Utility-first CSS with class-based dark mode
  • Stimulus: JavaScript framework for sprinkles of interactivity
  • Turbo: Fast page loads without full refreshes
  • Chartkick: Beautiful charts for analytics dashboard
  • ImportMap: Modern JavaScript without bundlers

Infrastructure

  • AWS EC2: Application server with systemd service
  • AWS RDS: Managed PostgreSQL with automated backups
  • AWS S3: Deployment artifacts and static assets
  • CloudFlare: CDN, SSL/TLS, DDoS protection
  • GitHub Actions: CI/CD pipeline for automated deployments

DevOps

  • Systemd: Service management and auto-restart
  • Puma: Multi-threaded Ruby web server
  • Let's Encrypt: Free SSL certificates with auto-renewal
  • AWS SSM: Secure command execution for deployments
  • Git: Version control with GitHub

Production-Ready Features

Security

  • • Two-factor authentication (TOTP)
  • • Secure password hashing (bcrypt)
  • • CSRF protection on all forms
  • • SSL/TLS encryption via CloudFlare
  • • Admin access locked to single user
  • • No public registration endpoints
  • • Session timeout and security headers

Spam Detection

  • • Multi-layer filtering system
  • • Honeypot field for bot detection
  • • Keyword-based spam detection
  • • Domain blacklist checking
  • • Risk scoring algorithm
  • • Manual approval/rejection workflow
  • • Blocked contacts tracking for analysis

Analytics

  • • Privacy-focused tracking with Ahoy
  • • Visit and event tracking
  • • Referrer source analysis
  • • Page view metrics
  • • Geographic visitor data
  • • Device and browser stats
  • • Interactive charts with Chartkick

Admin Dashboard

  • • Content management for projects
  • • Skills and experience editing
  • • Contact form submissions
  • • Spam filter management
  • • Real-time analytics dashboard
  • • 2FA setup and backup codes
  • • Responsive design for mobile admin

CI/CD Pipeline

Automated deployment pipeline using GitHub Actions for every push to main branch.

1

Build Assets

Compile Tailwind CSS and precompile Rails assets

2

Package Application

Create tarball with all application code and dependencies

3

Upload to S3

Store deployment artifact in S3 for EC2 to download

4

Deploy to EC2

Execute deployment via AWS Systems Manager: download, extract, bundle install, migrate, restart

5

Verify Deployment

Health check both main and admin sites, rollback on failure

Average deployment time: ~2 minutes from push to live

Key Design Decisions

Why Rails over Next.js/React?

Rails provides a mature authentication system (Devise), built-in admin tools, and rapid development. For a portfolio that needs CMS capabilities and secure authentication, Rails is ideal. Turbo provides SPA-like experience without complex frontend build tooling.

Why EC2 over Heroku/Vercel?

EC2 demonstrates cloud infrastructure skills and provides full control over the environment. It shows I can configure Linux servers, manage systemd services, handle deployments, and optimize costs. This is more representative of real-world enterprise deployments.

Why PostgreSQL over MongoDB?

Portfolio data is relational (projects have skills, users have sessions). PostgreSQL provides ACID guarantees, excellent Rails integration with ActiveRecord, and is industry standard for production web applications. AWS RDS handles backups and maintenance.

Why Custom Spam Detection?

Instead of using third-party services (reCAPTCHA, Akismet), I built a multi-layer system with honeypots, keyword filtering, and risk scoring. This demonstrates algorithm design, data modeling, and provides a privacy-friendly solution without external dependencies or tracking.

Why Tailwind CSS v3?

Tailwind v4's CSS-first configuration didn't support class-based dark mode properly. I downgraded to v3 for reliable class-based dark mode with JavaScript control. This shows debugging skills and pragmatic decision-making over using the "latest" version.

Performance & Metrics

99.9%
Uptime
<200ms
Avg Response Time
A+
SSL Rating
~2min
Deploy Time

Want to see how it's built?

Explore the Source Code