• Home
  • Guides
    • All
    • Linux
    • Programming
    • Tools
    • WordPress
    Server-Side Image Conversion with Apache

    Server-Side Image Conversion with Apache

    Imposter Syndrome as a Self-Taught Developer

    Imposter Syndrome as a Self-Taught Developer

    Fastest Way to Extract a Massive .tar.gz File on Linux

    Fastest Way to Extract a Massive .tar.gz File on Linux

    Monitor SSL Expiration with Python

    Monitor SSL Expiration with Python

    Building a Simple WordPress Post List Tool with PHP

    Building a Simple WordPress Post List Tool with PHP

    Monitoring Web Page Changes with Python

    Monitoring Web Page Changes with Python

    My SSH Setup: How I Manage Multiple Servers

    My SSH Setup: How I Manage Multiple Servers

    Building a Network Tracker Auditor for Privacy with Python

    Building a Network Tracker Auditor for Privacy with Python

    Streaming Audio Files Securely with PHP

    Streaming Audio Files Securely with PHP

  • Blog
    • All
    • Artificial Intelligence
    • Privacy
    • Reviews
    • Security
    • Tutorials
    Why Stable Websites Outperform Flashy Redesigns

    Why Stable Websites Outperform Flashy Redesigns

    AdGuard Ad Blocker Review

    AdGuard Ad Blocker Review

    Surfshark VPN Review

    Surfshark VPN Review

    Nmap Unleash the Power of Cybersecurity Scanning

    Nmap: Unleash the Power of Cybersecurity Scanning

    Floorp Browser Review

    Floorp Browser Review

    Understanding Man-in-the-Middle Attacks

    Understanding Man-in-the-Middle Attacks

    Privacy-Focused Analytics

    Privacy-Focused Analytics: Balancing Insights and Integrity

    Safeguarding Your Facebook Account

    Safeguarding Your Facebook Account: Understanding the Differences Between Hacking and Cloning

    38 essential points to harden WordPress

    38 Essential Points to Harden WordPress

  • Apps
    • Bible App
    • Bible Verse Screensaver
    • Blue AI Chatbot
    • Early Spring Predictor
    • FIGlet Generator
    • Password Generator
    • StegX
    • The Matrix
    • WeatherX
    • Website Risk Level Tool
  • About
    • About JMooreWV
    • Live Cyber Attack Stats
  • Contact
    • General Contact
    • Website Administration & Cybersecurity
No Result
View All Result
  • Home
  • Guides
    • All
    • Linux
    • Programming
    • Tools
    • WordPress
    Server-Side Image Conversion with Apache

    Server-Side Image Conversion with Apache

    Imposter Syndrome as a Self-Taught Developer

    Imposter Syndrome as a Self-Taught Developer

    Fastest Way to Extract a Massive .tar.gz File on Linux

    Fastest Way to Extract a Massive .tar.gz File on Linux

    Monitor SSL Expiration with Python

    Monitor SSL Expiration with Python

    Building a Simple WordPress Post List Tool with PHP

    Building a Simple WordPress Post List Tool with PHP

    Monitoring Web Page Changes with Python

    Monitoring Web Page Changes with Python

    My SSH Setup: How I Manage Multiple Servers

    My SSH Setup: How I Manage Multiple Servers

    Building a Network Tracker Auditor for Privacy with Python

    Building a Network Tracker Auditor for Privacy with Python

    Streaming Audio Files Securely with PHP

    Streaming Audio Files Securely with PHP

  • Blog
    • All
    • Artificial Intelligence
    • Privacy
    • Reviews
    • Security
    • Tutorials
    Why Stable Websites Outperform Flashy Redesigns

    Why Stable Websites Outperform Flashy Redesigns

    AdGuard Ad Blocker Review

    AdGuard Ad Blocker Review

    Surfshark VPN Review

    Surfshark VPN Review

    Nmap Unleash the Power of Cybersecurity Scanning

    Nmap: Unleash the Power of Cybersecurity Scanning

    Floorp Browser Review

    Floorp Browser Review

    Understanding Man-in-the-Middle Attacks

    Understanding Man-in-the-Middle Attacks

    Privacy-Focused Analytics

    Privacy-Focused Analytics: Balancing Insights and Integrity

    Safeguarding Your Facebook Account

    Safeguarding Your Facebook Account: Understanding the Differences Between Hacking and Cloning

    38 essential points to harden WordPress

    38 Essential Points to Harden WordPress

  • Apps
    • Bible App
    • Bible Verse Screensaver
    • Blue AI Chatbot
    • Early Spring Predictor
    • FIGlet Generator
    • Password Generator
    • StegX
    • The Matrix
    • WeatherX
    • Website Risk Level Tool
  • About
    • About JMooreWV
    • Live Cyber Attack Stats
  • Contact
    • General Contact
    • Website Administration & Cybersecurity
