favicon

Favicon Fetcher Service

License

This repository contains two variants of a high-performance service that fetches, caches, and serves website favicons:

  1. Docker/Node.js Variant: A traditional server application designed to run in a Docker container on platforms like Heroku, GCP Cloud Run, or any standard server.
  2. Cloudflare Worker Variant: A serverless version rewritten to run on Cloudflare’s global edge network for extremely low latency.

Features


API Usage

Base URL: https://your-app-url.com/

All parameters and their values are case-insensitive. Parameters can be provided via URL query string or request headers, with query string values taking precedence.

Example 1: Get Image (Default)

Request: GET /?domain=Github.com&S=128

Example 2: Get Base64 JSON

Request: GET /?domain=github.com&s=128&b64=TRUE

Example 3: Authentication

Request: GET /?domain=google.com&key=mysecretkey0 (Header-based authentication is also supported)


Deployment

The Cloudflare Worker variant runs on Cloudflare’s edge network for the lowest possible latency. The deploy button will automatically guide you through creating the required KV namespaces.

Deploy to Cloudflare Workers

Required Manual Step (After Deployment): For security, you must add your API keys as secrets after the initial deployment.

  1. In the Cloudflare dashboard, navigate to your newly deployed Worker.
  2. Go to Settings -> Variables.
  3. Under Environment Variables, click Add variable, enter the name (e.g., AUTHN0), enter the secret value, and click Encrypt.

Deploy to Heroku (Docker Variant)

Option 1: Deploy with Managed Redis (Production Ready) Deploy to Heroku with Redis

Option 2: Deploy Manually or In-Memory Deploy to Heroku

Deploy to GCP Cloud Run (Docker Variant)

Run on Google Cloud


Local Development (Docker Variant)

  1. Clone the repository and cd into it.
  2. Review the example configuration in docker-compose.yml to understand available environment variables.
  3. (Optional) Customize your local config:
    • Edit docker-compose.yml directly, OR
    • Create a .env file with your custom values (Docker Compose will use it automatically)
  4. Run with Docker Compose: docker-compose up --build

The service will be available at http://localhost:8080.

Example .env File (Optional)

If you prefer using a .env file instead of editing docker-compose.yml:

PORT=8080
REDIS_URL=redis://redis:6379
CACHE_ENABLED=true
CACHE_TTL_SECONDS=86400
REQ_TIMEOUT_MS=5000
HTML_PAYLOAD_LIMIT=250000
ICON_PAYLOAD_LIMIT=2097152
DEBUG=false

# Optional: DNS over HTTPS
# DOH1=https://dns.google/dns-query
# DOH2=https://cloudflare-dns.com/dns-query

# Optional: API Keys and Rate Limits
# AUTHN0=your_secret_key_here
# LIMIT0=rps:10,rpm:500

# Anonymous Rate Limits
LIMITA=rps:1,rpm:60
LIMITI=rpm:30

Environment Variables (Docker Variant)

Variable keys (e.g., PORT, AUTHN0) are case-sensitive.

Variable Description Default
PORT The port the server listens on. 8080
REDIS_URL Connection string for Redis. If not set, the app falls back to in-memory mode. "" (none)
DOH1, DOH2 Optional DoH endpoints. DOH1: https://cloudflare-dns.com/dns-query, DOH2: https://dns.google/dns-query. "" (none)
DEBUG Set to true to enable detailed console logging for troubleshooting. false
LIMIT_SEPARATOR Character for separating multiple rate limit rules. Defaults to ,. Set to ; for GCP. ,
CACHE_ENABLED Enables/disables caching (true/false). true
CACHE_TTL_SECONDS Cache expiration time in seconds. 86400 (24h)
IN_MEMORY_CACHE_MAX_SIZE Max cache size (in bytes) for in-memory mode. 52428800 (50MB)
REQ_TIMEOUT_MS Milliseconds to wait for target sites. 5000 (5s)
HTML_PAYLOAD_LIMIT Max HTML size to download (in bytes). 250000 (250KB)
ICON_PAYLOAD_LIMIT Max icon file size to download (in bytes). 2097152 (2MB)
CUSTOM_USER_AGENT Override the default User-Agent string. Mozilla/5.0 (Macintosh...)
AUTHN[0-1000] API key. e.g., AUTHN0=key_abc. ""
LIMIT[0-1000] Rate limit for the corresponding API key. e.g., LIMIT0=rps:10,rpm:500. ""
LIMITA Global rate limit for all anonymous users. rps:1,rpm:60
LIMITI Per-IP rate limit for anonymous users. Applied in addition to LIMITA. ""

Limit Format

Limits are defined as a comma/semicolon-separated list of unit:value pairs or just value (defaults to rps).

📜 License

Dual Licensed: Personal Non-Commercial OR Commercial

⚠️ Important: This software is available for personal, non-commercial use only under the free license.

Prohibited without commercial license:

Commercial licenses available: Contact https://www.kalman.co.il

Full terms: LICENSE.md