As a DevOps engineer and cloud architect, I wanted my personal website to reflect both my technical expertise and my commitment to modern development practices. In this post, I'll walk through the architecture and implementation details of this website, explaining the technical decisions and tools used.

Technology Stack

Static Site Generator: Pelican

I chose Pelican as the static site generator for several reasons: - Python-based: As someone who works extensively with Python, this allows me to easily extend and customize the site - Markdown Support: Content can be written in Markdown, making it easy to maintain and version control - Flexible Theming: Complete control over the site's appearance through Jinja2 templates - Active Community: Well-maintained with a robust ecosystem of plugins

Design System

The site's design emphasizes professionalism and readability through:

Color Palette

  • Burgundy (#6B1D1D): Primary accent color for headings and important elements
  • Red (#B92D2D): Secondary accent for interactive elements
  • Cream (#FFF6E9): Background color for improved readability
  • Navy (#1B2B44): Header and footer backgrounds
  • Light Blue (#9FB4D1): Subtle accents and hover states

Typography

  • Font Family: Inter with system fallbacks
  • Font Features: Ligatures and kerning for better readability
  • Font Weights: 400 for body text, 600 for emphasis, 800 for headings
  • Line Heights: 1.6 for body text, 1.2 for headings

Interactive Elements

  • Subtle hover animations on cards and buttons
  • Smooth transitions for color changes
  • Consistent shadow effects for depth
  • Responsive design patterns

Infrastructure and Deployment

Cloudflare Pages

The site is hosted on Cloudflare Pages, providing: - Global CDN with automatic HTTPS - Zero-configuration deployment - Automatic builds from Git - Preview deployments for pull requests

Infrastructure as Code with Pulumi

All infrastructure is managed through Pulumi using Python, allowing us to: - Define infrastructure in Python for consistency - Manage Cloudflare configurations programmatically - Version control our infrastructure - Automate DNS and security settings

Here's our Pulumi configuration:

import pulumi
import pulumi_cloudflare as cloudflare

# Create a Cloudflare Pages project
pages_project = cloudflare.PagesProject(
    "joelmerrick-blog",
    account_id=account_id,
    name="joelmerrick-blog",
    production_branch="main",
    build_config=cloudflare.PagesProjectBuildConfigArgs(
        build_command="pelican content -s publishconf.py",
        destination_dir="output",
    ),
    deployment_configs=cloudflare.PagesProjectDeploymentConfigsArgs(
        production=cloudflare.PagesProjectDeploymentConfigsProductionArgs(
            environment_variables={
                "PYTHON_VERSION": "3.12",
                "SITEURL": "https://joelmerrick.co.uk",
            },
        ),
        preview=cloudflare.PagesProjectDeploymentConfigsPreviewArgs(
            environment_variables={
                "PYTHON_VERSION": "3.12",
                "SITEURL": "${CF_PAGES_URL}",
            },
        ),
    ),
)

CI/CD Pipeline

The continuous integration and deployment pipeline is implemented using GitHub Actions, automating: 1. Code quality checks (black, isort, flake8, mypy) 2. Testing with pytest 3. Building with Pelican 4. Infrastructure deployment with Pulumi 5. Deployment verification

Additionally, we use GitHub's Dependabot for automated dependency management:

graph TD
    A[Dependabot] --> B[Daily Checks]
    B --> C{Updates Available?}
    C -->|Yes| D[Create PR]
    D --> E[Run CI Tests]
    E --> F{Tests Pass?}
    F -->|Yes| G[Ready for Review]
    G --> H[Auto-merge if Configured]
    F -->|No| I[PR Needs Attention]
    C -->|No| J[End]

The dependency management workflow: 1. Monitors three ecosystems: - Python (pip) dependencies - npm packages - GitHub Actions 2. Creates separate pull requests for each update 3. Runs our full test suite 4. Labels and assigns reviewers automatically 5. Can be configured for auto-merge on passing tests

Here's our Dependabot configuration:

version: 2
updates:
  - package-ecosystem: "pip"
    directory: "/"
    schedule:
      interval: "daily"
    labels:
      - "dependencies"
      - "python"

  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "daily"
    labels:
      - "dependencies"
      - "javascript"

  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "daily"
    labels:
      - "dependencies"
      - "github-actions"

Here's our main workflow:

name: Build and Deploy
on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

permissions:
  contents: write

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Format code
        run: |
          pip install black isort flake8 mypy
          black .
          isort .
      - name: Commit changes
        run: |
          git config --local user.email "github-actions[bot]@users.noreply.github.com"
          git config --local user.name "github-actions[bot]"
          git add .
          git diff --quiet && git diff --staged --quiet || git commit -m "Apply code formatting"
      - name: Push changes
        uses: ad-m/github-push-action@master
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          branch: ${{ github.ref }}

Testing and Quality Assurance

The project includes comprehensive testing: - Unit Tests: Testing individual components and utilities - Integration Tests: Ensuring different parts work together - Link Checking: Validating internal and external links - HTML Validation: Ensuring valid HTML output - Accessibility Testing: Using tools like Pa11y for accessibility compliance - Deployment Testing: Automated verification of DNS, SSL, and custom domains

Here's our testing workflow:

graph LR
    A[Code Changes] --> B[Unit Tests]
    B --> C[Integration Tests]
    C --> D[E2E Tests]
    D --> E[Security Checks]
    E --> F[Deploy]

    subgraph Security Checks
    G[Dependabot Alerts]
    H[Vulnerability Scan]
    I[License Check]
    end

Performance Optimization

Several optimizations are implemented: 1. Image Optimization: Automatic WebP conversion and responsive images 2. CSS Minification: Reducing CSS file size 3. Lazy Loading: For images and non-critical resources 4. Cache Headers: Proper cache control headers for static assets 5. Critical CSS: Inlining critical styles for faster initial render 6. Modern CSS Features: Using CSS variables and modern layout techniques

Security Considerations

Security is implemented through multiple layers: - HTTPS Only: Forced HTTPS through Cloudflare - Content Security Policy: Strict CSP headers - SRI Hashes: For external resources - Security Headers: Including HSTS, X-Content-Type-Options, etc. - SSL/TLS Configuration: Strict SSL mode with minimum TLS 1.2 - Dependency Management: * Automated updates via Dependabot * Security vulnerability scanning * Automated testing of updates * Version pinning and resolutions * Strict engine requirements * Daily monitoring of three ecosystems (Python, npm, GitHub Actions)

Here's our security architecture:

graph TD
    A[User Request] --> B[Cloudflare CDN]
    B --> C{Security Checks}
    C --> D[WAF Rules]
    C --> E[Bot Protection]
    C --> F[DDoS Mitigation]
    C --> G[SSL/TLS]
    C --> H[Security Headers]

    subgraph Headers
    I[CSP]
    J[HSTS]
    K[X-Frame-Options]
    L[Referrer-Policy]
    end

Development Workflow

The development workflow is streamlined for efficiency: 1. Local development using Poetry for dependency management 2. Pre-commit hooks for code quality 3. Automated testing on pull requests 4. Preview deployments for visual verification 5. Automated production deployments with verification

Here's our development workflow:

flowchart LR
    A[Local Changes] --> B[Pre-commit Hooks]
    B --> C[Push to GitHub]
    C --> D[CI/CD Pipeline]
    D --> E[Preview Deploy]
    E --> F{Approved?}
    F -->|Yes| G[Production Deploy]
    F -->|No| A

Future Improvements

Planned enhancements include: - Integration with a headless CMS for easier content management - Enhanced search functionality - Performance monitoring and analytics - Integration with external services via APIs - Automated image optimization pipeline - Advanced caching strategies

Conclusion

Building this site has been an exercise in applying modern web development practices while keeping things simple and maintainable. The combination of Pelican, Cloudflare Pages, and automated workflows provides a robust foundation that can evolve with my needs.

The complete source code is available on GitHub, demonstrating these concepts in practice.