EyeQ Docs

Using the Docker image

Learn how to use PFC Docker container to process images

This guide explains configuration options, volume mounts, and operational patterns for the Perfectly Clear Docker container.

Environment variables

You can configure the container behavior using environment variables passed with the -e flag. These variables control logging, caching, processing options, and more.

docker run -d \
  -v "$(pwd)/sdk_license":/sdk_license \
  -v "$(pwd)/presets":/presets \
  -p 80:80 \
  -e PFC_LOG_LEVEL='info' \
  -e PFC_IMG_CACHE_TTL='60' \
  pfc_container

Available variables

The following table lists all supported environment variables and their default values.

VariableDescriptionDefault
PFC_SITE_URLBase URL for download links returned by the APIhttp://localhost
PFC_LOG_LEVELLogging verbosity: debug, info, warning, errorinfo
PFC_IMG_CACHE_TTLMinutes to keep uploaded and corrected images before deletion60
PFC_AVXAVX instruction set usage: on, off, autoauto
PFC_USE_FASTFAEUse faster but less accurate face detectionfalse
PFC_SKIP_MODEImage skip mode: clipart, legacy, noneclipart
PFC_SKIP_EXIF_SOFTWARESkip images edited by specified software (comma-separated)
PFC_PRESERVE_INPUT_FILENAMEReuse input filename for outputfalse
PFC_ENABLE_COMPOSITEEnable composite photo extractiontrue
PFC_USE_AI_SERVERUse local AI server for faster correctionstrue

Volume mounts

The container supports several mount points for configuration and data. These allow you to provide license files, presets, custom looks, and configure input/output directories.

Mount pointPurpose
/sdk_licenseLicense files (required for license-protected builds)
/presetsPreset files and ICC profiles
/addonsCustom .looks files
/inputImages to be corrected
/outputCorrected images
/sceneCustom AI model files (.pnn)

Basic setup

The minimum required configuration mounts your license files and presets directory.

docker run -d \
  -v "$(pwd)/sdk_license":/sdk_license \
  -v "$(pwd)/presets":/presets \
  -p 80:80 \
  pfc_container

Before executing the command, ensure Docker daemon is running.

Direct file access

For high-volume workflows, you can mount input/output directories to bypass HTTP transfers entirely. This approach is faster for batch processing scenarios.

docker run -d \
  -v "$(pwd)/sdk_license":/sdk_license \
  -v "$(pwd)/presets":/presets \
  -v "$(pwd)/input":/input \
  -v "$(pwd)/output":/output \
  -p 80:80 \
  -e PFC_PRESERVE_INPUT_FILENAME='true' \
  pfc_container

With this setup, copy images directly to the input folder and use the filename as the imageKey. Corrected images appear in the output folder with the same filename.

API reference

The container exposes three HTTP endpoints for uploading images, applying corrections, and checking the SDK version.

Upload image

Use the PUT endpoint to upload an image and receive an imageKey for subsequent operations.

PUT /pfc

Headers:

Include headers with image type as required.

Content-Type: image/jpeg or image/png (required)

Response:

The imageKey is returned in the response object.

{
  "imageKey": "abc123"
}

Correct image

Use the GET endpoint with your imageKey to apply corrections and receive a download URL for the result.

GET /pfc/{imageKey}

Query parameters:

The following parameters let you control the correction behavior, output format, and resizing options.

ParameterDescription
presetPreset name to apply. Omit for AI Scene Detection
outputTypeOutput format: JPEG or PNG
outputQualityJPEG quality (40-100, default 90)
outputColorSpaceColor space: original, srgb, or ICC filename
widthOutput width in pixels
heightOutput height in pixels
longLong edge size in pixels
shortShort edge size in pixels
scaleScale percentage
autocropEnable auto cropping: true or false. This requires several other query parameters you can obtain from Workbench.
skipSkip mode: clipart, legacy, none. This parameter is ignored when using AI Preset Selection.
skip-exif-softwareSkip images edited by specified software
preserveInputFileNameIf set to true, reuse the same input file name as the output file name inside the container. This is for advanced usage. Also see the PFC_PRESERVE_INPUT_FILENAME environment variable.
enableCompositeEnable composite photo extraction (true/false). Default is true for packages that contain this additional feature. Also see the PFC_ENABLE_COMPOSITE environment variable.

Response:

The response object contains the corrected image URL.

{
  "corrected_url": "http://localhost/output/abc123.jpg",
  "scene": 5
}

