Create a Docker Container to Compress Images Using MozJpeg

Tiempo de lectura: 3 minutos

Today we are going to create a Docker container that will allow us to compress jpg images within a directory.

Compressing images is very important, especially when setting up a web service. This container will provide a powerful image compressor created by Mozilla and will speed up the download process for our users.

First, we will create this Dockerfile

# Use the base image of Alpine Linux
FROM alpine:latest

# Update package index and then install necessary tools, including a C compiler
RUN apk update && \
    apk add --no-cache \
    cmake \
    autoconf \
    automake \
    libtool \
    nasm \
    make \
    pkgconfig \
    git \
    libpng-dev \
    zlib-dev \
    build-base

# Clone the MozJPEG repository from GitHub
RUN git clone https://github.com/mozilla/mozjpeg.git /mozjpeg

# Change to the MozJPEG working directory
WORKDIR /mozjpeg

# Configure, compile and install MozJPEG
RUN mkdir build && cd build && \
    cmake -G"Unix Makefiles" .. -DPNG_SUPPORTED=0 && \
    make install

# Create symbolic links only if they do not already exist
RUN test -f /opt/mozjpeg/bin/cjpeg  ln -s /usr/local/bin/cjpeg /opt/mozjpeg/bin/cjpeg && \
    test -f /opt/mozjpeg/bin/djpeg  ln -s /usr/local/bin/djpeg /opt/mozjpeg/bin/djpeg

# Change to the working directory
WORKDIR /

CMD ["tail", "-f", "/dev/null"]

This will create the image with the MozJPEG library

Now let’s create a docker-compose.yml to launch the container.

version: '3'

services:
  mozjpeg:
    build: 
      context: .
      dockerfile: Dockerfile
    container_name: mozjpeg-container
    #tty: true
    volumes:
      - ${IMAGES_FOLDER}:/images

And create the .env file that will allow us to define IMAGES_FOLDER

.env

IMAGES_FOLDER=./images

The project looks like this:

You can create the .gitignore:

.DS_Store
.env

# Ignore files generated during image build
.DS_Store
.idea/
.vscode/
*.log
*.pid
*.pyc

images/*

Once created, we will need to run it:

docker compose up -d

And we can launch the command that will compress the items:

   docker exec mozjpeg-container sh -c 'cd /images && for file in *.jpg; do /opt/mozjpeg/bin/cjpeg -quality 80 "$file" > "$file.tmp" && mv "$file.tmp" "$file"; done'

Regarding the quality 80 indicated in the command, we can use this strategy:

  1. Acceptable quality: For most images on a website, a quality between 60 and 80 is generally sufficient. This significantly reduces the file size without a noticeable loss in visual quality.
  2. High-quality photographs: If your website includes high-quality images, such as professional photographs, you may opt for a higher quality between 80 and 90. This will preserve more details and colors but will also result in larger files.
  3. Graphics and logos: For graphics, logos, and other visual elements that contain solid color areas and sharp edges, you can use a lower quality between 50 and 70 without noticeable loss of quality.
  4. Testing and optimization: It is always advisable to perform tests and optimizations to find the right balance between visual quality and file size. You can test different quality settings and see how they affect your website’s performance using web performance analysis tools.
  5. Lossless compression: For images that need to maintain original quality, such as logos or detailed illustrations, consider using image formats with lossless compression, such as PNG.

To run the compression task periodically, it can be executed using a cron job or Ofelia.

Leave a Comment