Skip to content

Running SIPI

SIPI can be run either as a command-line image converter or as an IIIF media server.

Quick Start with Docker

docker run -p 1024:1024 daschswiss/sipi

Running SIPI as a Command-line Image Converter

SIPI now uses verb-noun subcommands (convert, query, compare, verify, server, health) instead of the legacy --convert / --query / --compare / --file / --outf flags. A bare sipi invocation errors with a usage message — every operation needs an explicit subcommand.

Convert an image file to another format:

sipi convert input.tif output.jpg --format jpg

Query image file information:

sipi query input.tif

Compare two image files pixel-wise:

sipi compare file1.tif file2.jpg

Running SIPI as a Server

sipi server --config config/sipi.config.lua

Health Check

sipi health is a self-contained liveness probe. It performs an HTTP GET on the local /health endpoint and maps the result to a process exit code, following the Docker/Swarm healthcheck convention:

  • 0 — the endpoint returned HTTP 200 (healthy).
  • 1 — connection refused, timeout, or any non-200 response (unhealthy).
sipi health            # probes http://127.0.0.1:1024/health
sipi health --port 80  # probe a server running on a different port

The host is always 127.0.0.1 and the path is always /health; only the port is configurable. A separate sipi health process cannot know whether the running server took its port from a config file, an env var, or --serverport, so the caller passes the port it configured (--port, default 1024). The probe uses a short (~2 s) timeout so a wedged server reports unhealthy rather than hanging. Because it needs no curl in the image, it is the intended container/orchestrator liveness command (see Health Endpoint).

Logging

SIPI uses two logging modes depending on how it is running:

  • CLI mode (convert, compare, query): Plain text output. Errors go to stderr, informational messages go to stdout. This is the standard Unix convention for command-line tools. When --json is also set (see Structured JSON output), every level is routed to stderr so stdout stays reserved for the single JSON document.

  • Server mode (sipi server --config): JSON-formatted log lines go to stdout. This follows container best practices — Docker, Kubernetes, and log collectors (Grafana Loki, Fluentd) expect structured logs on stdout. Each line is a JSON object: {"level": "INFO", "message": "..."}.

Log Levels

SIPI supports the following log levels (in order of increasing severity):

Level Description
DEBUG Detailed diagnostic information.
INFO Normal operational messages (routes added, server started, migrations).
NOTICE Significant but normal events.
WARNING Something unexpected but recoverable (e.g., failed XMP parse, incomplete metadata write).
ERR Errors that affect a specific operation (e.g., image processing failure, ICC error).
CRIT Critical errors.
ALERT Conditions requiring immediate attention.
EMERG System-wide emergencies.

The log level controls which messages are emitted. Setting a level suppresses all messages below it. For example, WARNING shows only WARNING, ERR, CRIT, ALERT, and EMERG — suppressing DEBUG, INFO, and NOTICE.

The log level can be configured in three ways (in order of precedence):

  1. CLI option: --loglevel WARNING
  2. Environment variable: SIPI_LOGLEVEL=WARNING
  3. Lua config: loglevel = "WARNING" (in the sipi block)

If none is specified, the default level is INFO.

Command-line Options

Image Conversion Options

These options are accepted by the convert subcommand (and where documented in the per-subcommand matrix, by convert access-file and convert service-file). Usage: sipi convert <input> <output> [options].

Flag Short Description
--format <fmt> -F Output format: jpx, jp2, jpg, tif, png, webp, gif
--icc <profile> -I Convert to ICC profile: none, sRGB, AdobeRGB, GRAY
--quality <1-100> -q JPEG compression quality (1 = highest compression, 100 = best quality)
--pagenum <n> -n Page number for multi-page PDF/TIFF input files
--region <x,y,w,h> -r Select a region of interest (4 integer values)
--reduce <factor> -R Reduce image size by factor (faster than --scale)
--size <w,h> -s Resize image to given dimensions
--scale <percent> -S Resize image by percentage
--mirror <dir> -m Mirror image: none, horizontal, vertical
--rotate <angle> -o Rotate image by degrees (0.0 - 360.0)
--skipmeta -k Strip all metadata from the output file
--topleft Enforce TOPLEFT orientation
--watermark <file> -w Overlay a watermark (single-channel grayscale TIFF)
--Ctiff_pyramid Store output in pyramidal TIFF format

