Skip to content

Commit b56dcf5

Browse files
gzigzigzeoDarthSim
andauthored
Version 4.0-pre docs (#11)
* Version 4.0-rc docs * Cache docs * Grammarly, fixed classification, addressed PR comments * Various fixes, addressed PR comments * Minor updates by the comments * Version 4-preview * Correct banner in latest version * Update glibc version and distro list * Update v4 autoquality docs * Fix checking relative links with lychee * Remove `IMGPROXY_DOWNLOAD_BUFFER_SIZE` and `IMGPROXY_BUFFER_POOL_CALIBRATION_THRESHOLD` docs * Change v4-pre label and URL --------- Co-authored-by: DarthSim <darthsim@gmail.com>
1 parent ea0edb8 commit b56dcf5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+6472
-5
lines changed

docusaurus.config.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,13 +100,17 @@ const config: Config = {
100100
routeBasePath: "/",
101101
sidebarPath: require.resolve("./sidebars.js"),
102102
// sidebarCollapsed: false,
103-
103+
lastVersion: "3.31.x",
104104
versions: {
105105
current: {
106106
label: "latest",
107107
path: "latest",
108108
banner: "unreleased",
109109
},
110+
"4-pre": {
111+
label: "4-beta.0",
112+
banner: "unreleased",
113+
},
110114
},
111115

112116
editUrl: "https://github.com/imgproxy/imgproxy-docs/tree/master/",

lefthook.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@ pre-push:
1212
commands:
1313
check-links:
1414
tags: docs
15-
run: command -v lychee && lychee docs README.md --exclude localhost --exclude x.com --exclude twitter.com --accept=200,429
15+
run: command -v lychee && lychee docs README.md --exclude localhost --exclude x.com --exclude twitter.com --accept=200,429 --root-dir "$(pwd)/static"

src/css/badge.css

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
.badge,
2-
.menu__list-item--badge a::after {
2+
.menu__list-item--badge .menu__link::after {
33
--ifm-badge-background-color: transparent;
44
--ifm-badge-border-width: 1px;
55
--ifm-badge-border-radius: 0.4em;
@@ -69,12 +69,12 @@ a.badge--pro:hover {
6969
text-decoration: none;
7070
}
7171

72-
.menu__list-item--badge a::after {
72+
.menu__list-item--badge .menu__link::after {
7373
top: 0;
7474
margin-left: auto;
7575
}
7676

77-
.menu__list-item.badge--pro a::after {
77+
.menu__list-item.badge--pro .menu__link::after {
7878
content: "pro";
7979
}
8080

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
description: Learn about imgproxy's processing pipeline
3+
---
4+
5+
# About the processing pipeline
6+
7+
imgproxy has a specific processing pipeline tuned for maximum performance. When you process an image with imgproxy, it does the following:
8+
9+
* If the source image format allows shrink-on-load, imgproxy uses it to quickly resize the image to the size that is closest to desired.
10+
* If it is needed to resize an image with an alpha-channel, imgproxy premultiplies one to handle alpha correctly.
11+
* imgproxy resizes the image to the desired size.
12+
* If the image colorspace need to be fixed, imgproxy fixes it.
13+
* imgproxy rotates/flip the image according to EXIF metadata.
14+
* imgproxy crops the image using the specified gravity.
15+
* imgproxy fills the image background if the background color was specified.
16+
* imgproxy applies filters.
17+
* imgproxy adds a watermark if one was specified.
18+
* And finally, imgproxy saves the image to the desired format.
19+
20+
This pipeline, using sequential access to source image data, allows for significantly reduced memory and CPU usage — one of the reasons imgproxy is so performant.
Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
---
2+
description: External cache options for imgproxy, including CDNs, nginx, and Varnish
3+
---
4+
5+
# External cache
6+
7+
External cache refers to caching layers in front of imgproxy, such as CDNs, reverse proxies, or caching appliances. These solutions provide edge caching, geo-distribution, and high-performance image delivery.
8+
9+
## CDN options
10+
11+
Most major CDNs (Cloudflare, Fastly, AWS CloudFront, Akamai, etc.) can cache imgproxy responses:
12+
13+
### Recommended CDN settings
14+
15+
* **Image optimization** - Disable CDN image optimization to avoid double-processing
16+
* **Compression** - In case your CDN supports conditional compression of SVG images, enable gzip/Brotli compression for bandwidth savings
17+
* **Include essential headers*** - Include `Accept` header in the cache key if you're using [format negotiation](../configuration/options.mdx#avifwebpjpeg-xl-support-detection). If you have [client hints](../configuration/options.mdx#client-hints-support) enabled, include also `DPR`, `Sec-CH-Dpr`, and `Sec-CH-Width` headers.
18+
* **Origin shield** - Add a secondary cache layer between your CDN and imgproxy origin if your CDN supports it.
19+
20+
## nginx caching
21+
22+
nginx can act as a reverse proxy cache in front of imgproxy:
23+
24+
```nginx
25+
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=imgproxy_cache:10m max_size=50g inactive=30d;
26+
27+
upstream imgproxy {
28+
server localhost:8080;
29+
}
30+
31+
server {
32+
listen 80;
33+
server_name images.example.com;
34+
35+
# Uncomment if you do not use format negotiation and client hints
36+
# proxy_cache_key "$scheme$proxy_host$request_uri";
37+
38+
# Uncomment if you use format negotiation
39+
# proxy_cache_key "$scheme$proxy_host$request_uri$http_accept";
40+
41+
# Uncomment if you use client hints
42+
# proxy_cache_key "$scheme$request_method$host$request_uri:dpr=$http_dpr:width=$http_width:chdpr=$http_sec_ch_dpr:chwidth=$http_sec_ch_width";
43+
44+
# Uncomment if you use format negotiation and client hints
45+
# proxy_cache_key "$scheme$request_method$host$request_uri:accept=$http_accept:dpr=$http_dpr:width=$http_width:chdpr=$http_sec_ch_dpr:chwidth=$http_sec_ch_width";
46+
47+
location / {
48+
proxy_pass http://imgproxy;
49+
50+
# Cache configuration
51+
proxy_cache imgproxy_cache;
52+
proxy_cache_valid 200 30d;
53+
proxy_cache_valid 404 1m;
54+
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
55+
proxy_cache_background_update on;
56+
proxy_cache_lock on;
57+
proxy_cache_bypass $http_pragma $http_authorization;
58+
proxy_no_cache $http_pragma $http_authorization;
59+
60+
# Add cache status header for debugging
61+
add_header X-Cache-Status $upstream_cache_status;
62+
}
63+
}
64+
```
65+
66+
### Possible cache key setup
67+
68+
The exact key depends on which imgproxy features can change output for the same URL.
69+
70+
1. Basic key when output depends only on URL/path options:
71+
72+
```nginx
73+
proxy_cache_key "$scheme$proxy_host$request_uri";
74+
```
75+
76+
2. Include [format negotiation](../configuration/options.mdx#avifwebpjpeg-xl-support-detection) signal when WebP/AVIF/JXL preference can vary by client:
77+
78+
```nginx
79+
proxy_cache_key "$scheme$proxy_host$request_uri$http_accept";
80+
```
81+
82+
3. Include [Client Hints](../configuration/options.mdx#client-hints-support) dimensions when width/DPR affects output:
83+
84+
```nginx
85+
proxy_cache_key "$scheme$request_method$host$request_uri:accept=$http_accept:dpr=$http_dpr:width=$http_width:chdpr=$http_sec_ch_dpr:chwidth=$http_sec_ch_width";
86+
```
87+
88+
Use the smallest key that still prevents collisions for your traffic profile.
89+
90+
### Key recommendations
91+
92+
* Include `Accept` in the cache key if [format negotiation](../configuration/options.mdx#avifwebpjpeg-xl-support-detection) is used.
93+
* Include DPR/width-related hints in the cache key if [Client Hints](../configuration/options.mdx#client-hints-support) are used to vary output.
94+
* Set long `inactive` timeout (30d) to keep popular images in cache.
95+
* Configure `proxy_cache_use_stale` for graceful degradation during origin issues.
96+
* Monitor `/proc/sys/fs/file-max` and increase if needed for large caches.
97+
* Use separate cache zones for different image types if needed.
98+
99+
## Varnish caching
100+
101+
Varnish is a powerful reverse proxy cache optimized for HTTP performance:
102+
103+
```vcl
104+
vcl 4.1;
105+
106+
backend imgproxy {
107+
.host = "localhost";
108+
.port = "8080";
109+
.connect_timeout = 600ms;
110+
.first_byte_timeout = 600s;
111+
.between_bytes_timeout = 60s;
112+
}
113+
114+
sub vcl_recv {
115+
set req.backend_hint = imgproxy;
116+
117+
# Cache only GET and HEAD requests
118+
if (req.method != "GET" && req.method != "HEAD") {
119+
return (pass);
120+
}
121+
122+
# Include important headers in cache key
123+
if (req.http.Accept) {
124+
set req.http.X-Accept = req.http.Accept;
125+
}
126+
127+
# Keep DPR if Client Hints are not enabled
128+
if (req.http.DPR) {
129+
set req.http.X-DPR = req.http.DPR;
130+
}
131+
132+
if (req.http.Width) {
133+
set req.http.X-Width = req.http.Width;
134+
}
135+
136+
if (req.http.Sec-CH-DPR) {
137+
set req.http.X-CH-DPR = req.http.Sec-CH-DPR;
138+
}
139+
140+
if (req.http.Sec-CH-Width) {
141+
set req.http.X-CH-Width = req.http.Sec-CH-Width;
142+
}
143+
}
144+
145+
sub vcl_hash {
146+
# Base hash
147+
hash_data(req.url);
148+
hash_data(req.http.Host);
149+
150+
# Include Accept header for format negotiation
151+
if (req.http.X-Accept) {
152+
hash_data(req.http.X-Accept);
153+
}
154+
155+
# Include DPR if present
156+
if (req.http.X-DPR) {
157+
hash_data(req.http.X-DPR);
158+
}
159+
160+
if (req.http.X-Width) {
161+
hash_data(req.http.X-Width);
162+
}
163+
164+
if (req.http.X-CH-DPR) {
165+
hash_data(req.http.X-CH-DPR);
166+
}
167+
168+
if (req.http.X-CH-Width) {
169+
hash_data(req.http.X-CH-Width);
170+
}
171+
}
172+
173+
sub vcl_backend_response {
174+
# Cache successful responses for 30 days
175+
if (beresp.status == 200) {
176+
set beresp.ttl = 30d;
177+
set beresp.keep = 30d;
178+
}
179+
180+
# Cache 404s for a short period
181+
if (beresp.status == 404) {
182+
set beresp.ttl = 1m;
183+
}
184+
185+
# Enable cache using stale object if backend is down
186+
set beresp.grace = 24h;
187+
}
188+
189+
sub vcl_deliver {
190+
# Add cache hit/miss header
191+
if (obj.hits > 0) {
192+
set resp.http.X-Cache = "HIT";
193+
set resp.http.X-Cache-Hits = obj.hits;
194+
} else {
195+
set resp.http.X-Cache = "MISS";
196+
}
197+
}
198+
```
199+
200+
### Key recommendations
201+
202+
* Use `sub vcl_hash` to customize cache key behavior.
203+
* Include `Accept` for [format negotiation](../configuration/options.mdx#avifwebpjpeg-xl-support-detection).
204+
* Include DPR/width-related headers when [Client Hints](../configuration/options.mdx#client-hints-support) support is enabled (`DPR`, `Width`, `Sec-CH-DPR`, `Sec-CH-Width`).
205+
* Set grace period (`beresp.grace`) for graceful error handling.
206+
* Monitor Varnish statistics with `varnishstat`.
207+
* Use tags for efficient cache purging: add `set beresp.http.Surrogate-Key = "images:product:123"` in `vcl_backend_response`.
208+
* Configure workspace limits if caching many large images.
209+
210+
## Cache headers from imgproxy
211+
212+
imgproxy sends the following headers useful for external caching:
213+
214+
* `Cache-Control: public, max-age=31536000` - Long-term caching (1 year default, configurable with `IMGPROXY_TTL`)
215+
* `ETag` - If `IMGPROXY_USE_ETAG=true` (by default), enables conditional requests
216+
* `Last-Modified` - If `IMGPROXY_USE_LAST_MODIFIED=true` (by default), enables conditional requests
217+
* `Content-Type` - Important for cache key if not in `Accept` header
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
---
2+
title: Internal cache
3+
description: Learn about how to configure and use imgproxy's internal cache
4+
---
5+
6+
# Internal cache ((pro))
7+
8+
imgproxy Pro provides an internal cache that stores processed images on disk or in cloud storage. This cache can act as both a primary and a secondary cache, serving as a fallback when your CDN cache misses.
9+
10+
:::tip
11+
While putting a CDN in front of imgproxy is and will always be a best practice, the internal cache provides long-term storage for cases that require an additional caching layer.
12+
:::
13+
14+
## Why use internal cache?
15+
16+
The internal cache provides long-term persistent storage for processed images, unlike CDNs, which typically delete rarely accessed content. It stores images in a single location rather than across multiple edge stores, eliminating cache misses when requests hit different edges. The cache is designed specifically for imgproxy, working seamlessly with features like modern image format detection and client hints support that generic external caches don't understand by default.
17+
18+
The cache is protected by the same security measures as imgproxy itself, including URL signatures and processing restrictions. Importantly, URL signatures are not part of the cache key, so you can rotate keys or use multiple key/salt pairs without invalidating cached images. You maintain full control over where the cache is stored and how it integrates with your infrastructure.
19+
20+
## Configuration
21+
22+
You need to define the following config variables to enable the internal cache:
23+
24+
* [`IMGPROXY_CACHE_USE`]: the cache storage adapter to use. Can be `fs`, `s3`, `gcs`, `abs` (Azure Blob Storage), or `swift` (OpenStack Swift). When blank, the cache is disabled. Default: blank
25+
* [`IMGPROXY_CACHE_PATH_PREFIX`]: _(optional)_ a path prefix for the cache files. This can be useful to organize cache files in a specific directory structure. Default: blank
26+
* [`IMGPROXY_CACHE_BUCKET`]: _(optional)_ the bucket name for cloud storage adapters (S3, GCS, ABS, Swift). When using the filesystem adapter, this can be used as an additional path component. Default: blank
27+
* [`IMGPROXY_CACHE_KEY_HEADERS`]: _(optional)_ a list of HTTP request headers (comma-separated) to include in the cache key. This allows caching different versions of the same image based on request headers. Default: blank
28+
* [`IMGPROXY_CACHE_KEY_COOKIES`]: _(optional)_ a list of HTTP request cookies (comma-separated) to include in the cache key. This allows caching different versions of the same image based on cookies. Default: blank
29+
* [`IMGPROXY_CACHE_REPORT_ERRORS`]: When `true`, imgproxy will report cache errors instead of silently falling back to processing without cache. Default: `false`
30+
31+
### Storage configuration
32+
33+
The internal cache supports all the storage backends that imgproxy can read source images from: local filesystem, Amazon S3 and compatible services (Cloudflare R2, DigitalOcean Spaces, MinIO, etc.), Google Cloud Storage, Microsoft Azure Blob Storage, and OpenStack Swift.
34+
35+
Configure the storage backend using `IMGPROXY_CACHE_*` variables:
36+
37+
* For filesystem cache, see [Cache storage: Local filesystem](./internal/local_filesystem.mdx).
38+
* For S3 cache, see [Cache storage: Amazon S3](./internal/amazon_s3.mdx).
39+
* For GCS cache, see [Cache storage: Google Cloud Storage](./internal/google_cloud_storage.mdx).
40+
* For Azure Blob Storage cache, see [Cache storage: Azure Blob Storage](./internal/azure_blob_storage.mdx).
41+
* For Swift cache, see [Cache storage: OpenStack Object Storage ("Swift")](./internal/openstack_swift.mdx).
42+
43+
## Cache key
44+
45+
The cache key is generated based on:
46+
47+
* Source image URL
48+
* Processing options
49+
* Output format
50+
* Optional: Request headers specified in `IMGPROXY_CACHE_KEY_HEADERS`
51+
* Optional: Request cookies specified in `IMGPROXY_CACHE_KEY_COOKIES`
52+
53+
URL signature is **not** part of the cache key, allowing key rotation without invalidating the cache.
54+
55+
## Limitations
56+
57+
* **No manual cache invalidation**: Currently, imgproxy doesn't provide a built-in means to invalidate the cache. However, imgproxy includes the [cachebuster](../usage/processing.mdx#cache-buster) in the cache key, so you can use it to force cache invalidation when needed. Most storage offerings also support object expiration, so you can set a reasonable expiration time for cached images.
58+
* **No cache for info requests**: The internal cache is currently used only for image processing requests. Requests to the `/info` endpoint are not cached.
59+
60+
## How it works
61+
62+
When a request comes in:
63+
64+
1. imgproxy checks the URL signature (if enabled).
65+
2. imgproxy generates the cache key from the request parameters.
66+
3. imgproxy checks if a cached image exists in the configured storage.
67+
4. If the cached image exists and is valid, imgproxy serves it directly.
68+
5. If not, imgproxy processes the image and stores the result in the cache before serving it.

0 commit comments

Comments
 (0)