Skip to content

Deploying Flyimg

Introduction

Flyimg is a powerful, Dockerized image processing service that resizes, crops, and compresses images on the fly. Think of it as your own self-hosted Cloudinary or Imgix alternative. Built on top of ImageMagick, Flyimg delivers optimized images in modern formats like AVIF, WebP, JPEG XL (JXL), and MozJPEG, with an intelligent caching system that ensures lightning-fast response times for repeated requests.

Flyimg stands out for:

  • Format Flexibility: Automatic format negotiation serves AVIF to supported browsers, with WebP and optimized JPEG fallbacks
  • On-the-Fly Processing: No pre-processing needed—pass image URLs with transformation parameters and Flyimg handles the rest
  • Smart Caching: Processed images are cached for instant delivery on subsequent requests
  • Advanced Features: Face detection, smart cropping, automatic orientation correction, and more
  • Modern Compression: MozJPEG for superior JPEG quality, AVIF for cutting-edge compression, and WebP for wide compatibility
  • Simple API: URL-based image transformations with intuitive parameter syntax

Key capabilities include:

  • Dynamic Resizing: Width, height, and aspect ratio control with multiple fit modes
  • Smart Cropping: Intelligent cropping with face detection and focal point preservation
  • Quality Control: Adjustable compression levels per format for optimal file size vs quality balance
  • Format Conversion: Automatic output format selection or forced conversion
  • Image Filters: Blur, sharpen, grayscale, and more through URL parameters
  • Watermarking: Add text or image watermarks dynamically
  • Metadata Stripping: Remove EXIF data for privacy and smaller file sizes
  • JPEG XL Support: Latest generation image format with excellent compression

Deploying Flyimg on Klutch.sh gives you a production-ready image processing service with automatic scaling, persistent caching, and zero infrastructure management. This guide walks you through the complete setup process, from configuration to optimization.


Prerequisites

Before deploying Flyimg to Klutch.sh, ensure you have:


Understanding Flyimg Architecture

Flyimg consists of several key components:

  1. Web Server (Nginx): Handles incoming HTTP requests and serves cached images
  2. PHP-FPM: Processes image transformation requests
  3. ImageMagick: The underlying image processing engine
  4. Redis (Optional): Rate limiting and distributed caching
  5. File System Cache: Stores processed images for fast retrieval

When a request comes in, Flyimg:

  1. Checks if the transformed image exists in cache
  2. If cached, serves it immediately (extremely fast)
  3. If not cached, fetches the source image, applies transformations, caches the result, then serves it
  4. Subsequent requests for the same transformation are served from cache

Installation and Setup

Step 1: Create Your Project Directory

Create a new directory for your Flyimg deployment:

Terminal window
mkdir flyimg-klutch
cd flyimg-klutch
git init

Step 2: Create the Dockerfile

Flyimg provides an official Docker image, but we’ll create a custom Dockerfile that allows for configuration customization. Create a Dockerfile in your project root:

# Use the official Flyimg image as base
FROM flyimg/flyimg:latest
# Set environment variables for PHP and ImageMagick
ENV PHP_MEMORY_LIMIT=512M \
PHP_MAX_EXECUTION_TIME=120 \
PHP_POST_MAX_SIZE=50M \
PHP_UPLOAD_MAX_FILESIZE=50M
# Flyimg configuration will be mounted or set via environment variables
# The application runs on port 80 internally
EXPOSE 80
# The base image already has the correct entrypoint
# It starts both nginx and php-fpm via s6-overlay

Dockerfile Explanation:

  • Base Image: Uses the official Flyimg image with all dependencies pre-installed
  • PHP Configuration: Increases memory limits and upload sizes for handling large images
  • Port 80: Flyimg serves HTTP traffic on port 80 (standard web server port)
  • s6-overlay: The base image uses s6 to manage both Nginx and PHP-FPM processes

Step 3: Create Configuration File (Optional)

Create a parameters.yml file to customize Flyimg’s behavior:

