Deploying imgproxy
Introduction
imgproxy is a fast, secure, and resource-efficient image processing server designed for on-the-fly image manipulation. Written in Go and leveraging the high-performance libvips library, imgproxy can resize, crop, rotate, and apply various transformations to images without pre-processing or caching on disk.
Unlike traditional image processing solutions that require generating multiple sizes upfront, imgproxy processes images in real-time based on URL parameters. This approach saves storage space, simplifies workflows, and allows dynamic adjustments without regenerating assets.
Key highlights of imgproxy:
- Lightning Fast: Built on libvips, one of the fastest image processing libraries available
- Memory Efficient: Processes images in streaming mode without loading entire files into memory
- Secure by Design: Optional URL signing prevents unauthorized image processing
- Format Conversion: Automatically serves WebP, AVIF, or other modern formats based on browser support
- Smart Cropping: Intelligent cropping that focuses on faces or points of interest
- Watermarking: Add watermarks to images dynamically
- Quality Optimization: Automatic quality adjustment for optimal file size
- CDN Ready: Works seamlessly with CDNs for edge caching
- S3/GCS Support: Fetch source images directly from cloud storage
- Pro Features: Optional paid tier adds PDF processing, video thumbnails, and more
- 100% Open Source: Core features available under MIT license
This guide walks through deploying imgproxy on Klutch.sh using Docker, configuring secure URL signing, and integrating with your web applications.
Why Deploy imgproxy on Klutch.sh
Deploying imgproxy on Klutch.sh provides several advantages for image processing:
Simplified Deployment: Klutch.sh automatically detects your Dockerfile and builds imgproxy without complex orchestration.
Scalable Performance: Allocate CPU and memory based on your expected image processing load. Scale up during traffic spikes.
HTTPS by Default: Klutch.sh provides automatic SSL certificates, ensuring secure image delivery.
GitHub Integration: Updates to your configuration trigger automatic redeployments.
Environment Variable Management: Securely store signing keys and cloud storage credentials.
CDN Integration: Combine with a CDN for global edge caching of processed images.
Custom Domains: Serve images from your own domain for consistent branding.
Always-On Availability: Your image processing service remains available 24/7.
Prerequisites
Before deploying imgproxy on Klutch.sh, ensure you have:
- A Klutch.sh account
- A GitHub account with a repository for your configuration
- Source images hosted on a web server, S3, GCS, or other accessible storage
- Basic familiarity with Docker and URL-based APIs
- (Optional) A CDN for caching processed images
Understanding imgproxy Architecture
imgproxy follows a simple request-response model:
URL Parsing: Each request URL contains processing instructions and the source image location.
Source Fetching: imgproxy retrieves the original image from the specified source (URL, S3, GCS, etc.).
Processing Pipeline: The image passes through a series of transformations (resize, crop, format conversion, etc.).
Response Delivery: The processed image is streamed back to the client without disk caching.
URL Signature Verification: Optional cryptographic signatures prevent unauthorized processing requests.
URL Structure
imgproxy URLs follow this pattern:
/{signature}/{processing_options}/{encoded_source_url}Or with path-style options:
/{signature}/rs:fit:300:200/plain/https://example.com/image.jpgPreparing Your Repository
Create a GitHub repository for your imgproxy deployment.
Repository Structure
imgproxy-deploy/├── Dockerfile├── README.md└── .dockerignoreCreating the Dockerfile
Create a Dockerfile in the root of your repository:
FROM darthsim/imgproxy:latest
# Security: Require URL signaturesENV IMGPROXY_KEY=${IMGPROXY_KEY}ENV IMGPROXY_SALT=${IMGPROXY_SALT}
# Performance settingsENV IMGPROXY_CONCURRENCY=${IMGPROXY_CONCURRENCY:-10}ENV IMGPROXY_MAX_SRC_RESOLUTION=${IMGPROXY_MAX_SRC_RESOLUTION:-50}ENV IMGPROXY_MAX_ANIMATION_FRAMES=${IMGPROXY_MAX_ANIMATION_FRAMES:-100}
# Quality settingsENV IMGPROXY_QUALITY=${IMGPROXY_QUALITY:-80}ENV IMGPROXY_AVIF_SPEED=${IMGPROXY_AVIF_SPEED:-8}
# Format detectionENV IMGPROXY_ENABLE_WEBP_DETECTION=${IMGPROXY_ENABLE_WEBP_DETECTION:-true}ENV IMGPROXY_ENABLE_AVIF_DETECTION=${IMGPROXY_ENABLE_AVIF_DETECTION:-true}
# Source restrictions (optional)ENV IMGPROXY_ALLOWED_SOURCES=${IMGPROXY_ALLOWED_SOURCES}
# Expose the server portEXPOSE 8080
# Health checkHEALTHCHECK --interval=30s --timeout=10s --start-period=10s --retries=3 \ CMD wget --no-verbose --tries=1 --spider http://localhost:8080/health || exit 1Advanced Dockerfile with S3 Support
For S3-based image sources:
FROM darthsim/imgproxy:latest
# SecurityENV IMGPROXY_KEY=${IMGPROXY_KEY}ENV IMGPROXY_SALT=${IMGPROXY_SALT}
# AWS S3 configurationENV IMGPROXY_USE_S3=${IMGPROXY_USE_S3:-true}ENV AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}ENV AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}ENV AWS_REGION=${AWS_REGION:-us-east-1}
# PerformanceENV IMGPROXY_CONCURRENCY=20ENV IMGPROXY_MAX_SRC_RESOLUTION=100ENV IMGPROXY_WORKERS=4
# Quality and formatENV IMGPROXY_QUALITY=80ENV IMGPROXY_ENABLE_WEBP_DETECTION=trueENV IMGPROXY_ENABLE_AVIF_DETECTION=trueENV IMGPROXY_PREFERRED_FORMATS=avif,webp,png,jpeg
# Caching headersENV IMGPROXY_CACHE_CONTROL_PASSTHROUGH=trueENV IMGPROXY_SET_CANONICAL_HEADER=true
# Expose portEXPOSE 8080
# Health checkHEALTHCHECK --interval=30s --timeout=10s --start-period=10s --retries=3 \ CMD wget --no-verbose --tries=1 --spider http://localhost:8080/health || exit 1Environment Variables Reference
| Variable | Required | Default | Description |
|---|---|---|---|
IMGPROXY_KEY | Recommended | - | Hex-encoded key for URL signing |
IMGPROXY_SALT | Recommended | - | Hex-encoded salt for URL signing |
IMGPROXY_CONCURRENCY | No | 10 | Maximum concurrent image processing operations |
IMGPROXY_MAX_SRC_RESOLUTION | No | 16.8 | Maximum source image resolution in megapixels |
IMGPROXY_QUALITY | No | 80 | Default JPEG/WebP quality (1-100) |
IMGPROXY_ALLOWED_SOURCES | No | - | Comma-separated list of allowed source domains |
IMGPROXY_USE_S3 | No | false | Enable S3 source support |
IMGPROXY_USE_GCS | No | false | Enable Google Cloud Storage support |
Deploying imgproxy on Klutch.sh
- Select HTTP as the traffic type
- Set the internal port to 8080
Generate Signing Keys
Generate secure hex-encoded keys for URL signing:
# Generate key (32 bytes = 64 hex characters)echo $(xxd -g 2 -l 32 -p /dev/random | tr -d '\n')
# Generate salt (32 bytes = 64 hex characters)echo $(xxd -g 2 -l 32 -p /dev/random | tr -d '\n')Store these securely for environment variable configuration.
Push Your Repository to GitHub
Initialize and push your repository:
git initgit add Dockerfile .dockerignore README.mdgit commit -m "Initial imgproxy deployment configuration"git remote add origin https://github.com/yourusername/imgproxy-deploy.gitgit push -u origin mainCreate a New Project on Klutch.sh
Navigate to the Klutch.sh dashboard and create a new project named “imgproxy” or “image-processor”.
Create a New App
Within your project, create a new app. Connect your GitHub account and select the repository containing your Dockerfile.
Configure HTTP Traffic
In the deployment settings:
Set Environment Variables
Add the following environment variables:
| Variable | Value |
|---|---|
IMGPROXY_KEY | Your generated hex key |
IMGPROXY_SALT | Your generated hex salt |
IMGPROXY_CONCURRENCY | 10 (adjust based on resources) |
IMGPROXY_QUALITY | 80 |
IMGPROXY_ALLOWED_SOURCES | Your source domains (optional) |
For S3 sources, also add:
| Variable | Value |
|---|---|
IMGPROXY_USE_S3 | true |
AWS_ACCESS_KEY_ID | Your AWS access key |
AWS_SECRET_ACCESS_KEY | Your AWS secret key |
AWS_REGION | Your S3 region |
Deploy Your Application
Click Deploy to start the build process.
Test Your Deployment
Once deployed, test image processing:
https://your-app-name.klutch.sh/insecure/rs:fit:300:200/plain/https://example.com/sample.jpgNote: Use signed URLs in production.
URL Signing
For production use, always sign your URLs to prevent unauthorized image processing:
Generating Signed URLs
Use the imgproxy URL signing algorithm in your application:
const crypto = require('crypto');
function signImgproxyUrl(path, key, salt) { const hmac = crypto.createHmac('sha256', Buffer.from(key, 'hex')); hmac.update(Buffer.from(salt, 'hex')); hmac.update(path);
const signature = hmac.digest('base64url').substring(0, 32); return `/${signature}${path}`;}
// Usageconst path = '/rs:fit:300:200/plain/https://example.com/image.jpg';const signedUrl = signImgproxyUrl(path, IMGPROXY_KEY, IMGPROXY_SALT);Available Libraries
Official and community libraries for URL generation:
- Node.js:
@imgproxy/imgproxy-node - Python:
imgproxy - Ruby:
imgproxy - Go:
imgproxy/imgproxy-go - PHP:
imgproxy/imgproxy-php
Processing Options
Common Transformations
| Option | Example | Description |
|---|---|---|
rs (resize) | rs:fit:300:200 | Resize to fit within 300x200 |
c (crop) | c:300:200:sm | Smart crop to 300x200 |
g (gravity) | g:ce | Center gravity for cropping |
q (quality) | q:90 | Set quality to 90% |
f (format) | f:webp | Force WebP output |
blur | blur:10 | Apply Gaussian blur |
sharp | sharp:1 | Apply sharpening |
wm | wm:1:ce:0:0:0.5 | Add watermark |
Example URLs
# Resize to 300px width, maintain aspect ratio/rs:fit:300:0/plain/https://example.com/image.jpg
# Square crop with smart focus/c:300:300:sm/plain/https://example.com/image.jpg
# Convert to WebP at 85% quality/q:85/f:webp/plain/https://example.com/image.jpg
# Resize and add watermark/rs:fit:800:600/wm:1:se:10:10:0.3/plain/https://example.com/image.jpgPerformance Optimization
Resource Allocation
- CPU: Image processing is CPU-intensive; allocate accordingly
- Memory: libvips is memory-efficient but allocate 512MB+ for large images
- Concurrency: Match IMGPROXY_CONCURRENCY to available CPU cores
CDN Integration
Place a CDN in front of imgproxy:
- Configure your CDN to cache responses
- Set appropriate cache headers in imgproxy
- Use long cache TTLs for immutable images
Source Optimization
- Use S3/GCS for faster source fetching
- Restrict allowed sources to prevent abuse
- Set reasonable max resolution limits
Security Best Practices
- Always Sign URLs: Enable URL signing in production
- Restrict Sources: Limit IMGPROXY_ALLOWED_SOURCES to your domains
- Set Limits: Configure max resolution and file size limits
- Rate Limiting: Use a CDN or reverse proxy for rate limiting
- Regular Updates: Keep the imgproxy image updated
Troubleshooting
Image Not Processing
- Verify the source URL is accessible
- Check that the source domain is allowed
- Review container logs for error messages
Slow Performance
- Increase IMGPROXY_CONCURRENCY
- Allocate more CPU resources
- Use a CDN to cache processed images
Signature Errors
- Verify key and salt are correctly hex-encoded
- Ensure signing algorithm matches
- Check for URL encoding issues
Additional Resources
- imgproxy Official Website
- imgproxy Documentation
- imgproxy GitHub Repository
- Configuration Reference
- Klutch.sh Persistent Volumes
- Klutch.sh Deployments
Conclusion
Deploying imgproxy on Klutch.sh gives you a powerful, on-demand image processing service with automatic HTTPS and scalable resources. With URL signing for security and CDN integration for performance, imgproxy handles your image optimization needs without pre-processing or storing multiple versions.
Whether you’re building a content-heavy website, e-commerce platform, or media application, imgproxy on Klutch.sh provides the flexibility and performance needed for modern image delivery.