No Result
View All Result
Home Guides Programming

Server-Side Image Conversion with Apache

Jonathan Moore by Jonathan Moore
12 hours ago
Reading Time: 6 mins read
A A
Server-Side Image Conversion with Apache
FacebookTwitter

I stopped relying on third party image services a while ago. They work, but they add cost, latency, and another dependency I do not control. Running everything directly on the server gives me full control over how images are processed and served, and it removes a lot of unnecessary moving parts.

This setup uses Apache, a simple shell script, and a couple of command line tools to convert images into modern formats like AVIF and WebP. It runs quietly in the background using cron, keeps your image library optimized, and only keeps files that are actually smaller than the originals. The result is faster page loads and less bandwidth usage without touching your existing workflow.

What Next Gen Images Actually Are

When I say next gen images, I am talking about newer image formats like WebP and AVIF. These formats are designed to replace older ones like JPEG and PNG by offering better compression while maintaining quality.

WebP has been around for a while and is supported by most browsers. AVIF is newer and can compress images even further, often producing files that are 30 to 50 percent smaller than JPEG. That reduction matters when you have hundreds or thousands of images being loaded across your site.

The benefit is simple. Smaller images load faster, reduce bandwidth, and improve page performance. Search engines also take this into account, so it can help with SEO without doing anything fancy.

Required Tools for Image Conversion

Before anything works, the server needs the right tools installed. The script depends on two binaries:

  • avifenc for AVIF conversion
  • cwebp for WebP conversion

AlmaLinux / CentOS / RHEL

sudo dnf install libavif-tools libwebp-tools -y

Ubuntu / Debian

sudo apt update
sudo apt install libavif-bin webp -y

Verify Installation

which avifenc
which cwebp

If both commands return a path, you are good to go. If not, the script will fail early and tell you what is missing.

Directory Structure Setup

I keep things simple and predictable. The original images stay where they are, and converted images go into separate directories.

/home/user/public_html/wp-content/uploads
/home/user/public_html/wp-content/avif-uploads
/home/user/public_html/wp-content/webp-uploads

This separation keeps things clean and avoids overwriting originals. It also makes it easy to remove generated files if needed without touching your source images.

The Conversion Script

This is the core of the system. It scans your upload directory, converts images, and only keeps them if they are smaller than the original. Below is the script (convert-to-avif-webp.sh) adapted for your environment.

#!/bin/bash

SRC_DIR="/home/user/public_html/wp-content/uploads"
AVIF_DIR="/home/user/public_html/wp-content/avif-uploads"
WEBP_DIR="/home/user/public_html/wp-content/webp-uploads"

AVIFENC="$(command -v avifenc)"
CWEBP="$(command -v cwebp)"

if [[ -z "$AVIFENC" ]]; then
    echo "ERROR: avifenc not found"
    exit 1
fi

if [[ -z "$CWEBP" ]]; then
    echo "ERROR: cwebp not found"
    exit 1
fi

