In this guide we'll run image_pipe_server in Docker, point it at a folder
of photos on your machine, and open resized, cropped, and converted copies of
a photo in the browser.
You need Docker, port 8080 free, and a JPEG photo.
Getting the server image
docker pull ghcr.io/hlindset/image_pipe_server:0.1
Adding a folder of images
The server reads originals from a folder and makes processed copies of them
on request. Let's create a working directory with an
images folder:
mkdir -p image-server/images
cd image-server
Copy any JPEG photo into images as photo.jpg:
cp /path/to/your/photo.jpg images/photo.jpg
The examples below use a 4000×2667 photo. With your photo, the widths match and the heights follow its proportions.
Writing the configuration
Next, we tell the server where the originals are. Create config.toml in the
image-server directory:
# config.toml
[sources.photos]
adapter = "file"
match = "path"
root = "/data/images"
root_id = "photos"This defines one source named photos. A source is a place the server reads
originals from:
adapter = "file"reads files from a directory.match = "path"sends every image path in a URL to this source.rootis that directory, as the server sees it inside the container. We mount ourimagesfolder there in the next step.root_idis a stable name for this directory.
Starting the server
Let's start the server in the background, with our configuration file and
our images folder mounted at the paths in config.toml:
docker run -d --name image-server -p 8080:8080 \
-v "$PWD/config.toml:/etc/image_pipe/config.toml:ro" \
-v "$PWD/images:/data/images:ro" \
ghcr.io/hlindset/image_pipe_server:0.1
The server reads /etc/image_pipe/config.toml at startup. Open
http://localhost:8080/health/ready in your browser. Within a second or two it
shows:
okIf the page doesn't load, the server didn't start. A mistake in
config.toml stops it. Check its log:
docker logs image-server
The log ends with a line that names the setting. Leaving out match, for
example, ends the log with:
invalid configuration: sources.photos.match: requiredFix config.toml, remove the stopped container with
docker rm image-server, and run the docker run command again.
Resizing an image
An image URL lists processing options, then src/, then the image's path in
the source. Let's ask for photo.jpg at 400 pixels wide. Open this URL:
http://localhost:8080/w=400/src/photo.jpg
GET /w=400/src/photo.jpg (in Chrome)
200 OK, content-type: image/avif, 400×267The browser's tab title shows the size, 400×267. Notice that:
src/photo.jpgis/data/images/photo.jpgin thephotossource, which isimages/photo.jpgon your machine. A photo in a subfolder,images/trips/beach.jpg, issrc/trips/beach.jpg.w=400sets only the width. The height follows the photo's proportions.- The original is a JPEG, but Chrome got AVIF, as its developer tools show.
Without a
formatoption, the server picks AVIF or WebP when the browser asks for one of them. A client that asks for neither, such ascurl, gets a JPEG.
Now change w=400 to w=800:
http://localhost:8080/w=800/src/photo.jpg
GET /w=800/src/photo.jpg
200 OK, content-type: image/avif, 800×533Files you add to images can be requested right away, without restarting
the server.
If a request fails, the status and body say why:
404withsource not found: the file name is mistyped.400withinvalid transformation options: the URL leaves outsrc/, as in/w=400/photo.jpg. The body ends withmissing src/, src64/, or enc/ before the image path.500withsource unavailable: the server can't read the file, for example because only your user can read it. Make it readable withchmod a+r images/photo.jpg.
Fitting an image in a box
With both a width and a height, the server fits the photo inside that box:
http://localhost:8080/w=300/h=300/src/photo.jpg
GET /w=300/h=300/src/photo.jpg
200 OK, content-type: image/avif, 300×200Notice that the result is 300×200, not 300×300. By default the whole photo
stays visible, so the wide photo fills the box's width and leaves its height
short. Add fit=cover to fill the box instead:
http://localhost:8080/w=300/h=300/fit=cover/src/photo.jpg
GET /w=300/h=300/fit=cover/src/photo.jpg
200 OK, content-type: image/avif, 300×300The photo now covers the whole 300×300 square, and the parts that don't fit are cropped off both sides, keeping the center.
The order of options doesn't matter: fit=cover/h=300/w=300 gives the same
image. An unknown value gets a 400, and the body points at the problem.
With fit=fill:
invalid transformation options
/w=300/h=300/fit=fill/src/photo.jpg
^^^^
|
invalid value: expected contain, cover, stretch, or autoChoosing the output format
To get the same format whatever the browser accepts, add format:
http://localhost:8080/w=300/h=300/fit=cover/format=png/src/photo.jpg
GET /w=300/h=300/fit=cover/format=png/src/photo.jpg
200 OK, content-type: image/png, 300×300format also takes webp, avif, and jpeg.
When you're done, stop and remove the container:
docker rm -f image-server
Next steps
We ran the server against a folder of originals and requested resized, cropped, and converted copies by URL. From here:
- Requesting images: how URLs are built, option values, presets, and error responses.
- Resize and layout: every
fitmode, pixel density, and padding. The processing options page lists the other categories. - Configuring image_pipe_server: environment
variables and every setting in
config.toml, including HTTP and S3 sources. - Deploying image_pipe_server: caches, a read-only filesystem, health checks, Docker Compose, and Kubernetes.
Before exposing the server, set up URL signing with the
[url] keys setting.
Building URLs for the server
shows the application side, which signs the URLs.