Per gi0baro's benchmarks, nginx halves dynamic throughput (1120 vs 2300 req/s)
while only marginally improving static serving. Granian's --static-path-route
serves photography and static files directly with 7-day cache headers.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Nginx serves photography images and static assets directly from disk,
proxies everything else to Granian with response caching. Adds gzip
compression and request buffering.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Performance CPUs require 4GB minimum — shared-cpu-2x with 2 workers
is more cost-effective for this workload.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
PDF generation and OG image rendering block a worker — multiple
workers keep the site responsive during heavy operations.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Initial Responder port — core content serving working
Homepage, markdown pages, directory listings, image galleries
all rendering. Flask template compatibility via RequestWrapper
and FakeConfig shims.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Complete Responder port — all routes working
Ported all routes from Flask blueprints: archive, search, OG images,
RSS, sitemap, robots.txt, API endpoints, directory browser.
All 25+ routes returning 200.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Update Dockerfile for Responder, warm caches on import
CMD now runs engine_responder:api via uvicorn.
Cache warming happens on module import for production.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Rename engine_responder.py to engine.py
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Update colophon for Responder
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Fix essay pages, OG images, and PDF export
- Fix find_related_posts and find_adjacent_posts call signatures
- Fix OG image route to use path:path for nested paths
- Add PDF export route with WeasyPrint
- All test plan items passing
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Replace gunicorn/gevent with uvicorn for ASGI support
- Add asgiref to wrap Flask WSGI app for uvicorn compatibility
- Enable auto-reload in docker-compose for development
- Add current_path to all content render_template calls
- Simplify breadcrumb template to exclude current page
- Only show breadcrumbs for nested paths (> 1 segment)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Update Dockerfile base image, pyproject.toml requirements, and .python-version to use Python 3.14. This includes updating the uv.lock file with the new Python version constraint.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add WeasyPrint dependencies to Dockerfile for server-side PDF generation
- Update README with Quick Start guide for Docker and local development
- Add PDF template for article rendering
- Add error template for better error handling
- Reorganize photography into top-12 subdirectory
- Update pyproject.toml with PDF generation dependencies
- Enhance content.py with PDF rendering capabilities
- Improve directory template with gallery features
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Copy tuftecms directory before install step since pyproject.toml force-includes templates and static directories.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add /games route with three inline JavaScript games (Snake, Pong, Breakout). Fix Dockerfile to copy README.md before install step since pyproject.toml references it.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Updated docker-compose.yml to mount data directory for improved file access.
- Implemented a unified cache generation function in engine.py to streamline cache creation for blog posts, sidenotes, outlines, quotes, connections, and terms.
- Replaced individual cache extraction functions with a single MetadataCache class for cleaner access to cached data.
- Modified prebuild_cache.py to utilize the new unified cache function, ensuring all cache files are generated in a single sweep.
- Enhanced outlines.html template to simplify anchor URL generation for headings.
Updated Dockerfile to use official astral/uv:python3.13-bookworm base image instead of copying uv from separate image, simplifying build process. Fixed docker-compose.yml to preserve pre-built cache directory when mounting local files, ensuring instant startup works in both production and local development environments.
Changes:
- Use astral/uv:python3.13-bookworm as base image
- Remove multi-stage copy of uv binary
- Add cache volume preservation in docker-compose
- Maintain instant startup with pre-built caches in all environments
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added prebuild_cache.py script that generates all site caches (blog posts, sidenotes, outlines, quotes, connections, terms) as JSON files during Docker build. Modified engine.py to load pre-built caches on startup, eliminating the 30-40 second cache preload delay and making the site instantly responsive.
Key improvements:
- Zero startup delay with pre-built caches
- Proper datetime serialization/deserialization
- Graceful fallback to runtime caching if pre-built files missing
- Technology serving human consciousness - mechanical work during build, instant experience for users
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Updated styles in directory.html for improved readability and aesthetics, including color adjustments and hover effects.
- Enhanced directory item display with better spacing and tracking for text elements.
- Improved loading animations and transitions for a smoother user experience.
- Refactored mindmap.html to implement an Obsidian-style theme with new CSS variables for consistent styling.
- Added control and search panels to the mindmap for better user interaction.
- Implemented a class-based structure for mindmap functionality, improving code organization and maintainability.
- Enhanced node and link rendering in the mindmap with dynamic styling based on node types.
- Added tooltip functionality for nodes in the mindmap to provide contextual information.
- Improved responsiveness and accessibility of both templates.