Skip to content
LogoLogo

Configuration

imgx reads all configuration from environment variables prefixed with IMGX_. Every variable is optional and has a sensible default. The legacy ZIMGX_ prefix (from the prior Zig implementation) is still read as a fallback for one release; prefer IMGX_ for all new configuration.

Server

VariableTypeDefaultDescription
IMGX_SERVER_PORTu168080TCP port to listen on
IMGX_SERVER_HOSTstring0.0.0.0IP address to bind to. Set to 127.0.0.1 to restrict to localhost.
IMGX_SERVER_REQUEST_TIMEOUT_MSu3230000Maximum time (ms) to wait for a complete request
IMGX_SERVER_MAX_REQUEST_SIZEusize52428800 (50 MiB)Maximum request/response body size in bytes

Origin

VariableTypeDefaultDescription
IMGX_ORIGIN_TYPEstringhttphttp fetches from IMGX_ORIGIN_BASE_URL. r2 fetches from an R2 bucket.
IMGX_ORIGIN_BASE_URLstringhttp://localhost:9000Base URL for the HTTP origin. The image path is appended to this value.
IMGX_ORIGIN_TIMEOUT_MSu3210000Timeout (ms) for origin fetch requests
IMGX_ORIGIN_MAX_RETRIESu82Retry attempts for failed origin fetches
IMGX_ORIGIN_PATH_PREFIXstring""Path prefix to strip from image paths before fetching from origin. When set, requests for /<prefix>/<key> resolve to origin key <key>. Useful for Cloudflare Images migration where URLs include the account ID.
IMGX_ALLOW_REMOTE_SOURCESboolfalseAllow the source-image segment of a request to be an absolute http:///https:// URL (Cloudflare parity: /image/<OPTIONS>/<SOURCE-IMAGE> where <SOURCE-IMAGE> is a full URL), fetched directly instead of from IMGX_ORIGIN_BASE_URL. Security warning: enabling this means imgx will fetch whatever URL a client's request names. A dedicated SSRF-safe fetcher enforces a scheme allowlist (http/https only), rejects addresses that resolve (or are given literally) as private/loopback/link-local/CGNAT, caps and re-validates redirects, and applies the same size/timeout limits as the configured origin — but these guards mitigate, not eliminate, risk against internal services. Only enable this if you understand and accept that risk, ideally alongside network-level isolation (e.g. running imgx without access to internal-only services/metadata endpoints). See docs/INVARIANTS.md INV-14 and docs/CLOUDFLARE_PARITY.md gap 2.
IMGX_ALLOW_DRAW_OVERLAYSboolfalseAllow draw[].url overlay images (Cloudflare parity: draw.<N>.url=...) to be fetched from an arbitrary http:///https:// URL. Independent of IMGX_ALLOW_REMOTE_SOURCES — enable one without the other if you only want overlays, or only want remote main sources. Reuses the exact same SSRF-safe fetcher and guards; the same security warning above applies. See docs/CLOUDFLARE_PARITY.md gap 11.

R2/S3

Required when IMGX_ORIGIN_TYPE=r2. All fields must be non-empty.

VariableTypeDefaultDescription
IMGX_R2_ENDPOINTstring""R2/S3-compatible endpoint URL
IMGX_R2_ACCESS_KEY_IDstring""Access key ID
IMGX_R2_SECRET_ACCESS_KEYstring""Secret access key
IMGX_R2_BUCKET_ORIGINALSstringoriginalsBucket for source images
IMGX_R2_BUCKET_VARIANTSstringvariantsBucket for cached transformed variants (L2 cache)

Transform limits

VariableTypeDefaultDescription
IMGX_TRANSFORM_MAX_WIDTHu328192Maximum output width in pixels
IMGX_TRANSFORM_MAX_HEIGHTu328192Maximum output height in pixels
IMGX_TRANSFORM_DEFAULT_QUALITYu880Default JPEG/WebP/AVIF quality when q is not specified
IMGX_TRANSFORM_MAX_PIXELSu6471000000Maximum total pixel count (width x height). Images exceeding this are rejected.
IMGX_TRANSFORM_STRIP_METADATAbooltrueStrip EXIF and other metadata from output. Accepts true/1 or false/0.
IMGX_TRANSFORM_MAX_FRAMESu32100Maximum frames to load from animated images. Excess frames are truncated.
IMGX_TRANSFORM_MAX_ANIMATED_PIXELSu6450000000Maximum total pixels across all frames. Animated images exceeding this budget are served as a static first frame.

Cache

VariableTypeDefaultDescription
IMGX_CACHE_ENABLEDbooltrueEnable the in-memory L1 cache. When disabled, every request fetches from origin and is served uncached.
IMGX_CACHE_MAX_SIZE_BYTESusize536870912 (512 MiB)Maximum memory for the L1 cache. Entries are evicted using LRU when exceeded; entries larger than the limit are served but not cached.
IMGX_CACHE_DEFAULT_TTL_SECONDSu323600TTL for Cache-Control: public, max-age= headers on image responses

Validation

imgx validates configuration at startup and refuses to start if:

  • IMGX_SERVER_PORT is 0
  • IMGX_SERVER_REQUEST_TIMEOUT_MS or IMGX_ORIGIN_TIMEOUT_MS is 0
  • IMGX_TRANSFORM_MAX_WIDTH or IMGX_TRANSFORM_MAX_HEIGHT is 0
  • IMGX_TRANSFORM_DEFAULT_QUALITY is outside 1–100
  • IMGX_ORIGIN_TYPE=http and IMGX_ORIGIN_BASE_URL is empty
  • IMGX_ORIGIN_TYPE=r2 and any R2 field is empty

Logging

Read directly from the environment at startup (not part of Config, so there's no IMGX_ prefix):

VariableDescription
RUST_LOGStandard tracing/env_logger-style filter, e.g. RUST_LOG=debug or RUST_LOG=info,imgx=debug. Defaults to info if unset.
IMGX_LOG_FORMAT=jsonStructured JSON log lines instead of human-readable text — useful for log-shipping pipelines (Cloud Logging, Loki, etc.) that parse structured fields. Any other value (or unset) keeps the default text format.

Example .env file

# Origin
IMGX_ORIGIN_TYPE=r2
 
# R2
IMGX_R2_ENDPOINT=https://0bc82bff4439c556f9dc1b054d2de6d7.r2.cloudflarestorage.com
IMGX_R2_ACCESS_KEY_ID=your-access-key
IMGX_R2_SECRET_ACCESS_KEY=your-secret-key
IMGX_R2_BUCKET_ORIGINALS=originals
IMGX_R2_BUCKET_VARIANTS=variants
 
# Server
IMGX_SERVER_PORT=8080
IMGX_SERVER_HOST=0.0.0.0
 
# Cache
IMGX_CACHE_ENABLED=true
IMGX_CACHE_MAX_SIZE_BYTES=536870912
IMGX_CACHE_DEFAULT_TTL_SECONDS=3600
 
# Transform limits
IMGX_TRANSFORM_DEFAULT_QUALITY=80
IMGX_TRANSFORM_STRIP_METADATA=true
IMGX_TRANSFORM_MAX_FRAMES=100
IMGX_TRANSFORM_MAX_ANIMATED_PIXELS=50000000