---
title: "Deploy imagor"
description: "Fast, secure image processing server in Go — drop-in Thumbor replacement."
category: "Other"
url: https://railway.com/deploy/imagor
---

# Deploy imagor

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

**[Deploy imagor on Railway](https://railway.com/template/imagor)**

Machine-readable deploy manifest (JSON, validated by TemplateCI): https://railway.com/deploy/imagor/manifest.json

- **Creator:** Adrian Shum
- **Category:** Other

## Template content

### imagor https://docs.imagor.net/img/icon.png

- **Image:** shumc/imagor:1.9.6
- **Health check:** /healthcheck
- **Public domain:** Yes

## Documentation

# 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:

```python
import hmac, hashlib, base64

def sign(path: str, secret: str) -&gt; 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](https://docs.imagor.net/security).

## 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 image** — `shumc/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.

| Variable | Description |
| --- | --- |
| `IMAGOR_SECRET` | Required. Secret for signing image URLs (HMAC). Auto-generated at deploy time; rotating it invalidates existing signed URLs. |
| `HTTP_LOADER_BLOCK_PRIVATE_NETWORKS` | Reject 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_NETWORKS` | Reject connections to loopback addresses. Default is off. |
| `HTTP_LOADER_BLOCK_LINK_LOCAL_NETWORKS` | Reject connections to link-local addresses (169.254.0.0/16). Default is off. |
| `HTTP_LOADER_ACCEPT` | Set 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](https://docs.imagor.net/configuration) 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](https://docs.imagor.net/storage-s3), [Google Cloud Storage](https://docs.imagor.net/storage-gcloud) or the [filesystem](https://docs.imagor.net/storage-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](https://github.com/cshum/vipsgen) bindings. Video thumbnails are available via [imagorvideo](https://github.com/cshum/imagorvideo).
- Source: [github.com/cshum/imagor](https://github.com/cshum/imagor) · Docs: [docs.imagor.net](https://docs.imagor.net)

---

Maintained by the imagor author.


## Similar templates

- [Rocky Linux](https://railway.com/deploy/rocky-linux) — Hosted Rocky Linux 9 workspace with SSH and persistent storage. 🚀
- [Foundry Virtual Tabletop](https://railway.com/deploy/X5tR6G) — A Self-Hosted & Modern Roleplaying Platform
- [Letta Code Remote](https://railway.com/deploy/letta-code-remote) — Run a Letta Code agent 24/7. No inbound ports, just deploy.

Open this page in a browser: https://railway.com/deploy/imagor