The scene value indicates the detected scene category (-1 if unknown).

Get version

This endpoint returns the SDK version and supported features, useful for verifying your container deployment.

GET /version

Resizing priority

When multiple resize parameters are provided, only one is used based on a priority order. This prevents conflicting resize instructions.

The priority order is:

  1. width
  2. height
  3. long
  4. short
  5. scale

For width and height, the output size will be set to have either the specified width or height the other dimension is calculated automatically to maintain aspect ratio. For long and short, the parameter applies to whichever side of the image matches (longest or shortest edge).

When using scale, provide an integer percentage value. For example, scale=50 produces an image at half the original dimensions.

Scene detection

When no preset is specified, the container uses AI Scene Detection to automatically select the optimal preset for each image. This provides intelligent, content-aware corrections without manual preset selection.

To see all available scene categories, check the container logs at startup:

docker logs pfc_container | grep -i scene

The correction response includes a scene field indicating which category was detected:

{
  "corrected_url": "http://localhost/output/abc123.jpg",
  "scene": 5
}

A value of -1 means the scene was not detected or is unknown.

To use custom presets for each scene, export an AI Presets group from Perfectly Clear Workbench and mount it to the /presets directory.

Auto crop configuration

Auto crop uses face detection to automatically crop portrait images, ensuring consistent face size and positioning across a batch. This is particularly useful for school photos, ID photos, and similar workflows.

The easiest way to configure auto crop parameters is in Perfectly Clear Workbench:

  1. Open the cropping tool in Workbench.
  2. Configure your desired crop settings.
  3. Copy the parameters from the "info" panel.
  4. Use these values in your API calls.

Example pipelines

The following examples demonstrate common workflows for correcting images with the Docker container.

Apply a specific preset

Upload an image and apply a named preset to it.

imageKey=$(curl -s -H "Content-Type: image/jpeg" \
  -X PUT "http://localhost:80/pfc" \
  --upload-file photo.jpg | jq -r '.imageKey')

curl -s -X GET "http://localhost:80/pfc/${imageKey}?preset=pro" | jq

Resize output

Control the output dimensions using the long edge or scale parameters.

Set the long edge to 1200 pixels:

curl -s -X GET "http://localhost:80/pfc/${imageKey}?long=1200" | jq

Scale to 50%:

curl -s -X GET "http://localhost:80/pfc/${imageKey}?scale=50" | jq

Convert to PNG

Change the output format from JPEG to PNG.

curl -s -X GET "http://localhost:80/pfc/${imageKey}?outputType=PNG" | jq

Skip previously edited images

Avoid re-processing images that were already edited in other software like Photoshop or Lightroom.

curl -s -X GET "http://localhost:80/pfc/${imageKey}?skip-exif-software=photoshop,lightroom" | jq

Or set it globally via environment variable:

docker run -d \
  -v "$(pwd)/sdk_license":/sdk_license \
  -v "$(pwd)/presets":/presets \
  -p 80:80 \
  -e PFC_SKIP_EXIF_SOFTWARE='photoshop,lightroom' \
  pfc_container

Direct file workflow

For high-throughput scenarios, you can bypass HTTP transfers entirely by mounting the /input and /output directories. This approach eliminates network overhead and is ideal for batch processing.

docker run -d \
  -v "$(pwd)/sdk_license":/sdk_license \
  -v "$(pwd)/presets":/presets \
  -v "$(pwd)/input":/input \
  -v "$(pwd)/output":/output \
  -p 80:80 \
  -e PFC_PRESERVE_INPUT_FILENAME='true' \
  pfc_container

With this configuration:

  1. Copy images to your local input/ folder — they become available inside the container.
  2. Use the filename (photo.jpg) as the imageKey in the GET request, skipping the PUT upload step.
  3. Corrected images are saved to the output/ folder with the same filename.
# Copy image to input folder
cp photo.jpg ./input/

# Correct using filename as imageKey (no upload needed)
curl -s -X GET "http://localhost:80/pfc/photo.jpg" | jq

# Result is in ./output/photo.jpg

Monitoring and health checks

The container provides logging and health check capabilities to help you monitor its operation in production environments.

View logs

Use Docker's built-in log commands to view container output.

For a running container:

docker logs pfc_container

Follow logs in real-time:

docker logs -f pfc_container

Log levels

Set PFC_LOG_LEVEL to control the verbosity of log output.

  • debug: All requests and processing details
  • info: Basic usage information (default)
  • warning: Potential issues
  • error: Failures requiring attention