# Flyimg Configuration
# See https://docs.flyimg.io/configuration for all options
# Application Settings
app_secret: 'your-secret-key-change-this-in-production'
# Default image quality settings
default_quality: 90
mozjpeg_quality: 85
webp_quality: 80
avif_quality: 70
# Output format preferences
default_output: 'auto' # auto, jpg, png, webp, avif, gif, jxl
output_formats:
- jpg
- webp
- avif
- png
- jxl
# Storage settings
storage_system: 'local' # local or s3
storage_path: '/var/www/html/web/uploads/'
# Cache settings
cache_system: 'file' # file or redis
file_cache_path: '/var/www/html/web/cache/'
cache_ttl: 86400 # 24 hours in seconds
# Redis settings (if using Redis for caching or rate limiting)
redis_enabled: false
redis_host: 'redis'
redis_port: 6379
redis_password: ''
redis_database: 0
# Rate limiting (requires Redis)
rate_limit_enabled: false
rate_limit_requests: 100
rate_limit_per_seconds: 60
# Security settings
allowed_domains:
- '*' # Restrict to specific domains in production
# Image processing limits
max_image_size: 10485760 # 10MB in bytes
max_output_dimension: 4000 # Maximum width or height
# Face detection (requires OpenCV)
face_detection_enabled: true
# Performance optimization
optimize_memory_usage: true
extract_metadata: false # Strip EXIF data for smaller files

Step 4: Create .dockerignore File

Create a .dockerignore file to exclude unnecessary files:

.git
.github
.gitignore
README.md
*.log
.env
.DS_Store
node_modules
web/uploads/*
web/cache/*

Step 5: Test Locally (Optional)

Test your Flyimg setup locally before deploying:

Terminal window
# Build the Docker image
docker build -t flyimg-klutch .
# Run with default configuration
docker run -d \
--name flyimg-test \
-p 8080:80 \
flyimg-klutch
# Or run with custom parameters.yml
docker run -d \
--name flyimg-test \
-p 8080:80 \
-v $(pwd)/parameters.yml:/var/www/html/config/parameters.yml \
flyimg-klutch

Test the service by visiting:

http://localhost:8080/upload/w_300,h_250,q_90/https://flyimg.io/demo-images/Citroen-DS.jpg

You should see a resized and compressed version of the demo image.

Cleanup after testing:

Terminal window
docker stop flyimg-test
docker rm flyimg-test

Step 6: Optional - Local Development with Docker Compose

For local development with Redis, create a docker-compose.yml file:

version: '3.8'
services:
flyimg:
build: .
ports:
- "8080:80"
volumes:
- ./parameters.yml:/var/www/html/config/parameters.yml
- flyimg-cache:/var/www/html/web/cache
- flyimg-uploads:/var/www/html/web/uploads
environment:
- REDIS_HOST=redis
- REDIS_PORT=6379
depends_on:
- redis
redis:
image: redis:7-alpine
command: redis-server --appendonly yes
volumes:
- redis-data:/data
volumes:
flyimg-cache:
flyimg-uploads:
redis-data:

Note: Docker Compose is only for local development. Klutch.sh doesn’t support Docker Compose deployments, but you can deploy Flyimg and Redis as separate applications.

Step 7: Push to GitHub

Commit your project files to GitHub:

Terminal window
git add Dockerfile .dockerignore parameters.yml
git commit -m "Add Flyimg configuration for Klutch.sh deployment"
git branch -M main
git remote add origin https://github.com/yourusername/flyimg-klutch.git
git push -u origin main

Deploying to Klutch.sh

Now that your Flyimg project is ready on GitHub, let’s deploy it to Klutch.sh.

Deployment Steps

    1. Log in to Klutch.sh

      Navigate to klutch.sh/app and sign in to your account.

    2. Create a New Project

      Go to Create Project and name it something like “Image Processing Service” or “Flyimg CDN”.

    3. Deploy Redis (Optional but Recommended)

      For production deployments with rate limiting, deploy Redis first:

      • Follow our Redis deployment guide
      • Configure it with TCP traffic on internal port 6379
      • Note the Redis connection details (e.g., redis-app.klutch.sh:8000)
      • Set a strong Redis password using REDIS_PASSWORD environment variable
    4. Create a New App for Flyimg

      Navigate to Create App to configure your Flyimg deployment.

    5. Select Your Repository

      • Choose GitHub as your Git source
      • Select the repository containing your Flyimg Dockerfile
      • Choose the branch you want to deploy (typically main)

      Klutch.sh will automatically detect the Dockerfile in your repository root and use it for the build.

    6. Configure Traffic Type

      • Traffic Type: Select HTTP (Flyimg is a web application)
      • Internal Port: Set to 80 (the port Nginx serves on inside the container)

      This configuration routes HTTP traffic from your Klutch.sh app URL to the Flyimg service.

    7. Set Environment Variables

      Configure the following environment variables in the Klutch.sh dashboard:

      Required Environment Variables:

      • APP_SECRET: A random secret key for security (generate with openssl rand -hex 32)

      Redis Configuration (if using Redis):

      • REDIS_ENABLED: Set to true
      • REDIS_HOST: Your Redis app hostname (e.g., redis-app.klutch.sh)
      • REDIS_PORT: 8000 (Klutch.sh’s external TCP port)
      • REDIS_PASSWORD: Your Redis password
      • REDIS_DATABASE: 0 (default database number)

      Rate Limiting (requires Redis):

      • RATE_LIMIT_ENABLED: Set to true
      • RATE_LIMIT_REQUESTS: 100 (number of requests allowed)
      • RATE_LIMIT_PER_SECONDS: 60 (time window in seconds)

      Image Processing Limits:

      • MAX_IMAGE_SIZE: 10485760 (10MB in bytes, adjust as needed)
      • MAX_OUTPUT_DIMENSION: 4000 (maximum width or height in pixels)

      PHP Configuration:

      • PHP_MEMORY_LIMIT: 512M (increase for processing large images)
      • PHP_MAX_EXECUTION_TIME: 120 (seconds, for slow image sources)

      Quality Settings:

      • DEFAULT_QUALITY: 90 (general quality setting)
      • MOZJPEG_QUALITY: 85 (JPEG compression quality)
      • WEBP_QUALITY: 80 (WebP compression quality)
      • AVIF_QUALITY: 70 (AVIF compression quality - lower values work well)

      Security Tip: Never commit sensitive values like APP_SECRET or REDIS_PASSWORD to your repository. Always set them as environment variables in Klutch.sh.

    8. Attach Persistent Volumes

      Flyimg benefits greatly from persistent storage for caching processed images. Configure these volumes:

      Volume 1 - Image Cache:

      • Mount Path: /var/www/html/web/cache
      • Size: 20GB or more (depending on your expected traffic and image diversity)

      Volume 2 - Uploaded Images (if storing uploads):

      • Mount Path: /var/www/html/web/uploads
      • Size: 10GB or more (if you plan to allow image uploads)

      Important: Persistent volumes ensure processed images remain cached across container restarts, significantly improving performance and reducing processing load.

    9. Configure Additional Settings

      • Region: Select the region closest to your users for optimal latency
      • Compute Resources:
        • Minimum: 1 CPU, 1GB RAM (for light usage)
        • Recommended: 2 CPU, 2GB RAM (for moderate traffic)
        • High Traffic: 4+ CPU, 4GB+ RAM (for heavy image processing workloads)
      • Instances: Start with 1 instance; scale horizontally as traffic grows
    10. Deploy Your Application

      Click “Create” to start the deployment. Klutch.sh will:

      • Automatically detect and build from your Dockerfile
      • Install all dependencies (ImageMagick, PHP, Nginx)
      • Attach persistent volumes to the specified mount paths
      • Start the Flyimg service
      • Assign a URL for accessing your image processing service
    11. Verify Deployment

      Once deployment completes, you’ll receive a URL like example-app.klutch.sh. Test your Flyimg instance:

      • Health Check: Visit https://example-app.klutch.sh/ - you should see “Hello from Flyimg!”

      • Image Processing: Try resizing an image:

        https://example-app.klutch.sh/upload/w_300,h_200,q_90/https://flyimg.io/demo-images/Citroen-DS.jpg

Getting Started with Flyimg

Now that Flyimg is deployed, let’s explore how to transform images using URL parameters.

Basic URL Structure

Flyimg uses a simple URL structure for image transformations:

https://example-app.klutch.sh/upload/{parameters}/{image-url}
  • Parameters: Comma-separated options (e.g., w_300,h_200,q_90)
  • Image URL: The source image URL (can be absolute or relative)

Common Image Transformations

Resize by Width:

<img src="https://example-app.klutch.sh/upload/w_500/https://example.com/image.jpg" />

Resize by Width and Height:

<img src="https://example-app.klutch.sh/upload/w_500,h_300/https://example.com/image.jpg" />

Resize with Quality Control:

<img src="https://example-app.klutch.sh/upload/w_500,h_300,q_85/https://example.com/image.jpg" />

Force Output Format:

<!-- Force WebP output -->
<img src="https://example-app.klutch.sh/upload/w_500,o_webp/https://example.com/image.jpg" />
<!-- Force AVIF output -->
<img src="https://example-app.klutch.sh/upload/w_500,o_avif/https://example.com/image.jpg" />

Automatic Format Selection:

<!-- Flyimg serves AVIF to supported browsers, WebP as fallback, then JPEG -->
<img src="https://example-app.klutch.sh/upload/w_500,o_auto/https://example.com/image.jpg" />

Available Parameters

ParameterDescriptionExample
w_Width in pixelsw_500
h_Height in pixelsh_300
q_Quality (1-100)q_90
o_Output formato_webp, o_avif, o_auto
c_Crop mode (1=crop, 0=no crop)c_1
r_Rotate degreesr_90
bg_Background color (hex)bg_FFFFFF
blur_Blur radiusblur_5
sharpen_Sharpen amountsharpen_80
f_Face detection cropf_1
strip_Strip metadatastrip_1
mozjpeg_Use MozJPEGmozjpeg_1

Advanced Use Cases

Responsive Images with srcset:

<img
src="https://example-app.klutch.sh/upload/w_800,o_auto/https://example.com/hero.jpg"
srcset="
https://example-app.klutch.sh/upload/w_400,o_auto/https://example.com/hero.jpg 400w,
https://example-app.klutch.sh/upload/w_800,o_auto/https://example.com/hero.jpg 800w,
https://example-app.klutch.sh/upload/w_1200,o_auto/https://example.com/hero.jpg 1200w,
https://example-app.klutch.sh/upload/w_1600,o_auto/https://example.com/hero.jpg 1600w
"
sizes="(max-width: 600px) 400px, (max-width: 1200px) 800px, 1200px"
alt="Hero image"
/>

Product Images with Smart Crop:

<!-- Square product thumbnail with face detection -->
<img src="https://example-app.klutch.sh/upload/w_300,h_300,c_1,f_1,o_auto/https://example.com/product.jpg" />

Optimized Hero Images:

<!-- Large hero with aggressive AVIF compression -->
<img src="https://example-app.klutch.sh/upload/w_1920,h_1080,q_75,o_avif/https://example.com/hero.jpg" />

Sample Code: Integrating Flyimg

Here are examples of how to integrate Flyimg into various applications:

Node.js/Express Example

const express = require('express');
const app = express();
const FLYIMG_BASE_URL = 'https://example-app.klutch.sh';
// Helper function to generate image URLs
function flyimgUrl(imageUrl, options = {}) {
const {
width = null,
height = null,
quality = 90,
format = 'auto',
crop = false,
faceDetection = false
} = options;
const params = [];
if (width) params.push(`w_${width}`);
if (height) params.push(`h_${height}`);
if (quality) params.push(`q_${quality}`);
if (format) params.push(`o_${format}`);
if (crop) params.push('c_1');
if (faceDetection) params.push('f_1');
const paramString = params.join(',');
return `${FLYIMG_BASE_URL}/upload/${paramString}/${imageUrl}`;
}
// API endpoint that returns optimized image URLs
app.get('/api/images/:id', (req, res) => {
const originalUrl = `https://storage.example.com/images/${req.params.id}.jpg`;
res.json({
thumbnail: flyimgUrl(originalUrl, { width: 200, height: 200, crop: true }),
medium: flyimgUrl(originalUrl, { width: 800 }),
large: flyimgUrl(originalUrl, { width: 1600 }),
hero: flyimgUrl(originalUrl, { width: 1920, height: 1080, quality: 85 })
});
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});

React Component Example

import React from 'react';
const FLYIMG_BASE_URL = 'https://example-app.klutch.sh';
function generateFlyimgUrl(imageUrl, options = {}) {
const {
width,
height,
quality = 90,
format = 'auto',
crop = false
} = options;
const params = [];
if (width) params.push(`w_${width}`);
if (height) params.push(`h_${height}`);
params.push(`q_${quality}`);
params.push(`o_${format}`);
if (crop) params.push('c_1');
return `${FLYIMG_BASE_URL}/upload/${params.join(',')}/${imageUrl}`;
}
function OptimizedImage({ src, alt, width, height, className }) {
const sizes = [400, 800, 1200, 1600];
const srcSet = sizes
.map(w => `${generateFlyimgUrl(src, { width: w })} ${w}w`)
.join(', ');
return (
<img
src={generateFlyimgUrl(src, { width: 800 })}
srcSet={srcSet}
sizes="(max-width: 600px) 400px, (max-width: 1200px) 800px, 1200px"
alt={alt}
width={width}
height={height}
className={className}
loading="lazy"
/>
);
}
// Usage
function ProductCard({ product }) {
return (
<div className="product-card">
<OptimizedImage
src={product.imageUrl}
alt={product.name}
width={300}
height={300}
/>
<h3>{product.name}</h3>
<p>${product.price}</p>
</div>
);
}
export default ProductCard;

Python/Flask Example

from flask import Flask, jsonify
from urllib.parse import quote
app = Flask(__name__)
FLYIMG_BASE_URL = 'https://example-app.klutch.sh'
def flyimg_url(image_url, width=None, height=None, quality=90,
output_format='auto', crop=False, face_detection=False):
"""Generate Flyimg transformation URL"""
params = []
if width:
params.append(f'w_{width}')
if height:
params.append(f'h_{height}')
if quality:
params.append(f'q_{quality}')
if output_format:
params.append(f'o_{output_format}')
if crop:
params.append('c_1')
if face_detection:
params.append('f_1')
param_string = ','.join(params)
encoded_url = quote(image_url, safe='')
return f'{FLYIMG_BASE_URL}/upload/{param_string}/{image_url}'
@app.route('/api/images/<image_id>')
def get_image_urls(image_id):
original_url = f'https://storage.example.com/images/{image_id}.jpg'
return jsonify({
'thumbnail': flyimg_url(original_url, width=200, height=200, crop=True),
'medium': flyimg_url(original_url, width=800),
'large': flyimg_url(original_url, width=1600),
'optimized': flyimg_url(original_url, width=1200, quality=85, output_format='avif')
})
@app.route('/api/responsive-image/<path:image_url>')
def get_responsive_image(image_url):
sizes = [400, 800, 1200, 1600]
srcset = [
{
'url': flyimg_url(image_url, width=size),
'width': size
}
for size in sizes
]
return jsonify({
'src': flyimg_url(image_url, width=800),
'srcset': srcset
})
if __name__ == '__main__':
app.run(debug=True)

PHP Example

<?php
class FlyimgHelper {
private $baseUrl;
public function __construct($baseUrl = 'https://example-app.klutch.sh') {
$this->baseUrl = rtrim($baseUrl, '/');
}
public function generateUrl($imageUrl, $options = []) {
$defaults = [
'width' => null,
'height' => null,
'quality' => 90,
'format' => 'auto',
'crop' => false,
'faceDetection' => false,
'blur' => null,
'sharpen' => null
];
$options = array_merge($defaults, $options);
$params = [];
if ($options['width']) {
$params[] = 'w_' . $options['width'];
}
if ($options['height']) {
$params[] = 'h_' . $options['height'];
}
if ($options['quality']) {
$params[] = 'q_' . $options['quality'];
}
if ($options['format']) {
$params[] = 'o_' . $options['format'];
}
if ($options['crop']) {
$params[] = 'c_1';
}
if ($options['faceDetection']) {
$params[] = 'f_1';
}
if ($options['blur']) {
$params[] = 'blur_' . $options['blur'];
}
if ($options['sharpen']) {
$params[] = 'sharpen_' . $options['sharpen'];
}
$paramString = implode(',', $params);
return "{$this->baseUrl}/upload/{$paramString}/{$imageUrl}";
}
public function responsiveImageSet($imageUrl, $sizes = [400, 800, 1200, 1600]) {
$srcset = [];
foreach ($sizes as $width) {
$url = $this->generateUrl($imageUrl, ['width' => $width]);
$srcset[] = "{$url} {$width}w";
}
return implode(', ', $srcset);
}
}
// Usage
$flyimg = new FlyimgHelper('https://example-app.klutch.sh');
// Generate product thumbnail
$thumbnail = $flyimg->generateUrl(
'https://example.com/product.jpg',
['width' => 300, 'height' => 300, 'crop' => true]
);
// Generate responsive image set
$srcset = $flyimg->responsiveImageSet('https://example.com/hero.jpg');
echo "<img src='{$thumbnail}' alt='Product' />";
echo "<img srcset='{$srcset}' sizes='100vw' alt='Hero' />";

Production Best Practices

Performance Optimization

1. Use Persistent Volumes

Ensure cache and upload volumes are properly configured. Cached images load instantly, while uncached images require processing time.

2. Leverage CDN

Place a CDN like Cloudflare in front of your Flyimg deployment:

  • Set long cache TTLs for transformed images (they don’t change)
  • Enable Cloudflare’s image optimization on top of Flyimg for double optimization
  • Reduce load on your Flyimg instance

3. Optimize Quality Settings

Different formats have different optimal quality settings:

  • AVIF: 65-75 quality provides excellent results
  • WebP: 75-85 quality balances size and quality
  • JPEG: 85-90 quality for photographic content
  • PNG: Use for images requiring transparency only

4. Use Format Auto-Negotiation

Always use o_auto to let Flyimg serve the best format based on browser support:

/upload/w_800,o_auto/image.jpg

5. Implement Lazy Loading

Use native lazy loading for images below the fold:

<img src="..." loading="lazy" />

Security Recommendations

1. Restrict Allowed Domains

Update your parameters.yml to only allow images from trusted domains:

allowed_domains:
- 'example.com'
- 'cdn.example.com'
- 'storage.example.com'

2. Enable Rate Limiting

Deploy Redis and enable rate limiting to prevent abuse:

rate_limit_enabled: true
rate_limit_requests: 100
rate_limit_per_seconds: 60

3. Set Resource Limits

Limit maximum image dimensions and file sizes:

max_image_size: 10485760 # 10MB
max_output_dimension: 4000 # 4000px max width/height

4. Use Environment Variables for Secrets

Never commit sensitive data. Use Klutch.sh environment variables for:

  • APP_SECRET
  • REDIS_PASSWORD
  • S3 credentials (if using S3 storage)

5. Monitor Access Logs

Regularly review Nginx access logs for suspicious patterns:

  • Excessive requests from single IPs
  • Requests for very large images
  • Unusual transformation parameters

Scaling Considerations

1. Horizontal Scaling

Increase the number of Flyimg instances in Klutch.sh as traffic grows. Flyimg is stateless (with file cache in persistent volumes), making horizontal scaling straightforward.

2. Vertical Scaling

For processing-intensive workloads:

  • Increase CPU for faster image processing
  • Increase RAM for handling larger images
  • Monitor CPU and memory usage in Klutch.sh dashboard

3. Cache Volume Size

Monitor cache volume usage:

  • Start with 20GB and adjust based on your image diversity
  • Larger caches reduce processing load but increase storage costs
  • Implement cache cleanup strategies for old or rarely-accessed images

4. Separate Storage from Processing

For very high traffic:

  • Use S3-compatible storage for source images
  • Let Flyimg cache processed images on local volumes
  • This separates storage from processing concerns

Monitoring and Maintenance

Key Metrics to Monitor:

  • Response Time: Average time to serve images (cached vs uncached)
  • Cache Hit Rate: Percentage of requests served from cache
  • Processing Time: Time to transform new images
  • Error Rate: Failed image processing attempts
  • Volume Usage: Cache and upload volume disk space
  • CPU/Memory Usage: Resource utilization patterns

Maintenance Tasks:

  • Cache Cleanup: Periodically remove old cached images to free space
  • Log Rotation: Ensure Nginx and PHP logs don’t fill disk
  • Dependency Updates: Update Flyimg to latest version for security patches
  • Performance Testing: Load test your deployment before major traffic events

Backup and Recovery

What to Back Up:

  1. Configuration Files: parameters.yml and custom settings
  2. Uploaded Images: If storing uploads (mount /var/www/html/web/uploads)
  3. Environment Variables: Document all Klutch.sh environment variables

Cache Volumes: No need to back up cache volumes—they can be rebuilt on demand.

Recovery Process:

  1. Redeploy Flyimg from GitHub repository
  2. Restore environment variables in Klutch.sh
  3. Restore uploaded images to volume (if applicable)
  4. Cache will rebuild automatically as requests come in

Troubleshooting

Images Not Loading

Symptom: Requests return 404 or timeout

Solutions:

  • Verify the source image URL is accessible from your Flyimg instance
  • Check allowed_domains configuration if domain restrictions are enabled
  • Ensure the internal port is set to 80 in Klutch.sh
  • Review deployment logs for errors during image fetching

Slow Image Processing

Symptom: First-time image requests are very slow

Solutions:

  • Increase PHP memory limit (PHP_MEMORY_LIMIT=1024M)
  • Increase execution time (PHP_MAX_EXECUTION_TIME=180)
  • Reduce source image size before transformation
  • Check if the source image server is slow to respond
  • Consider upgrading to more CPU cores in Klutch.sh

Cache Not Working

Symptom: Every request processes the image again

Solutions:

  • Verify persistent volume is attached at /var/www/html/web/cache
  • Check volume has sufficient disk space
  • Ensure file permissions allow write access (should be automatic)
  • Review cache configuration in parameters.yml

Out of Memory Errors

Symptom: Image processing fails with memory errors

Solutions:

  • Increase PHP_MEMORY_LIMIT environment variable
  • Reduce MAX_IMAGE_SIZE to reject very large source images
  • Upgrade to a plan with more RAM in Klutch.sh
  • Enable optimize_memory_usage in parameters.yml

Rate Limiting Not Working

Symptom: No rate limiting despite configuration

Solutions:

  • Ensure Redis is deployed and accessible
  • Verify REDIS_ENABLED=true in environment variables
  • Check Redis connection details (REDIS_HOST, REDIS_PORT, REDIS_PASSWORD)
  • Confirm RATE_LIMIT_ENABLED=true is set
  • Review Redis logs for connection errors

AVIF/WebP Not Working

Symptom: Modern formats not being served

Solutions:

  • Verify ImageMagick has support for these formats (Flyimg image includes them)
  • Check browser’s Accept header includes the format
  • Use o_avif or o_webp to force the format (for testing)
  • Review Flyimg logs for format conversion errors

Additional Resources


Conclusion

Deploying Flyimg on Klutch.sh gives you a powerful, self-hosted image processing service that automatically optimizes images for modern web performance. With support for cutting-edge formats like AVIF and JPEG XL, intelligent caching, and a simple URL-based API, Flyimg is an excellent alternative to expensive commercial image CDNs. By following this guide, you’ve set up a production-ready deployment with persistent caching, optional Redis integration for rate limiting, and all the configuration needed to handle real-world traffic at scale.