Query and Compare

Use the query and compare subcommands. --query / --compare flag forms are gone.

Subcommand Description
sipi query <file> Dump all information about the given file
sipi compare <f1> <f2> Compare two files pixel-wise

Structured JSON output (CLI)

Flag Description
--json Emit a single JSON document to stdout instead of human-readable output. Accepted by convert, convert access-file, query, and compare. Useful for programmatic consumers and for local debugging when no Sentry DSN is configured.

Use cases:

  • Local debugging with no Sentry DSN — the primary RDU case. Every ImageContext field normally sent to Sentry appears in the JSON document instead.
  • CI pipelines that need to assert on image properties (jq '.image.bps') or on a specific failure mode (jq '.phase').
  • Scripts that consume sipi output pipeline-style.

See json-output.md for the full schema, worked examples, and the stdout / stderr contract.

JPEG2000 Options

Flag Description
--Sprofile <val> J2K profile: PROFILE0, PROFILE1, PROFILE2, PART2, CINEMA2K, CINEMA4K, BROADCAST, CINEMA2S, CINEMA4S, CINEMASS, IMF
--rates <string> Bit-rate(s) for quality layers (-1 for lossless final layer)
--Clayers <n> Number of quality layers (default: 8)
--Clevels <n> Number of wavelet decomposition levels (default: 8)
--Corder <val> Progression order: LRCP, RLCP, RPCL, PCRL, CPRL (default: RPCL)
--Stiles <string> Tile dimensions "{tx,ty}" (default: "{256,256}")
--Cprecincts <string> Precinct dimensions "{px,py}" (default: "{256,256}")
--Cblk <string> Code-block dimensions "{dx,dy}" (default: "{64,64}")
--Cuse_sop <val> Include SOP markers (default: yes)

Server Options

These options are accepted by the server subcommand. Usage: sipi server [options].

Flag Short Env Var Default Description
--config <file> -c SIPI_CONFIGFILE Lua configuration file for server mode
--serverport <n> SIPI_SERVERPORT 80 HTTP port
--sslport <n> SIPI_SSLPORT 443 HTTPS port
--hostname <name> SIPI_HOSTNAME localhost Public DNS hostname
--keepalive <sec> SIPI_KEEPALIVE 5 HTTP keep-alive timeout in seconds (now enforced server-side)
--nthreads <n> -t SIPI_NTHREADS 0 (auto) Worker threads (0 = auto-detect from CPU cores, container-aware)
--max-waiting <n> SIPI_MAX_WAITING 0 (unlimited) Max queued connections before HTTP 503 rejection (0 = unlimited, timeout-only)
--queue-timeout <sec> SIPI_QUEUE_TIMEOUT 10 Max seconds a request waits in queue before 503
--maxpost <size> SIPI_MAXPOSTSIZE 300M Maximum POST upload size
--imgroot <path> SIPI_IMGROOT ./images Image repository root directory
--docroot <path> SIPI_DOCROOT ./server Web server document root
--wwwroute <path> SIPI_WWWROUTE /server URL route for web server
--scriptdir <path> SIPI_SCRIPTDIR ./scripts Directory for Lua route scripts
--tmpdir <path> SIPI_TMPDIR ./tmp Temporary files directory
--maxtmpage <sec> SIPI_MAXTMPAGE 86400 Max age of temp files in seconds
--initscript <path> SIPI_INITSCRIPT ./config/sipi.init.lua Path to Lua init script
--cachedir <path> SIPI_CACHEDIR ./cache Cache directory
--cachesize <size> SIPI_CACHESIZE 200M Maximum cache size (-1=unlimited, 0=disabled)
--cachenfiles <n> SIPI_CACHENFILES 200 Maximum number of cached files (0=no limit)
--thumbsize <size> SIPI_THUMBSIZE !128,128 Default thumbnail size (IIIF syntax)
--sslcert <path> SIPI_SSLCERTIFICATE ./certificate/certificate.pem SSL certificate path
--sslkey <path> SIPI_SSLKEY ./certificate/key.pem SSL key file path
--jwtkey <string> SIPI_JWTKEY JWT shared secret (42 chars)
--loglevel <level> SIPI_LOGLEVEL DEBUG Log level (see Logging section)

