Production Guide
This guide covers best practices for running Manael safely and efficiently in production environments.
Caching and CDN
Manael is a stateless proxy and does not cache converted images internally. In production, place a CDN or caching layer in front of Manael to avoid redundant conversions and to reduce load on your origin server.
The Vary: Accept header
Manael automatically includes the Vary: Accept header in every response. This header instructs CDNs and intermediate caches to store separate copies of the same URL for each unique Accept header value. Without this, a CDN might serve a cached WebP image to a client that only supports JPEG, or vice versa.
HTTP/1.1 200 OK
Content-Type: image/webp
Vary: Accept
For a single image URL, a correctly configured CDN will maintain distinct cache entries for:
- Clients that accept
image/avif(served as AVIF when enabled) - Clients that accept
image/webp(served as WebP) - All other clients (served in the original format)
CDN configuration
Most CDNs respect the Vary header by default, but some require explicit configuration. Verify the following for your CDN:
| CDN | Action required |
|---|---|
| Cloudflare | Enable Polish or configure a Cache Rule that respects Vary: Accept. |
| Fastly | Respect Vary headers by default; no additional configuration needed. |
| Amazon CloudFront | Create a Cache Policy that includes Accept in the list of allowed headers. |
| Google Cloud CDN | Enable cache-mode CACHE_ALL_STATIC and ensure Vary headers are forwarded. |
Always test your CDN configuration by requesting the same URL with different Accept headers and confirming that each variant is cached independently.
Security
Upstream locking
Manael locks the upstream target at startup using the -upstream_url flag (or the MANAEL_UPSTREAM_URL environment variable). All incoming requests are proxied exclusively to that single upstream origin. It is not possible to redirect Manael to a different host at request time.
This design prevents Manael from being exploited as an open proxy. Attackers cannot craft requests that cause Manael to fetch arbitrary URLs from internal networks or third-party services, which eliminates the class of vulnerabilities known as Server-Side Request Forgery (SSRF).
Recommendations:
- Set
-upstream_urlto the narrowest possible scope (e.g., a specific bucket or host) rather than a broad network segment. - Run Manael in a network environment where outbound traffic is restricted to the upstream origin only, using firewall rules or a service mesh egress policy.
Resource tuning
Image conversion—especially AVIF encoding—is CPU- and memory-intensive. Without appropriate resource limits, a single Manael instance can exhaust node resources and affect other workloads running on the same host.
Kubernetes
Always set resource requests and limits in your Deployment manifest:
resources:
requests:
cpu: "250m"
memory: "256Mi"
limits:
cpu: "1000m"
memory: "1Gi"
Increase the memory limit to 2Gi when AVIF conversion (MANAEL_ENABLE_AVIF=true) is enabled under sustained traffic. Prefer horizontal scaling (increasing replicas) over increasing per-pod limits.
Amazon ECS
Set cpu and memory in your task definition:
{
"cpu": "1024",
"memory": "1024"
}
cpu is expressed in CPU units (1024 = 1 vCPU) and memory in MiB. For AVIF workloads, a value of 2048 MiB or higher is recommended.
Maximum image size
Manael rejects upstream responses that exceed the size configured by the MANAEL_MAX_IMAGE_SIZE environment variable (default: 20 MiB). Lowering this value reduces peak memory usage per request and limits the impact of unexpectedly large images from the upstream origin.
MANAEL_MAX_IMAGE_SIZE=10485760 manael -http=:8080 -upstream_url=https://storage.example.com