Ultra Image Server
A production grade on-the-fly image processing server setup using imgproxy and Nginx caching.
Table of contents
- Why it's good
- Getting started
- Examples
- Debugging
- Configurations
- Author: Mai Nhut Tan shin@shin.company
- Copyright: 2021-2024 SHIN Company https://code.shin.company/docker-imgproxy#readme
Disclaimer
This project provides a solid foundation for building a custom image processing server. While it's designed for general use, you might need to tweak it further to perfectly match your specific needs.
I poured my heart into this project, hoping it serves as a valuable learning resource for anyone interested in exploring image processing configurations. If it doesn't fully address your current requirements, don't hesitate to keep searching for the perfect solution!
Support my activities
If you find this project useful, consider donating via PayPal or open an issue on Github. Your support helps keep this project maintained and improved for the community.
Why it's good
Experience the ultimate in efficient image delivery with our cutting-edge solution:
- Lightning-fast on-the-fly thumbnail generation powered by
imgproxy. - High availability and unparalleled performance thanks to Nginx content caching.
- Bid farewell to URL signature management hassles while maintaining top-notch security.
- Effortless serving of local files or remote server content.
- SEO-friendly URL crafting without exposing complex
imgproxyoptions. - Unmatched flexibility:
- Customize image presets for any request.
- Dynamic origin server selection.
- Graceful fallback image handling for unavailable sources.
- Hassle-free SSL configuration with built-in HTTP/2 support for blazing-fast load times.
- Intelligent image format conversion to WebP (or AVIF) for browser compatibility.
- Seamless visual experience across devices.
Unleash the power of our cutting-edge solution and take your project to new heights with efficient image delivery.
Getting started
Pull this project from Github
Please run the below command to download the project to your local machine:
Or:
rm -f docker-imgproxy.zip
mv docker-imgproxy-main docker-imgproxy
Prepare your files
Change your working directory to downloaded directory in the above step.
Then put your image files to be served to the folder www/.
There are some sample files available (a sample image cacti.jpg, a watermark, and some fallback images).
Start the server
docker-compose up -d --build --remove-orphans --force-recreate
That's all!
Note: This setup requires Docker Compose installed. If you have already installed Docker Desktop or Docker Toolbox, then no need of installation for Docker Compose.
If you like this setup, please support my works .
Examples
Local images
Assuming that we want to generate various thumbnail images from the original file named cacti.jpg.
I already created some preset names, such as _thumb or _w200, and I add preset names to the original URL to get thumbnails from it.
Image with no preset (it is resized to max-width=1600 as default).
http://localhost/cacti.jpg
The image with preset
_w200applied (200is a dynamic number).
http://localhost/_w200/cacti.jpg
The image with preset
_blurryapplied.
http://localhost/_blurry/cacti.jpg
The image with preset
_smallapplied.
http://localhost/_small/cacti.jpg
The image with preset
_mediumapplied.
http://localhost/_medium/cacti.jpg
The image with preset
_thumbapplied.
http://localhost/_thumb/cacti.jpg
The image with preset
_squareapplied.
http://localhost/_square/cacti.jpg
The image with preset
_maskedapplied.
http://localhost/_masked/cacti.jpg
Or just to download the image (with filters applied).
http://localhost/_download/cacti.jpg
See my configurations to know how it works.
Remote images
With the same presets as above examples, we are going to serve an image by NASA using the alias @nasa, that will be added in these URLs.
Note: the image source is from NASA, it may be unavailable in the future.
Image with no preset (it is resized to max-width=1600 as default).
http://localhost/@nasa/40368_PIA22228.jpg
The image with preset
_w200applied (200is a dynamic number).
http://localhost/@nasa/_w200/40368_PIA22228.jpg
The image with preset
_blurryapplied.
http://localhost/@nasa/_blurry/40368_PIA22228.jpg
The image with preset
_smallapplied.
http://localhost/@nasa/_small/40368_PIA22228.jpg
The image with preset
_mediumapplied.
http://localhost/@nasa/_medium/40368_PIA22228.jpg
The image with preset
_thumbapplied.
http://localhost/@nasa/_thumb/40368_PIA22228.jpg
The image with preset
_squareapplied.
http://localhost/@nasa/_square/40368_PIA22228.jpg
The image with preset
_maskedapplied.
http://localhost/@nasa/_masked/40368_PIA22228.jpg
Or just to download the image (with filters applied).
http://localhost/@nasa/_download/40368_PIA22228.jpg
Supported origin servers
This setup serve images from other public origin servers, as well as from Amazon S3 buckets, Google Cloud and Azure Blob.
You can learn how to serve files from private storage in the configurations section.
Base64 encoded URLs
The source URL can be encrypted with URL-safe Base64, prepended by the /@base64/ prefix. So you can access the remote images like the below:
Note: the image source is from NASA, it may be unavailable in the future.
Image with no preset (it is resized to max-width=1600 as default).
http://localhost/@base64/aHR0cHM6Ly9tYXJzLm5hc2EuZ292L3N5c3RlbS9kb3dubG9hZGFibGVfaXRlbXMvNDAzNjglNUZQSUEyMjIyOC5qcGc=
The image with preset
_w200applied (200is a dynamic number).
http://localhost/@base64/_w200/aHR0cHM6Ly9tYXJzLm5hc2EuZ292L3N5c3RlbS9kb3dubG9hZGFibGVfaXRlbXMvNDAzNjglNUZQSUEyMjIyOC5qcGc=
The image with preset
_blurryapplied.
http://localhost/@base64/_blurry/aHR0cHM6Ly9tYXJzLm5hc2EuZ292L3N5c3RlbS9kb3dubG9hZGFibGVfaXRlbXMvNDAzNjglNUZQSUEyMjIyOC5qcGc=
The image with preset
_smallapplied.
http://localhost/@base64/_small/aHR0cHM6Ly9tYXJzLm5hc2EuZ292L3N5c3RlbS9kb3dubG9hZGFibGVfaXRlbXMvNDAzNjglNUZQSUEyMjIyOC5qcGc=
The image with preset
_mediumapplied.
http://localhost/@base64/_medium/aHR0cHM6Ly9tYXJzLm5hc2EuZ292L3N5c3RlbS9kb3dubG9hZGFibGVfaXRlbXMvNDAzNjglNUZQSUEyMjIyOC5qcGc=
The image with preset
_thumbapplied.
http://localhost/@base64/_thumb/aHR0cHM6Ly9tYXJzLm5hc2EuZ292L3N5c3RlbS9kb3dubG9hZGFibGVfaXRlbXMvNDAzNjglNUZQSUEyMjIyOC5qcGc=
The image with preset
_squareapplied.
http://localhost/@base64/_square/aHR0cHM6Ly9tYXJzLm5hc2EuZ292L3N5c3RlbS9kb3dubG9hZGFibGVfaXRlbXMvNDAzNjglNUZQSUEyMjIyOC5qcGc=
The image with preset
_maskedapplied.
http://localhost/@base64/_masked/aHR0cHM6Ly9tYXJzLm5hc2EuZ292L3N5c3RlbS9kb3dubG9hZGFibGVfaXRlbXMvNDAzNjglNUZQSUEyMjIyOC5qcGc=
Or just to download the image (with filters applied).
http://localhost/@base64/_download/aHR0cHM6Ly9tYXJzLm5hc2EuZ292L3N5c3RlbS9kb3dubG9hZGFibGVfaXRlbXMvNDAzNjglNUZQSUEyMjIyOC5qcGc=
Customize resizing via query string
Image width and height
You can also parse arguments from the request's query string, such as ?width=300 for the image's width or ?height=200 for the image's height, or even both of demensions, to flexibly change some parameters for resizing.
In this setup example, I used the width and height arguments to override the existing presets.
Image with specific demensions (1200x960).
http://localhost/@nasa/40368_PIA22228.jpg?width=1200&height=960
Image with
widthis set to 500px.
http://localhost/@nasa/40368_PIA22228.jpg?width=500
Image with
heightis set to 500px.
http://localhost/@nasa/40368_PIA22228.jpg?height=500
The image with preset
_mediumapplied, but the query string will override the dimensions of the output image to 50x200px.
http://localhost/@nasa/_medium/40368_PIA22228.jpg?width=50&height=200
Image quality
In addition, you can override the default quality defined by IMGPROXY_FORMAT_QUALITY in the docker-compose.yml file by passing a quality value (ranging from 1 to 100) in the query string of the request. For example, adding ?quality=100 will set the output image quality to 100% (the best quality).
Image with
qualityis set.
You can check the download size of the image using browser's Developer Tools.
http://localhost/cacti.jpg?quality=1http://localhost/cacti.jpg?quality=10
http://localhost/cacti.jpg?quality=50
Image quality with a human readable
qualityvalue.
You can check the download size of the image using browser's Developer Tools.
http://localhost/cacti.jpg?quality=lowhttp://localhost/cacti.jpg?quality=clear
You can combine the
qualityoption with any above preset.
http://localhost/_medium/cacti.jpg?quality=highhttp://localhost/_blurry/cacti.jpg?width=500&height=500&quality=1
See my configurations to know how it works.
Debugging
Debugging rewrite rule:
When you make a request with the query component debug=1, you will see an X-Debug header contains its internal imgproxy's options.
Example 1 (local file with preset _small):
curl -Isk 'http://localhost/_small/cacti.jpg?debug=1'
HTTP/1.1 200 OK
Server: nginx
Content-Type: image/webp
X-Debug: /unsafe/size:320:320:0:0/sharpen:0.3/preset:logo/dpr:1/plain/local:///cacti.jpg