---
title: "Develop a docker image"
slug: "develop-a-docker-image"
updated: 2023-02-15T12:33:12Z
published: 2023-02-15T12:33:12Z
canonical: "docs.akridata.ai/develop-a-docker-image"
---

> ## Documentation Index
> Fetch the complete documentation index at: https://docs.akridata.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Develop a docker image(thumbnail generator)

As described in [Pipelines and dockers](/data-explorer/docs/pipelines-and-dockers), there are four types of docker images, namely the Image preprocessor, featurizer, thumbnail generator and attribute generator. This article describes the general process for developing a docker image using a thumbnail generator as an example. The rest of the articles detail the interface specification for other types of dockers and the fields required for registering other types of dockers.

## Interface specification

| **Input location** | The input images are presented at location /input/i1, with multiple images(1000+) presented at this location. |
| --- | --- |
| **Output location** | The docker is expected to produce thumbnails at /output/o1. There should be 1 thumbnail file generated per input file in /input/i1, and the name of the output file must exactly match the name of the input file path relative to the input location. For e.g. If the input file is at /input/i1/dir1/a.jpg, then the output thumbnail must be produced at /output/o1/dir1/a.jpg. |
| **Output format** | Common formats like PNG and JPG are recommended. Irrespective of the output format, the filename must exactly match the filename of the input file. |
| **Other details** | - The aspect ratio of the thumbnail should preferably match that of the input image. - The resolution of the thumbnail should be sufficient to provide good visual clarity on the UI. The default provided thumbnail generator produces thumbnails at a resolution of 192x108 pixels. - The thumbnail size should preferably be limited to under 20KB per thumbnail. |

## Sample program

Based on the above specification, a sample implementation(in Python) is provided below. This program does the following.

1. Reads files from /input/i1
2. For each file, extracts the filename from the path and write out a thumbnail with the exact same filename preserving the path relative to /input/i1.

```python
import os

from PIL import Image, ImageFile, UnidentifiedImageError

OUTPUT_WIDTH = 192
OUTPUT_HEIGHT = 108
ImageFile.LOAD_TRUNCATED_IMAGES = True
SOURCE_DIR = '/input/i1'
DEST_DIR = '/output/o1'

def get_input_files():
    file_list = []
    for root, _, files in os.walk(SOURCE_DIR):
        for filename in files:
            file_list.append(os.path.join(root, filename))
    return file_list

def generate_thumbnail_and_save(fname, width, height):
    try:
        with Image.open(fname) as img:
            img.thumbnail((width, height), resample=Image.BICUBIC)
            # Extract filename and save thumbnail with same filename
            dest_path = os.path.join(DEST_DIR, fname[len(SOURCE_DIR) + 1:])
            path_dir = os.path.dirname(dest_path)
            if not os.path.exists(path_dir):
                os.makedirs(path_dir)
            img.convert('RGB').save(dest_path, format="JPEG", quality=95)
    except UnidentifiedImageError as ex:
        print("Unknown Image format {}".format(fname))
        raise ex
    except Exception as ex:
        print("Failed to generate thumbnail for {}".format(fname))
        raise ex

def main():
    input_files = get_input_files()
    # Throw error if input is empty
    if len(input_files) == 0:
        print("Input file list to create thumbnail is empty")
        raise ValueError("Input file list to create thumbnail is empty")

    for f in input_files:
        generate_thumbnail_and_save(f, OUTPUT_WIDTH, OUTPUT_HEIGHT)

if __name__ == "__main__":
    if not os.path.exists(DEST_DIR):
        os.makedirs(DEST_DIR)
    main()
```

## Packaging into a docker

Below is a sample Dockerfile to build docker with the above Python program and necessary dependencies. The Dockerfile assumes the above Python program is stored as cmds/thumbnail.py relative to where this build is being done and copies the file into /opt/akridata/thumbnail.py within the docker.

```none
FROM python:3.8-slim-buster

RUN python3.8 -m pip install --upgrade pip==21.2.4 pillow==9.0.1
RUN mkdir /opt/akridata/
COPY cmds/thumbnail.py /opt/akridata/thumbnail.py
```

With the above stored as Dockerfile, the docker image can be built using the following command.

```shell
docker build -t thumbnail_generator:latest .
```

The docker can be tested using a sample command as below. The test assumes one or more input images are stored in /tmp/i1. The -v option mounts /tmp/i1 at /input/i1 within the docker and /tmp/o1 at /output/o1 within the docker. At the end of a successful run, the output thumbnails are expected to be present in /tmp/o1 with the same file names as the files in /tmp/i1.

```shell
docker run -v /tmp/i1:/input/i1 -v /tmp/o1:/output/o1 thumbnail_generator:latest python3 /opt/akridata/thumbnail.py
```

## Upload docker to a registry(docker repository)

The docker image must be uploaded to the registry using the docker push command. Please refer to [Publish-docker-image](/data-explorer/docs/publish-a-docker-image) for more details.
