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_containerAvailable variables
The following table lists all supported environment variables and their default values.
| Variable | Description | Default |
|---|---|---|
PFC_SITE_URL | Base URL for download links returned by the API | http://localhost |
PFC_LOG_LEVEL | Logging verbosity: debug, info, warning, error | info |
PFC_IMG_CACHE_TTL | Minutes to keep uploaded and corrected images before deletion | 60 |
PFC_AVX | AVX instruction set usage: on, off, auto | auto |
PFC_USE_FASTFAE | Use faster but less accurate face detection | false |
PFC_SKIP_MODE | Image skip mode: clipart, legacy, none | clipart |
PFC_SKIP_EXIF_SOFTWARE | Skip images edited by specified software (comma-separated) | — |
PFC_PRESERVE_INPUT_FILENAME | Reuse input filename for output | false |
PFC_ENABLE_COMPOSITE | Enable composite photo extraction | true |
PFC_USE_AI_SERVER | Use local AI server for faster corrections | true |
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 point | Purpose |
|---|---|
/sdk_license | License files (required for license-protected builds) |
/presets | Preset files and ICC profiles |
/addons | Custom .looks files |
/input | Images to be corrected |
/output | Corrected images |
/scene | Custom 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_containerBefore 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_containerWith 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 /pfcHeaders:
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.
| Parameter | Description |
|---|---|
preset | Preset name to apply. Omit for AI Scene Detection |
outputType | Output format: JPEG or PNG |
outputQuality | JPEG quality (40-100, default 90) |
outputColorSpace | Color space: original, srgb, or ICC filename |
width | Output width in pixels |
height | Output height in pixels |
long | Long edge size in pixels |
short | Short edge size in pixels |
scale | Scale percentage |
autocrop | Enable auto cropping: true or false. This requires several other query parameters you can obtain from Workbench. |
skip | Skip mode: clipart, legacy, none. This parameter is ignored when using AI Preset Selection. |
skip-exif-software | Skip images edited by specified software |
preserveInputFileName | If 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. |
enableComposite | Enable 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 /versionResizing 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:
widthheightlongshortscale
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 sceneThe 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:
- Open the cropping tool in Workbench.
- Configure your desired crop settings.
- Copy the parameters from the "info" panel.
- 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" | jqResize 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" | jqScale to 50%:
curl -s -X GET "http://localhost:80/pfc/${imageKey}?scale=50" | jqConvert to PNG
Change the output format from JPEG to PNG.
curl -s -X GET "http://localhost:80/pfc/${imageKey}?outputType=PNG" | jqSkip 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" | jqOr 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_containerDirect 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_containerWith this configuration:
- Copy images to your local
input/folder — they become available inside the container. - Use the filename (
photo.jpg) as theimageKeyin the GET request, skipping the PUT upload step. - 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.jpgMonitoring 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_containerFollow logs in real-time:
docker logs -f pfc_containerLog levels
Set PFC_LOG_LEVEL to control the verbosity of log output.
debug: All requests and processing detailsinfo: Basic usage information (default)warning: Potential issueserror: 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.
| ID | Level | Method | Message | Causes | Solution | HTTP Error |
|---|---|---|---|---|---|---|
configuredMessage | Error | — | Configured | Always shown to display parameters | — | — |
unknownErrorLevelMessage | Error | — | Unknown log level. Defaulting to 'info' | Unrecognized error level | Use a valid error level: debug, info, warning, error (case insensitive) | — |
noContentTypeRequestMessage | Debug | PUT /pfc/ | Ignoring request with wrong Content-Type | User sent a request with an unsupported header | — | 400 |
bodyRequestMessage | Error | PUT /pfc/ | Couldn't read body request | The request image couldn't be extracted | Probably wrongly encoded by the user or too much RAM pressure on your container | 503 |
temporaryFileCreationMessage | Error | PUT /pfc/ | Couldn't create temporary file for input image | — | Make sure /input inside the container is writable and the machine has enough disk space | 503 |
temporaryFileWritingMessage | Error | PUT /pfc/ | Couldn't close temporary file for output | — | Make sure /input inside the container is writable and the machine has enough disk space | 503 |
savingImageMessage | Debug | PUT /pfc/ | Processing image | An image was processed | — | — |
noIdMessage | Debug | GET /pfc/{id} | Ignoring request without image key | Client called GET on /pfc/ | Correct client code | 400 |
invalidIdMessage | Debug | GET /pfc/{id} | Ignoring invalid imageKey | Sanity check for ID failed | Use correct image ID | 400 |
unknownImageIdMessage | Debug | GET /pfc/{id} | Ignoring request with unknown image key | The given ID does not exist | Use correct image ID | 400 |
unknownPresetMessage | Debug | GET /pfc/{id} | Unknown preset requested | The preset has not been uploaded or mounted | Make sure to mount the correct preset directory under /presets and the preset exists, or correct the calling code | 400 |
temporaryOutputFileMessage | Error | GET /pfc/{id} | Couldn't create temporary file for output | The /output partition is full or not writable | Make sure the volume or machine has enough capacity or permissions. See exact error under 'error' | 503 |
temporaryCloseOutputFileMessage | Error | GET /pfc/{id} | Couldn't close temporary file for output | The /output partition is full or not writable | Make sure the volume or machine has enough capacity or permissions. See exact error under 'error' | 503 |
correctingImageMessage | Debug | GET /pfc/{id} | Processing image | — | — | — |
processingPFCErrorMessage | Error | GET /pfc/{id} | PerfectlyClear processing failed | Processing of the image caused errors. Check further details under 'error' | Some specific images cause the corrections to fail and cannot be corrected through PFC | 503 |
cleanUpFileMessage | Info | — | Couldn't delete file | Couldn't delete an image from the /input or /output directories | If mounting them, make sure the proper permissions are set | — |
unknownOutputTypeMessage | Debug | — | Unknown output file type requested | Only JPEG (or jpg) or PNG are supported | Change the client to only ask for JPEG or PNG | — |
versionMessage | Info | GET /version | Displays 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-stoppedResource considerations
Keep these factors in mind when planning your production deployment.
- The container checks every 10 minutes for images older than
PFC_IMG_CACHE_TTLand 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.