232 Commits

Author SHA1 Message Date
kennethreitz e41d1a8526 compose: pass S3 custom domain and addressing style through
Needed for the MinIO storage flip; unset values fall back to the
Tigris defaults in settings.py.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 02:15:05 -04:00
kennethreitz e29aefc065 Make S3 custom domain and addressing style env-driven
Defaults unchanged (Tigris virtual-host style); MinIO needs
path-style and a custom public host.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 02:08:15 -04:00
kennethreitz 568db35de4 compose: attach services to dokploy-network for DB + Traefik reachability
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 01:03:32 -04:00
kennethreitz 1125efdb48 Remove Fly workflows; deploys now via Dokploy compose webhook on mercury
daily-restart was a Fly-era band-aid (see CLAUDE.md); drop it too.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 01:01:03 -04:00
kennethreitz 2dd48eae6b compose: pass Celery broker/result URLs, note healthcheck host
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 00:59:05 -04:00
kennethreitz 6ff67cfb90 Add production compose file for Dokploy on mercury
Web (runbolt) + Celery worker from one image; Postgres stays a
Dokploy-managed database reached over dokploy-network.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 00:54:37 -04:00
kennethreitz 59de5e4d3a Sync CLAUDE.md infrastructure section with reality
The infra section had drifted: claimed two processes (web + worker)
and 4GB dedicated Postgres, neither of which has been true for weeks.
Also documents the Tigris CORS config and the daily-restart workflow
so future sessions know they exist.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 21:00:05 -04:00
kennethreitz 08247c2b1d Drop DbRetryMiddleware, make logger async, bump django-bolt
Wedges resumed despite the April 16 DB-timeout fix, and this time with
zero ESTABLISHED connections to Postgres — so not a DB deadlock. Most
suspicious piece is DbRetryMiddleware itself: its async path awaits
sync_to_async(...) inside an exception handler, a known-tricky pattern
on the asgiref thread pool. Django already handles stale-connection
recovery via conn_health_checks=True plus the psycopg connect_timeout/
statement_timeout added earlier, so the retry layer isn't load-bearing.

Also:
- RequestLoggingMiddleware is now async-capable, so the full chain
  stays async for async views instead of hopping through the thread
  pool on every request.
- Bump django-bolt 0.7.4 → 0.7.5 for any upstream fixes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 23:12:03 -04:00
kennethreitz efccf79fd8 Prevent app wedge when Postgres restarts
Two problems caused the whole app to hang after DB restarts, not just
return errors:

1. psycopg had no timeouts, so in-flight queries blocked forever on a
   half-open TCP socket after the Postgres backend died. That starved
   the ASGI worker pool — even /health queued behind stuck threads.
   Adds connect_timeout, TCP keepalives, and server-side
   statement_timeout so broken connections surface as errors in
   seconds rather than hanging indefinitely.

2. DbRetryMiddleware was sync-only; django-bolt mounts Django under
   ASGI, so async views never actually went through the retry path.
   It also used close_old_connections() which respects CONN_MAX_AGE
   and leaves freshly-broken connections in place. Rewritten with
   sync+async support and an explicit conn.close() on all connections
   before retry. Also catches InterfaceError (psycopg3 closed-conn).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-16 16:36:14 -04:00
