Python
Django
PostgreSQL
Elasticsearch
Redis
Celery
RabbitMQ
Docker
AWS
GCP

Photographer Explorer is an international directory of professional photographers. Besides portfolio management, the platform provides numerous discoverability and social networking features, such as search, messaging, client recommendations, activity metrics, and photography contests. The platform is available in two languages and currently hosts photographer profiles across Europe, Asia, North America, and Oceania.
I developed Photographer Explorer on my own, from scratch, as a full-time project, for two simple reasons: I love photography, and I wanted to create a platform that is technically capable and interesting enough to have an international reach.
The design goals were:
- Scalability to handle tens of thousands of photographers, their clients, and millions of messages grouped into conversations.
- Reliable accessibility anywhere in the world, with mostly sub-second page load times.
- Localization to each user’s geography through location-aware search and recommendations.
- Support for translations and language preferences.
- Tiered usage quotas and request rate limits.
- Reasonable security against attacks such as DDoS and password cracking.
- Automation of as much of the platform’s maintenance as possible.
- Paid subscriptions with free trial periods.
- Strict GDPR compliance.
Architecture
flowchart TB
browser[[Browser]]
cloudflare@{ shape: cloud, label: Cloudflare }
subgraph docker[Docker]
direction TB
nginx@{ shape: procs }
subgraph logic[Logic layer]
direction TB
web@{ shape: procs, label: "Gunicorn + Django" }
worker@{ shape: procs, label: "Celery Worker + Beat" }
cron[Cron]
end
subgraph data[Data layer]
direction TB
redis[(Redis)]
pgbouncer[PgBouncer]
postgres[(PostgreSQL)]
elasticsearch[(Elasticsearch)]
rabbitmq@{ shape: h-cyl, label: RabbitMQ }
pgbouncer --> postgres
end
subgraph ops[Operations layer]
direction TB
portainer[Portainer]
logspout
end
nginx --> logic
logic --> data
data ~~~ ops
end
subgraph cloud[Cloud services]
direction TB
s3[Amazon S3]
ses[Amazon SES]
oauth[Google OAuth2]
maps[Google Maps API]
places[Google Places API]
recaptcha[Google reCaptcha]
maxmind[MaxMind]
geonames[GeoNames]
locationiq[LocationIQ]
paddle[Paddle]
sentry[Sentry]
papertrail[Papertrail]
s3 ~~~ ses ~~~ oauth
maps ~~~ places ~~~ recaptcha
maxmind ~~~ geonames ~~~ locationiq
paddle ~~~ sentry ~~~ papertrail
end
browser --> cloudflare --> docker --> cloud
cloudflare --> cloud
browser --> cloud