Deploy imagor

Fast, secure image processing server in Go — drop-in Thumbor replacement.

Deploy imagor

Just deployed

Deploy and Host imagor on Railway

imagor is a fast, secure image processing server and Go library built on libvips. Resize, crop, smart-crop, rotate, watermark, filter and convert images on the fly through a URL-based API — typically 4–8x faster than ImageMagick, with libvips streaming for parallel processing pipelines and high network throughput.

It adopts the Thumbor URL syntax, so it works as a drop-in replacement: existing image URLs and integrations keep working.

About Hosting imagor

This template deploys imagor as a single stateless HTTP service from the official shumc/imagor image. Railway builds nothing — the container starts and binds to the platform-provided PORT. A public HTTPS domain is created automatically and routed to the service, and the deployment is health-checked at /healthcheck.

A signing secret is generated automatically at deploy time. URL signing is required by default; unsigned mode is deliberately not enabled, because on a public deployment it would let any request make imagor fetch an arbitrary URL — an SSRF vector.

Because signing is on, a plain request returns 403. Generate a signed URL like this:

import hmac, hashlib, base64

def sign(path: str, secret: str) -> str:
    h = hmac.new(secret.encode(), path.encode(), hashlib.sha1)
    return base64.urlsafe_b64encode(h.digest()).decode() + '/' + path

print(sign('500x500/top/raw.githubusercontent.com/cshum/imagor/master/testdata/gopher.png', ''))

Then request https:///. SHA-256 and SHA-512 are also supported via IMAGOR_SIGNER_TYPE. Recipes for Go, PHP, Node and others are in the security docs.

Why Deploy imagor on Railway

imagor is typically 4–8x faster than the quickest ImageMagick settings and uses far less memory, because libvips processes images in a streaming fashion rather than decoding whole files into RAM. That makes a single small instance handle a large volume of transformations.

Deploying it on Railway gives you a managed HTTPS endpoint, health checks and usage-based scaling without operating a container host yourself. It is the fastest way to replace a hosted image SaaS, or to stand up an image CDN origin in front of your own storage.

If you are coming from Thumbor or Imaginary, imagor's URL-compatible syntax means your existing image URLs continue to work unchanged.

Common Use Cases

  • Image CDN origin — generate responsive variants (thumbnails, retina, format-specific) on demand behind a CDN or cache.
  • Replacing a hosted image service — Cloudinary, Imgix and similar, served from infrastructure you control, with no per-transformation billing.
  • Migrating off Thumbor — keep the same URL format and filter names, without the Python 2 legacy or the operational overhead.
  • E-commerce and marketplace catalogs — smart-crop, watermark and standardise product imagery at request time.
  • User-generated content pipelines — normalise uploads, strip metadata and produce derivatives without a batch job.
  • Media and publishing — dynamic crop and resize for editorial layouts.

Dependencies for imagor Hosting

Deployment Dependencies

  • Docker imageshumc/imagor, published by the project author. No build step required.
  • libvips — bundled inside the image; nothing to install.
  • Networking — one public HTTPS domain, routed to the service's PORT.
  • Source images — loaded over HTTP(S) by default. No database and no persistent volume are needed for this template. Add the loader/storage variables if you want imagor to read from and write to your own storage.

Configuration

This template sets five variables and nothing else. Four exist solely to make a public deployment safe, and one is the signing secret. Every other option stays on imagor's default — you can add any of the ~150 remaining settings as variables when you need them.

VariableDescription
IMAGOR_SECRETRequired. Secret for signing image URLs (HMAC). Auto-generated at deploy time; rotating it invalidates existing signed URLs.
HTTP_LOADER_BLOCK_PRIVATE_NETWORKSReject connections to private network addresses (RFC 1918 and IPv6 unique-local). Stops a crafted URL reaching services on your platform's private network. Default is off.
HTTP_LOADER_BLOCK_LOOPBACK_NETWORKSReject connections to loopback addresses. Default is off.
HTTP_LOADER_BLOCK_LINK_LOCAL_NETWORKSReject connections to link-local addresses (169.254.0.0/16). Default is off.
HTTP_LOADER_ACCEPTSet to image/* — sent as the Accept header and validated against the response Content-Type, so only images are fetched. Default is */*, which validates nothing.

Every command-line flag has an environment-variable equivalent (uppercase snake case). See the configuration reference for the full list — output formats, cache headers, timeouts, concurrency limits, VIPS_* processing limits, and the S3/GCS/filesystem loaders and storages.

Using Your Own Storage

This template is stateless. To read and write your own storage, add the loader and storage variables for S3, Google Cloud Storage or the filesystem.

Notes

  • IMAGOR_UNSAFE exists for local testing only. It disables signature verification entirely, so anyone who can reach the instance can make it fetch an arbitrary URL. If you need it temporarily, add IMAGOR_UNSAFE=1 as a variable and remove it afterwards — don't run it that way in production.
  • Built on libvips with the vipsgen bindings. Video thumbnails are available via imagorvideo.
  • Source: github.com/cshum/imagor · Docs: docs.imagor.net

Maintained by the imagor author.


Template Content

More templates in this category

View Template
Rocky Linux
Hosted Rocky Linux 9 workspace with SSH and persistent storage. 🚀

codestorm
47
View Template
Foundry Virtual Tabletop
A Self-Hosted & Modern Roleplaying Platform

Lucas
71
View Template
Letta Code Remote
Run a Letta Code agent 24/7. No inbound ports, just deploy.

Letta
51