Skip to content

Country statistics and Caddy ​

ReleaseDesk records a country for downloads and feed requests, shown in Devices and analytics. The client IP is never stored.

Where the country comes from ​

In order:

  1. CF-IPCountry (two-letter ISO code) when present and not XX.
  2. Otherwise, if RD_GEOIP_DB points to a MaxMind GeoLite2/GeoIP2 Country or City .mmdb file, a lookup of the client IP taken from CF-Connecting-IP, else the first X-Forwarded-For entry. The IP is used only for the lookup and never stored.

With neither, country breakdowns stay empty. The database is read once at startup; restart after updating it. An unreadable file logs an error and disables lookups.

Without Cloudflare, set RD_GEOIP_DB to a country .mmdb: MaxMind GeoLite2-Country (free, needs an account) or DB-IP "IP to Country Lite" (free, no account, CC BY 4.0 - credit DB-IP if you publish the data). Caddy sets X-Forwarded-For to the real client address when it is the edge proxy.

Do not trust the header from the internet ​

If Caddy is reachable directly (not only through Cloudflare), anyone can send a fake CF-IPCountry. Pick one setup.

Keep the header, and take the real client IP from Cloudflare so logs and rate limits are correct. Restrict the origin firewall to Cloudflare IP ranges.

caddyfile
{
	email {$ACME_EMAIL}
	servers {
		trusted_proxies static 173.245.48.0/20 103.21.244.0/22 103.22.200.0/22 103.31.4.0/22 141.101.64.0/18 108.162.192.0/18 190.93.240.0/20 188.114.96.0/20 197.234.240.0/22 198.41.128.0/17 162.158.0.0/15 104.16.0.0/13 104.24.0.0/14 172.64.0.0/13 131.0.72.0/22
		client_ip_headers CF-Connecting-IP
	}
}

{$RD_DOMAIN} {
	encode zstd gzip
	request_body {
		max_size 4GB
	}
	reverse_proxy releasedesk:3000 {
		transport http {
			read_timeout 30m
			write_timeout 30m
		}
	}
}

Check the range list against Cloudflare's published one; it changes.

Without Cloudflare ​

Strip the header so clients cannot forge it, and use RD_GEOIP_DB for country.

caddyfile
reverse_proxy releasedesk:3000 {
	header_up -CF-IPCountry
}

Deployment files ​

  • deploy/prod/Caddyfile: single site with automatic HTTPS and 30 minute upload timeouts. Requires RD_DOMAIN and ACME_EMAIL.
  • deploy/dev/caddy/Caddyfile: DNS-01 certificates through Cloudflare (CLOUDFLARE_API_TOKEN), plus an s3. site for presigned download URLs. Built by deploy/dev/caddy/Dockerfile with the caddy-dns/cloudflare module.

Both keep request_body max_size 4GB and long timeouts so large uploads are not cut off.