Sentry Error Reporting

Flag Env Var Description
--sentry-dsn <url> SIPI_SENTRY_DSN Sentry DSN for error reporting
--sentry-release <ver> SIPI_SENTRY_RELEASE Sentry release version
--sentry-environment <env> SIPI_SENTRY_ENVIRONMENT Sentry environment name

Deprecated Options

Flag Description
--subdirlevels <n> Number of subdirectory levels (deprecated)
--subdirexcludes <dirs> Directories excluded from subdir calculations
--pathprefix Treat IIIF prefix as file path (deprecated)

Environment Variables

All server options can be configured via environment variables. Environment variables override Lua configuration file values but are themselves overridden by command-line flags.

Variable CLI Flag Default Description
SIPI_CONFIGFILE --config Configuration file path
SIPI_SERVERPORT --serverport 80 HTTP port
SIPI_SSLPORT --sslport 443 HTTPS port
SIPI_HOSTNAME --hostname localhost Public hostname
SIPI_KEEPALIVE --keepalive 5 Keep-alive timeout (seconds, now enforced server-side)
SIPI_NTHREADS --nthreads 0 (auto) Worker threads (0 = auto-detect, container-aware)
SIPI_MAX_WAITING --max-waiting 0 (unlimited) Max queued connections before 503 (0 = unlimited, timeout-only)
SIPI_QUEUE_TIMEOUT --queue-timeout 10 Max seconds in queue before 503
SIPI_MAXPOSTSIZE --maxpost 300M Max POST size
SIPI_IMGROOT --imgroot ./images Image root directory
SIPI_DOCROOT --docroot ./server Document root
SIPI_WWWROUTE --wwwroute /server Web server route
SIPI_SCRIPTDIR --scriptdir ./scripts Lua scripts directory
SIPI_TMPDIR --tmpdir ./tmp Temporary directory
SIPI_MAXTMPAGE --maxtmpage 86400 Max temp file age
SIPI_INITSCRIPT --initscript ./config/sipi.init.lua Init script path
SIPI_CACHEDIR --cachedir ./cache Cache directory
SIPI_CACHESIZE --cachesize 200M Max cache size (-1=unlimited, 0=disabled)
SIPI_CACHENFILES --cachenfiles 200 Max cached files (0=no limit)
SIPI_THUMBSIZE --thumbsize !128,128 Thumbnail size
SIPI_SSLCERTIFICATE --sslcert ./certificate/certificate.pem SSL certificate
SIPI_SSLKEY --sslkey ./certificate/key.pem SSL key
SIPI_JWTKEY --jwtkey JWT secret
SIPI_JPEGQUALITY --quality 60 JPEG quality
SIPI_LOGLEVEL --loglevel DEBUG Log level
SIPI_SENTRY_DSN --sentry-dsn Sentry DSN
SIPI_SENTRY_RELEASE --sentry-release Sentry release
SIPI_SENTRY_ENVIRONMENT --sentry-environment Sentry environment
SIPI_MAX_DECODE_MEMORY --max-decode-memory 0 (auto) Max concurrent decode memory (0=auto 75%, 2G, 500M)
SIPI_DECODE_MEMORY_MODE --decode-memory-mode off Memory budget mode: off, monitor, enforce