kennethreitz 0a5024822c Add daily rolling restart workflow
Mitigates long-running app wedges (e.g. request-loop deadlocks that
leave the machine 'started' but unresponsive). Runs at 08:00 UTC with
manual dispatch available.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-16 15:25:26 -04:00
kennethreitz 15ec7fac43 Add composite index for public image listing query
Covers (visibility, is_processing, upload_date) which is the
primary filter used across the site.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 17:35:46 -04:00
kennethreitz 6bd507ce09 Add DB retry middleware for Postgres restart resilience
Catches OperationalError from stale connections, closes them,
and retries the request once. Prevents 500s after DB restarts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 14:42:53 -04:00
kennethreitz ee10a7a898 Log bot name and user-agent for crawler requests
Helps identify which bots are hitting the site and how often.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 10:47:40 -04:00
kennethreitz 45b0b25799 Remove 5000 image cap from sitemap
All public images should be discoverable by search engines.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 10:43:42 -04:00
kennethreitz 961a0d45ea Bump VM memory to 2GB and add crawler rate limits
OOM crash took the site down — increase memory from 1GB to 2GB.
Add Crawl-delay to robots.txt to throttle aggressive bots.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 10:41:31 -04:00
kennethreitz 48cc7bf8b0 Add random photo button in nav
/random/ picks a random public image and redirects to its
detail page. Shows as the last nav item after Search.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 01:27:04 -04:00
kennethreitz dbdbdea109 Polish: Inter font, glassmorphic nav, hover effects, view transitions
- Add Inter font via Google Fonts with proper preconnect
- Nav: backdrop-filter blur with semi-transparent background
- Image cards: hover-reveal overlay, inner zoom, shadow on hover
- Gear/collection cards: hover lift with shadow
- EXIF bar: rounded card style instead of bordered lines
- Search inputs: accent focus glow ring
- Homepage: display site tagline, more generous hero spacing
- View Transitions API for smooth cross-page fades (Chrome 126+)
- Animated loading pulse for infinite scroll
- Global: smooth scroll, accent selection color, focus-visible
- Radius 6px→8px, font smoothing, CSS custom properties
- Fix stray </div> in base template
- Disable hover transforms on mobile

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 00:21:49 -04:00
kennethreitz 0fcf1bb31f Move prev/next + download to toolbar right under the photo
Prev on left, download centered, next on right — all directly
below the image for easy navigation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 21:18:31 -04:00
kennethreitz efd1dd5ca0 Collection photo count overlay + move prev/next above map
- Show photo count as badge overlaid on collection card images
- Move prev/next navigation to appear after EXIF/tags, before map
- Download dropdown now appears last

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 21:16:02 -04:00
kennethreitz 517357e5bb Add load more button back as fallback for scroll
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 10:26:32 -04:00
kennethreitz 2c978ced08 Fix embed infinite scroll: check hasMore before increasing batch size
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 10:16:48 -04:00
kennethreitz 898c509057 Embed: infinite scroll, 12 initial then 48 per page
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 10:07:04 -04:00
kennethreitz d5b003edb4 Add Gauges analytics to embed page
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 09:58:29 -04:00
kennethreitz 27d641e250 Add request logging middleware — method, path, status, duration to stdout
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 09:46:27 -04:00
kennethreitz b5f6b70f47 conn_max_age=10 — balance between reuse and not exhausting pool
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 19:45:26 -04:00
kennethreitz 1c69f2f187 Set conn_max_age=0 — close DB connections after each request
ASGI threads each hold a connection; with conn_max_age=60 they pile up
and exhaust Postgres max_connections on the shared 2GB instance.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 19:42:16 -04:00
kennethreitz 55f33b5eec Remove Celery worker from production — use thread fallback
Postgres broker eats all DB connections. Thread fallback handles
image processing and AI descriptions inline.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 16:48:57 -04:00
kennethreitz ceb61c15b0 Add /health endpoint for fast health checks, fix cold start timeout
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 16:02:20 -04:00
kennethreitz 816c7e111b Add health check for blue-green deploys
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 15:53:11 -04:00
kennethreitz 11f1890fca Image embed: camera and lens names link to gear pages
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 15:47:36 -04:00
kennethreitz 2de886dcf5 Image embed: clicking photo links to detail page
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 15:46:45 -04:00
kennethreitz dadb581689 Remove footer link from image detail embed
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 15:45:34 -04:00
kennethreitz b61acea86c Enable blue-green deploys
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 15:45:09 -04:00
kennethreitz 1ae4dc5518 Image embed: just photo + EXIF line, no title/description
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 15:44:03 -04:00
kennethreitz 8a9abdc341 Embed: start with 12 images, load more for rest
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 15:42:30 -04:00
kennethreitz e3f7562bbe Allow embed page in iframes (remove X-Frame-Options)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 15:28:47 -04:00
kennethreitz b4666fb8eb Fix embed to use bolt API correctly (no page param, use limit)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 15:23:49 -04:00
kennethreitz 2dac355b39 Interactive iframe embed: year pills, load more, EXIF overlays
oEmbed now returns an iframe pointing to /embed/ — full JS interactivity
like SoundCloud. Year filtering, lazy loading, load more button.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 15:19:21 -04:00
kennethreitz f0686ce799 Force center alignment on oEmbed footer link
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 15:17:26 -04:00
kennethreitz cddb882fff Fix oEmbed year pill fonts to sans-serif
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 15:15:36 -04:00
kennethreitz 763a85c6ce Fix oEmbed overlay font to sans-serif
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 15:14:00 -04:00
kennethreitz 8c7d87b4c5 Add year pills to homepage oEmbed (link to site with year filter)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 15:13:12 -04:00
kennethreitz 66a7410dc0 Revert overlay links — plain text, no clickable camera names
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 15:10:37 -04:00
kennethreitz 1e6109a101 EXIF overlays on oEmbed grid items, camera links on site overlays
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 15:08:35 -04:00
kennethreitz f9604266ac Revert overlay to original (camera + focal + aperture)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 15:06:48 -04:00
kennethreitz ba0ab1387f oEmbed: 44 photos (divisible by 4)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 15:03:34 -04:00
kennethreitz cb21b7cf3c oEmbed: increase max-width to 800px for bigger thumbnails
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 15:03:17 -04:00
kennethreitz e9acc1a642 Add lens + ISO to image overlay, fix oEmbed period
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 15:02:59 -04:00
kennethreitz 36b19c8a55 oEmbed: 4-column grid
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 15:01:58 -04:00
kennethreitz 58f12c8cfe oEmbed: 3-column grid for larger photos
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 15:00:32 -04:00