Show HN: Fottly – Self-hosted image API with AI background removal Fottly, an open-source self-hosted image API with AI background removal, was released on Hacker News as a Cloudinary alternative. It supports resizing, format conversion, and background removal, caching results to avoid reprocessing, and uses S3-compatible storage (AWS S3, Cloudflare R2, MinIO) configured via environment variables. The service includes rate limiting (100 req/min per IP by default) and public image delivery, with authentication required only for file management. A self-hosted image transformation service with built-in AI background removal — an open-source Cloudinary alternative. Already tested and working: resizes, converts format, removes backgrounds, and caches the result so the same request is never processed twice. Source images and the result cache are read/written from S3-compatible storage AWS S3, Cloudflare R2, MinIO... , configured via environment variables. There's a browsable demo page at demo.html /Noah-1919/Fottly/blob/main/demo.html — open it in a browser with the stack running to build transformation URLs interactively. | Variable | Description | Example local MinIO | |---|---|---| S3 ENDPOINT | S3 endpoint URL. Leave empty for real AWS S3. | http://localhost:9000 | S3 REGION | Region. | us-east-1 | S3 BUCKET | Bucket where source images and the cache cache/... live. | fottly | S3 ACCESS KEY ID | Access key. | minioadmin | S3 SECRET ACCESS KEY | Secret key. | minioadmin | S3 FORCE PATH STYLE | true for MinIO/backends without virtual-hosted style. false on real AWS S3. | true | API KEY | Key required for authentication see the Authentication section below . | dev-secret-key | MAX UPLOAD SIZE MB | Maximum request body size, in megabytes applies to file uploads . | 25 | RATE LIMIT MAX | Maximum requests per IP within the time window see Rate limiting below . | 100 | RATE LIMIT WINDOW MS | Rate limit time window, in milliseconds. | 60000 | There's a .env.example with these values the same ones used by docker-compose.yml . All routes are globally rate-limited per IP RATE LIMIT MAX requests per RATE LIMIT WINDOW MS milliseconds, 100 req/min by default . Exceeding it returns 429 with X-RateLimit- headers indicating the limit, remaining requests, and reset time. The Authorization: Bearer