Deploy imagor - transform images on demand
Resize, crop, and optimize images on demand via simple URLs
shumc/imagor
shumc/imagor
Just deployed
Deploy and Host imagor on Railway
What is imagor?
Imagor is a blazing-fast, Go-powered image processing server that lets you resize, crop, optimize, and transform images on demand through simple URLs. It’s built for speed, security, and flexibility - making it perfect for modern apps, SaaS platforms, and APIs that need powerful image handling without external dependencies.
About Hosting imagor
Hosting Imagor on Railway means you can instantly deploy a production-ready image processing service with zero hassle. Railway takes care of scaling, networking, and environment configuration, so you can focus on delivering responsive, media-rich experiences to your users. Imagor supports multiple storage backends (local, S3, GCS, Cloudflare R2) and integrates seamlessly with your stack. With environment variables like IMAGOR_SECRET
and SENTRY_DSN
, you get full control over security and observability, while Railway ensures smooth deployments and auto-scaling infrastructure behind the scenes.
Common Use Cases
- Serve responsive images optimized for web and mobile apps
- Automate thumbnails, previews, and image transformations for SaaS platforms
- Securely deliver media from S3, R2, or local storage with signed URLs
Dependencies for imagor
- Docker image:
shumc/imagor
- Storage backend (local filesystem, AWS S3, Cloudflare R2, or GCS) - Optional
Deployment Dependencies
Why Deploy imagor on Railway?
Railway is a singular platform to deploy your infrastructure stack. Railway will host your infrastructure so you don't have to deal with configuration, while allowing you to vertically and horizontally scale it.
Available configuration
PORT="8000" # Port Imagor listens on (default 8000)
DEBUG="0" # Enable debug mode. 0 = off, 1 = on
IMAGOR_SECRET="railway" # Secret key for signing URLs. Required unless IMAGOR_UNSAFE=1
IMAGOR_UNSAFE="0" # Unsafe mode (no signature validation). 0 = off, 1 = on (not for production)
IMAGOR_AUTO_WEBP="1" # Auto convert to WebP if client accepts it
IMAGOR_AUTO_AVIF="0" # Auto convert to AVIF if client accepts it (experimental)
IMAGOR_AUTO_JPEG="0" # Auto convert to JPEG if client accepts it
IMAGOR_BASE_PARAMS="filters:watermark(example.png)" # Default params applied to all requests
IMAGOR_SIGNER_TYPE="sha1" # URL signer: sha1 (default), sha256, sha512
IMAGOR_SIGNER_TRUNCATE="16" # Truncate signature length in characters
IMAGOR_RESULT_STORAGE_PATH_STYLE="digest" # Path style for result storage: original, digest, suffix
IMAGOR_STORAGE_PATH_STYLE="digest" # Path style for storage: original, digest
IMAGOR_CACHE_HEADER_TTL="168h" # Cache TTL for successful responses (default 168h = 7 days)
IMAGOR_CACHE_HEADER_SWR="24h" # stale-while-revalidate window (default 24h)
IMAGOR_CACHE_HEADER_NO_CACHE="0" # Force no-cache headers. 0 = disabled, 1 = enabled
IMAGOR_REQUEST_TIMEOUT="30s" # Overall request timeout
IMAGOR_LOAD_TIMEOUT="20s" # Timeout for image loading
IMAGOR_SAVE_TIMEOUT="20s" # Timeout for saving images
IMAGOR_PROCESS_TIMEOUT="20s" # Timeout for image processing
IMAGOR_PROCESS_CONCURRENCY="4" # Max concurrent processing jobs (-1 = unlimited)
IMAGOR_PROCESS_QUEUE_SIZE="100" # Queue size before returning 429
IMAGOR_BASE_PATH_REDIRECT="https://example.com/docs" # Redirect root path to docs
IMAGOR_MODIFIED_TIME_CHECK="0" # Enable modified time check on source images
IMAGOR_DISABLE_PARAMS_ENDPOINT="0" # Disable /params endpoint
IMAGOR_DISABLE_ERROR_BODY="0" # Disable response body for errors
SERVER_ADDRESS=":8000" # Address to bind server
SERVER_CORS="1" # Enable CORS
SERVER_STRIP_QUERY_STRING="0" # Strip query string from URL via redirect
SERVER_PATH_PREFIX="/img" # Prefix for all routes (e.g. /img)
SERVER_ACCESS_LOG="1" # Enable HTTP access logging
PROMETHEUS_BIND=":9000" # Prometheus metrics bind address
PROMETHEUS_PATH="/metrics" # Prometheus metrics path
SENTRY_DSN="" # Sentry DSN to report errors
# HTTP Loader
HTTP_LOADER_ALLOWED_SOURCES="*.github.com,*.google.com" # Allowlist for remote sources (glob patterns)
HTTP_LOADER_BASE_URL="https://example.com/images" # Base URL to prepend for relative paths
HTTP_LOADER_FORWARD_HEADERS="Authorization,X-Custom" # Forward selected headers to source
HTTP_LOADER_OVERRIDE_RESPONSE_HEADERS="Cache-Control" # Copy selected headers from source response
HTTP_LOADER_FORWARD_CLIENT_HEADERS="User-Agent" # Forward client headers to source
HTTP_LOADER_INSECURE_SKIP_VERIFY_TRANSPORT="0" # Skip TLS verification (not safe for prod)
HTTP_LOADER_MAX_ALLOWED_SIZE="20971520" # Max allowed download size (20MB)
HTTP_LOADER_PROXY_URLS="http://proxy:8080" # Proxy URLs, comma-separated
HTTP_LOADER_ALLOWED_SOURCE_REGEXP="^https://images.example.com/.*$" # Regex allowlist for sources
HTTP_LOADER_PROXY_ALLOWED_SOURCES="*.restricted.com" # Sources that must go through proxy
HTTP_LOADER_DEFAULT_SCHEME="https" # Default scheme if none provided
HTTP_LOADER_ACCEPT="image/*" # Force Accept header and validate Content-Type
HTTP_LOADER_BLOCK_LINK_LOCAL_NETWORKS="1" # Block link-local IPs
HTTP_LOADER_BLOCK_LOOPBACK_NETWORKS="1" # Block 127.0.0.0/8 etc.
HTTP_LOADER_BLOCK_PRIVATE_NETWORKS="1" # Block 10.0.0.0/8, 192.168.0.0/16
HTTP_LOADER_BLOCK_NETWORKS="" # Custom blocked CIDRs (comma-separated)
HTTP_LOADER_DISABLE="0" # Disable HTTP loader completely
# File Loader / Storage
FILE_SAFE_CHARS="/" # Safe characters not escaped in file paths
FILE_LOADER_BASE_DIR="/mnt/data" # Base directory for file loader
FILE_LOADER_PATH_PREFIX="source" # Path prefix under base dir for file loader
FILE_STORAGE_BASE_DIR="/mnt/data" # Base directory for storage
FILE_STORAGE_PATH_PREFIX="original" # Path prefix under base dir
FILE_STORAGE_MKDIR_PERMISSION="0755" # mkdir permissions
FILE_STORAGE_WRITE_PERMISSION="0644" # file write permissions
FILE_STORAGE_EXPIRATION="168h" # TTL for storage files (7 days)
FILE_RESULT_STORAGE_BASE_DIR="/mnt/data/result" # Base dir for result storage
FILE_RESULT_STORAGE_PATH_PREFIX="processed" # Prefix under base dir
FILE_RESULT_STORAGE_MKDIR_PERMISSION="0755" # mkdir permissions
FILE_RESULT_STORAGE_WRITE_PERMISSION="0644" # file write permissions
FILE_RESULT_STORAGE_EXPIRATION="168h" # TTL for result storage
# AWS
AWS_ACCESS_KEY_ID="minio" # Global AWS access key
AWS_SECRET_ACCESS_KEY="minio123" # Global AWS secret key
AWS_REGION="us-east-1" # Default AWS region
AWS_SESSION_TOKEN="" # Optional session token
S3_ENDPOINT="http://minio:9000" # Custom endpoint for S3-compatible storage
S3_FORCE_PATH_STYLE="1" # Use path-style URLs instead of virtual-host style
S3_SAFE_CHARS="/" # Safe chars in S3 keys
# Loader
S3_LOADER_BUCKET="mybucket" # Bucket name for loader
S3_LOADER_BASE_DIR="source" # Optional base dir
S3_LOADER_PATH_PREFIX="images" # Optional prefix
AWS_LOADER_ACCESS_KEY_ID="" # Override credentials for loader
AWS_LOADER_SECRET_ACCESS_KEY="" # Override credentials for loader
AWS_LOADER_REGION="" # Override region for loader
AWS_LOADER_SESSION_TOKEN="" # Override session token
S3_LOADER_ENDPOINT="" # Override endpoint
# Storage
S3_STORAGE_BUCKET="mybucket" # Bucket name for storage
S3_STORAGE_BASE_DIR="original" # Optional base dir
S3_STORAGE_PATH_PREFIX="images" # Optional prefix
S3_STORAGE_ACL="public-read" # ACL (e.g. private, public-read)
S3_STORAGE_EXPIRATION="168h" # TTL for storage
AWS_STORAGE_ACCESS_KEY_ID="" # Override credentials for storage
AWS_STORAGE_SECRET_ACCESS_KEY="" # Override credentials for storage
AWS_STORAGE_REGION="" # Override region for storage
AWS_STORAGE_SESSION_TOKEN="" # Override session token
S3_STORAGE_ENDPOINT="" # Override endpoint
# Result Storage
S3_RESULT_STORAGE_BUCKET="mybucket" # Bucket name for result storage
S3_RESULT_STORAGE_BASE_DIR="processed" # Optional base dir
S3_RESULT_STORAGE_PATH_PREFIX="images" # Optional prefix
S3_RESULT_STORAGE_ACL="public-read" # ACL
S3_RESULT_STORAGE_EXPIRATION="168h" # TTL for results
AWS_RESULT_STORAGE_ACCESS_KEY_ID="" # Override credentials for result storage
AWS_RESULT_STORAGE_SECRET_ACCESS_KEY="" # Override credentials for result storage
AWS_RESULT_STORAGE_REGION="" # Override region
AWS_RESULT_STORAGE_SESSION_TOKEN="" # Override session token
S3_RESULT_STORAGE_ENDPOINT="" # Override endpoint
# Google Cloud Storage
GOOGLE_APPLICATION_CREDENTIALS="/etc/secrets/google/appcredentials.json" # Path to Google ADC JSON
GCLOUD_SAFE_CHARS="/" # Safe chars in GCS keys
GCLOUD_LOADER_BUCKET="mybucket" # Bucket name for loader
GCLOUD_LOADER_BASE_DIR="source" # Optional base dir
GCLOUD_LOADER_PATH_PREFIX="images" # Optional prefix
GCLOUD_STORAGE_BUCKET="mybucket" # Bucket name for storage
GCLOUD_STORAGE_BASE_DIR="original"
GCLOUD_STORAGE_PATH_PREFIX="images"
GCLOUD_STORAGE_ACL="publicRead" # Storage ACL (private, publicRead)
GCLOUD_STORAGE_EXPIRATION="168h"
GCLOUD_RESULT_STORAGE_BUCKET="mybucket" # Bucket name for result storage
GCLOUD_RESULT_STORAGE_BASE_DIR="processed"
GCLOUD_RESULT_STORAGE_PATH_PREFIX="images"
GCLOUD_RESULT_STORAGE_ACL="publicRead"
GCLOUD_RESULT_STORAGE_EXPIRATION="168h"
# VIPS (Image Processing)
VIPS_MAX_ANIMATION_FRAMES="1" # Limit animation frames. 1 = no animation, -1 = unlimited
VIPS_DISABLE_BLUR="0" # Disable blur filter
VIPS_DISABLE_FILTERS="blur,watermark" # Comma-separated filters to disable
VIPS_MAX_FILTER_OPS="10" # Max allowed filter operations (-1 unlimited)
VIPS_MAX_WIDTH="4096" # Max width allowed
VIPS_MAX_HEIGHT="4096" # Max height allowed
VIPS_MAX_RESOLUTION="16777216" # Max total pixels (e.g. 4096*4096)
VIPS_MOZJPEG="1" # Use mozjpeg encoder if available
VIPS_AVIF_SPEED="5" # AVIF encode speed (0=best,9=fastest)
VIPS_STRIP_METADATA="1" # Strip EXIF and metadata
VIPS_UNLIMITED="0" # Disable all safety limits (dangerous)
Template Content
shumc/imagor
shumc/imagorIMAGOR_SECRET
Secret for signing URLs. Required unless unsafe mode.
IMAGOR_UNSAFE
(true / false) Unsafe mode (no URL signature).