Health check

Verify the container is responding by calling the version endpoint.

curl -s "http://localhost:80/version" > /dev/null && echo "OK" || echo "FAIL"

Log message reference

The server uses the logrus logger package and outputs JSON-formatted logs for easy parsing. Logs can be read through docker logs pfc_container. The following table describes all status messages you may encounter.

IDLevelMethodMessageCausesSolutionHTTP Error
configuredMessageErrorConfiguredAlways shown to display parameters
unknownErrorLevelMessageErrorUnknown log level. Defaulting to 'info'Unrecognized error levelUse a valid error level: debug, info, warning, error (case insensitive)
noContentTypeRequestMessageDebugPUT /pfc/Ignoring request with wrong Content-TypeUser sent a request with an unsupported header400
bodyRequestMessageErrorPUT /pfc/Couldn't read body requestThe request image couldn't be extractedProbably wrongly encoded by the user or too much RAM pressure on your container503
temporaryFileCreationMessageErrorPUT /pfc/Couldn't create temporary file for input imageMake sure /input inside the container is writable and the machine has enough disk space503
temporaryFileWritingMessageErrorPUT /pfc/Couldn't close temporary file for outputMake sure /input inside the container is writable and the machine has enough disk space503
savingImageMessageDebugPUT /pfc/Processing imageAn image was processed
noIdMessageDebugGET /pfc/{id}Ignoring request without image keyClient called GET on /pfc/Correct client code400
invalidIdMessageDebugGET /pfc/{id}Ignoring invalid imageKeySanity check for ID failedUse correct image ID400
unknownImageIdMessageDebugGET /pfc/{id}Ignoring request with unknown image keyThe given ID does not existUse correct image ID400
unknownPresetMessageDebugGET /pfc/{id}Unknown preset requestedThe preset has not been uploaded or mountedMake sure to mount the correct preset directory under /presets and the preset exists, or correct the calling code400
temporaryOutputFileMessageErrorGET /pfc/{id}Couldn't create temporary file for outputThe /output partition is full or not writableMake sure the volume or machine has enough capacity or permissions. See exact error under 'error'503
temporaryCloseOutputFileMessageErrorGET /pfc/{id}Couldn't close temporary file for outputThe /output partition is full or not writableMake sure the volume or machine has enough capacity or permissions. See exact error under 'error'503
correctingImageMessageDebugGET /pfc/{id}Processing image
processingPFCErrorMessageErrorGET /pfc/{id}PerfectlyClear processing failedProcessing of the image caused errors. Check further details under 'error'Some specific images cause the corrections to fail and cannot be corrected through PFC503
cleanUpFileMessageInfoCouldn't delete fileCouldn't delete an image from the /input or /output directoriesIf mounting them, make sure the proper permissions are set
unknownOutputTypeMessageDebugUnknown output file type requestedOnly JPEG (or jpg) or PNG are supportedChange the client to only ask for JPEG or PNG
versionMessageInfoGET /versionDisplays Perfectly Clear SDK version

Common issues

Here are solutions for frequently encountered problems.

Corrected image identical to original

License validation failed. Check that sdk_license is mounted correctly and contains valid license files.

"Couldn't write image" error

Docker ran out of disk space. Check available space with docker system df.

Small images rejected

Images must be at least 32 pixels on the short side.

Beautify corrections not applied

Beautify corrections are disabled for images with aspect ratios higher than 21:1.

Production deployment

For production environments, use Docker Compose to manage the container lifecycle and configuration.

Run as a service

Docker Compose provides declarative configuration and automatic restart capabilities.

version: '3.8'
services:
  pfc:
    image: pfc_container
    ports:
      - "80:80"
    volumes:
      - ./sdk_license:/sdk_license:ro
      - ./presets:/presets:ro
      - ./input:/input
      - ./output:/output
    environment:
      - PFC_LOG_LEVEL=info
      - PFC_IMG_CACHE_TTL=30
    restart: unless-stopped

Resource considerations

Keep these factors in mind when planning your production deployment.

  • The container checks every 10 minutes for images older than PFC_IMG_CACHE_TTL and deletes them.
  • AI model loading takes time on first request always keep the container running for best performance.
  • We recommend at least 1GB RAM per CPU core for optimal processing.

DOCKER Version 10.7.2.1269 built from 4fa849d8101945eea725a08dd0dae5101f090fa0 on 11-10-2025.

Copyright © 2026 EyeQ Imaging Inc. All rights reserved.

On this page