find "$SRC_DIR" -type f \( -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.png' \) | while read -r src_img; do
    rel_path="${src_img#$SRC_DIR/}"
    rel_base="${rel_path%.*}"

    avif_dest="$AVIF_DIR/${rel_base}.avif"
    if [[ ! -f "$avif_dest" ]]; then
        mkdir -p "$(dirname "$avif_dest")"
        echo "Converting to AVIF: $rel_path"

        if ! "$AVIFENC" "$src_img" "$avif_dest"; then
            echo "  AVIF conversion failed: $rel_path"
            rm -f "$avif_dest"
        elif [[ -f "$avif_dest" ]]; then
            orig_size=$(stat -c %s "$src_img")
            avif_size=$(stat -c %s "$avif_dest")
            if (( avif_size >= orig_size )); then
                echo "  AVIF larger than original. Removing: $rel_path"
                rm -f "$avif_dest"
            fi
        fi
    fi

    webp_dest="$WEBP_DIR/${rel_base}.webp"
    if [[ ! -f "$webp_dest" ]]; then
        mkdir -p "$(dirname "$webp_dest")"
        echo "Converting to WebP: $rel_path"

        if ! "$CWEBP" -quiet "$src_img" -o "$webp_dest"; then
            echo "  WebP conversion failed: $rel_path"
            rm -f "$webp_dest"
        elif [[ -f "$webp_dest" ]]; then
            orig_size=$(stat -c %s "$src_img")
            webp_size=$(stat -c %s "$webp_dest")
            if (( webp_size >= orig_size )); then
                echo "  WebP larger than original. Removing: $rel_path"
                rm -f "$webp_dest"
            fi
        fi
    fi
done

Breaking Down What the Script Does

The script looks simple, but there is a lot going on behind the scenes. Understanding it makes troubleshooting much easier later.

The first section defines your directories and checks for required tools. If avifenc or cwebp is missing, it exits immediately instead of failing silently. That alone saves a lot of time when something is not installed correctly.

The find command walks through your uploads directory and targets only .jpg, .jpeg, and .png files. Each file is processed one at a time, which keeps memory usage low even on large libraries. It also builds a relative path so the converted images mirror your original folder structure.

For each image, the script checks if a converted version already exists. If it does, it skips it, which prevents unnecessary work. If not, it converts the image and then compares file sizes.

That size check is important. If the converted image is larger than the original, it gets deleted immediately. This ensures you never accidentally make performance worse by converting images that do not benefit from compression.

Making the Script Executable

After placing the script in your server, make it executable.

chmod +x /home/user/path/to/scripts/convert_images/convert-to-avif-webp.sh

Without this step, cron will not be able to run it.

Automating with Cron

I run this script every 15 minutes. That keeps new uploads converted quickly without putting too much load on the server.

*/15 * * * * /home/user/path/to/scripts/convert_images/convert-to-avif-webp.sh

This setup works well because it is lightweight. The script skips files that are already processed, so each run only handles new images.

Serving Next Gen Images with Apache

At this point, the server is generating AVIF and WebP images in the background. The last piece is telling Apache how to serve those images automatically using your .htaccess file. This is where everything comes together, because it allows you to keep using your original image URLs while Apache quietly swaps in the optimized versions.

The .htaccess file sits in your web root, usually inside /home/user/public_html/. Apache reads this file on each request and applies the rewrite rules before serving content. That means you can control how images are delivered without touching your application code or WordPress itself.

Here is the full .htaccess configuration used for this setup:

<IfModule mod_rewrite.c>
    RewriteEngine On

    RewriteCond %{HTTP_ACCEPT} image/avif
    RewriteCond %{DOCUMENT_ROOT}/wp-content/avif-uploads/$1.avif -s
    RewriteRule ^wp-content/uploads/(.+)\.(jpe?g|png)$ /wp-content/avif-uploads/$1.avif [T=image/avif,L]

    RewriteCond %{HTTP_ACCEPT} image/webp
    RewriteCond %{DOCUMENT_ROOT}/wp-content/webp-uploads/$1.webp -s
    RewriteRule ^wp-content/uploads/(.+)\.(jpe?g|png)$ /wp-content/webp-uploads/$1.webp [T=image/webp,L]
</IfModule>

<IfModule mod_headers.c>
    Header append Vary Accept
</IfModule>

AddType image/avif .avif
AddType image/webp .webp

This configuration works by checking the browser’s Accept header. If the browser supports AVIF, Apache looks for a matching .avif file in your avif-uploads directory. If that file exists, it serves it instead of the original JPEG or PNG. If AVIF is not supported, it moves on and checks for WebP support, and then falls back to the original image if neither format is available.

The -s flag in the rewrite condition ensures the file exists and is not empty. This prevents broken image responses if a conversion failed or has not been created yet. It also keeps everything safe during the first few runs of your cron job while images are still being generated.

The Header append Vary Accept line is important for caching. It tells browsers and proxies that the response may change depending on the Accept header. Without this, you could run into caching issues where the wrong image format is served to the wrong browser.

The AddType directives make sure Apache correctly identifies AVIF and WebP files when serving them. Without these, some setups may send the wrong content type, which can cause display issues in certain browsers.

Once this is in place, everything happens automatically. You keep using standard image URLs like /wp-content/uploads/..., and Apache handles the rest behind the scenes.

Why This Approach Works Better Than Plugins

Most WordPress plugins try to do this in real time. They intercept requests, generate images on demand, and store them afterward. That works, but it adds overhead to every request.

This approach is different. Everything happens ahead of time. By the time a visitor requests an image, it is already converted and ready to go.

It also avoids dependency issues. You are not relying on an external API or a plugin that may stop being maintained. Everything runs locally using standard Linux tools.

Performance Benefits You Will Actually See

Once this is in place, the difference shows up quickly. Pages load faster, especially on mobile connections where bandwidth matters more. Image-heavy pages benefit the most, since those are usually the biggest contributors to load time.

Server load stays low because conversions happen in the background. Apache simply serves static files, which is what it does best. There is no additional processing during page requests.

Storage usage can increase slightly because you are keeping multiple versions of images. In practice, the savings in bandwidth and performance usually outweigh that tradeoff.

Final Thoughts

This setup gives you full control over image optimization without relying on third party services. It runs quietly, requires very little maintenance, and scales well as your site grows.

Once it is in place, you can forget about it. New images get converted automatically, Apache serves the best format available, and your site stays fast without extra effort.

If you are already managing your own server, this is one of those improvements that is worth the small amount of setup time.

Tags: ApacheAutomationLinuxProgrammingSEO
ShareTweetSharePinShareShareScan
ADVERTISEMENT
Jonathan Moore

Jonathan Moore

I am a Senior Software Engineer and Cybersecurity Specialist with 30+ years of experience building applications for Linux and Windows systems. I focus on custom web platforms, server infrastructure, and security-focused tools, with a strong emphasis on performance and reliability. Over the years, I have built everything from WordPress plugins and automation systems to ad serving platforms, monitoring tools, and API-driven applications. I enjoy working close to the system, solving real problems, and building tools that are meant to be used.

Related Articles

Fastest Way to Extract a Massive .tar.gz File on Linux

Fastest Way to Extract a Massive .tar.gz File on Linux

When I am dealing with a 40GB or 50GB website backup, I do not just run tar -xzf file.tar.gz and...

Monitor SSL Expiration with Python

Monitor SSL Expiration with Python

SSL certificates are one of those systems that work quietly in the background until something goes wrong. When a certificate...

My SSH Setup: How I Manage Multiple Servers

My SSH Setup: How I Manage Multiple Servers

If you work with more than one server, the need to manage multiple servers with SSH becomes obvious pretty quickly....

Recommended Services

Latest Articles

Server-Side Image Conversion with Apache

Server-Side Image Conversion with Apache

I stopped relying on third party image services a while ago. They work, but they add cost, latency, and another...

Read moreDetails

Imposter Syndrome as a Self-Taught Developer

Imposter Syndrome as a Self-Taught Developer

I started writing code over 35 years ago. Everything I learned came from figuring things out on my own, long...

Read moreDetails

Fastest Way to Extract a Massive .tar.gz File on Linux

Fastest Way to Extract a Massive .tar.gz File on Linux

When I am dealing with a 40GB or 50GB website backup, I do not just run tar -xzf file.tar.gz and...

Read moreDetails

Monitor SSL Expiration with Python

Monitor SSL Expiration with Python

SSL certificates are one of those systems that work quietly in the background until something goes wrong. When a certificate...

Read moreDetails
  • Privacy Policy
  • Terms of Service

© 2025 JMooreWV. All rights reserved.

No Result
View All Result
  • Home
  • Guides
    • Linux
    • Programming
      • JavaScript
      • PHP
      • Python
    • Tools
    • WordPress
  • Blog
    • Artificial Intelligence
    • Tutorials
    • Privacy
    • Security
  • Apps
    • Bible App
    • Bible Verse Screensaver
    • Blue AI Chatbot
    • Early Spring Predictor
    • FIGlet Generator
    • Password Generator
    • StegX
    • The Matrix
    • WeatherX
    • Website Risk Level Tool
  • About
    • About JMooreWV
    • Live Cyber Attack Stats
  • Contact
    • General Contact
    • Website Administration & Cybersecurity