A source is a place ImagePipe reads original images from: a directory, an HTTP origin, an S3 bucket, or a store of your own. Each source has a name, an adapter that reads it, match rules for which image paths reach it, and the adapter's options. Image URLs name the image after src/, and the source whose rules match it serves the request.

Routing image paths to sources

These sources serve paths under media/ from one directory, other paths from a second directory, and full HTTPS URLs from one host:

Plug

sources: [
  media: [
    adapter: ImagePipe.Source.File,
    match: [prefix: "media"],
    options: [root: "/srv/images", root_id: "media"]
  ],
  static: [
    adapter: ImagePipe.Source.File,
    match: :path,
    options: [root: "/srv/static", root_id: "static"]
  ],
  web: [
    adapter: ImagePipe.Source.HTTP,
    match: [scheme: ["http", "https"]],
    options: [allowed_hosts: ["assets.example.com"]]
  ]
]

image_pipe_server

[sources.media]
adapter = "file"
match = { prefix = "media" }
root = "/srv/images"
root_id = "media"

[sources.static]
adapter = "file"
match = "path"
root = "/srv/static"
root_id = "static"

[sources.web]
adapter = "http"
match = { scheme = ["http", "https"] }
allowed_hosts = ["assets.example.com"]

The match rules are the same on both surfaces:

RuleServesExample source
prefix mediaPaths whose first segment is media. The adapter receives the rest.media/photos/beach.jpg
pathPaths that no prefix matchesphotos/beach.jpg
scheme http, httpsHTTP and HTTPS URLshttps://assets.example.com/beach.jpg
scheme s3S3 objectss3://bucket/beach.jpg
scheme assetA custom scheme, served as a pathasset://photos/beach.jpg

prefix and scheme each take one value or a list, and one source can have both. A prefix is a single path segment. A custom scheme is another spelling of a prefix: asset://photos/beach.jpg reaches its source as the path photos/beach.jpg. Only http, https, and s3 select URL and object sources.

A prefix always wins, so the path source can't serve a top-level folder named like a prefix. Renaming a source keeps its cache entries, and sources that read the same originals can share them (see originals and processed images). The source's name appears in telemetry events as :source_name.

Requests that no source serves fail:

  • A path that no source matches answers 404 source not found, like a missing image. So does a path with nothing after its prefix or scheme, or with an empty, ., or .. segment.
  • A scheme:// URL that no source matches, including http, https, and s3, answers 400 invalid source.

The configuration fails to load when two sources claim the same prefix or scheme, when more than one source matches path, or when a source matches requests its adapter can't serve, such as a file source matching https, an S3 source matching a prefix, or an HTTP source without a base_url matching paths or a custom scheme.

Adapters

AdapterServesSetup guideOptions
Local filesA directory on the ImagePipe hostServing images from local filesImagePipe.Source.File, adapter = "file"
HTTPPaths on one origin, or URLs from listed hostsServing images from an HTTP originImagePipe.Source.HTTP, adapter = "http"
S3Objects in S3 and S3-compatible storageServing images from S3ImagePipe.Source.S3, adapter = "s3"
CustomAny store your Elixir code can readWriting a custom sourceImagePipe.Source

Every adapter also takes the cache settings in ImagePipe.Source.CacheSettings, explained in Caching and freshness. In Elixir code, ImagePipe.run/4 reads the same sources, and also takes a file or bytes that no source serves.