Configuration precedence (highest to lowest):

  1. Command-line flags
  2. Environment variables
  3. Lua configuration file

Exit Codes and Error Handling

Exit Codes

When running SIPI as a command-line image converter, the process exit code indicates whether the conversion succeeded:

  • 0 — Success. The output file was written correctly.
  • 1 (EXIT_FAILURE) — Image processing error. The image could not be read, converted, or written.

Important for calling services: Always check the exit code. A non-zero exit code means the output file was not produced (or is incomplete).

The sipi health subcommand follows the same convention: 0 = healthy (/health returned 200), 1 = unhealthy (connection refused, timeout, or non-200).

Error Output

On failure, SIPI prints a short error message to stderr indicating the failure phase and the specific error. The format is:

Error <phase> image: <details>

Where <phase> is one of reading, converting, or writing. Example:

Error reading image: Unsupported JPEG colorspace JCS_UNKNOWN (file=input.jpg, dimensions=2048x1536, components=4)

Sentry Integration (CLI Mode)

When the SIPI_SENTRY_DSN environment variable is set, CLI conversion failures automatically send a Sentry event with rich image context. This allows developers to diagnose failures without reproducing them locally.

Each Sentry event includes:

  • Tags (indexed, searchable, filterable in Sentry):

    • sipi.mode — always cli for command-line conversions
    • sipi.phaseread, convert, or write
    • sipi.output_format — the target format (e.g., jpx, jpg, tif, png)
    • sipi.colorspace — the image's photometric interpretation
    • sipi.bps — bits per sample
  • Context ("Image" context with structured data):

    • input_file, output_file — file paths
    • width, height — image dimensions (if read successfully)
    • channels — number of color channels
    • bps — bits per sample
    • colorspace — photometric interpretation
    • icc_profile_type — ICC profile type (e.g., sRGB, AdobeRGB, CMYK)
    • orientation — EXIF orientation
    • file_size_bytes — input file size

Common Failure Causes

Error Meaning
Unsupported colorspace (JCS_UNKNOWN) The JPEG uses a colorspace SIPI cannot convert. Re-encode the source image in sRGB.
Unsupported bits/sample Only 8 and 16 bits/sample are supported. Images with other bit depths must be converted first.
Channel/colorspace mismatch The number of channels does not match the declared colorspace (e.g., 4 channels but RGB). The file metadata may be corrupt.
ICC profile incompatible The ICC profile does not match the channel count (e.g., CMYK profile on a 3-channel image).
Corrupt or truncated file The input file is incomplete or damaged.
Unsupported TIFF tiling The TIFF tile configuration is inconsistent or uses unsupported bit depths.

Integration Notes for Calling Services

If you call SIPI CLI from another service (e.g., a Java service):

  1. Check the exit code. Non-zero means failure — do not assume the output file exists or is valid.
  2. Parse stderr (optional). The first line of stderr contains a human-readable error message with the failure phase and details.
  3. Set SIPI_SENTRY_DSN to get full diagnostics server-side. Use the Sentry tags sipi.phase, sipi.colorspace, sipi.bps, and sipi.output_format to build alerts and filters for specific failure patterns.

Configuration Files

SIPI's configuration file is written in Lua. You can make your own configuration file by adapting config/sipi.config.lua.

  • Check that the port number is correct and that your operating system's firewall does not block it.
  • Set imgroot to the directory containing the files to be served.
  • Create the directory cache in the top-level directory of the source tree.

For more information, see the comments in config/sipi.config.lua and the Reference page for all configuration parameters.

HTTPS Support

SIPI supports SSL/TLS encryption if the OpenSSL library is installed. You will need to install a certificate; see config/sipi.config.lua for instructions.

IIIF Prefixes

SIPI supports IIIF Image API URLs.

If the configuration property prefix_as_path is set to true, the IIIF prefix portion of the URL is interpreted as a subdirectory of imgroot, and SIPI looks for the requested image file in that subdirectory. Otherwise, it looks for the file in imgroot.