Headless GIMP in Docker for Server-Side Rendering
Running the GNU Image Manipulation Program (GIMP) in a headless Docker container enables scalable, automated image processing pipelines on servers without physical displays. This guide outlines the essential steps to containerize GIMP, configure a virtual framebuffer using Xvfb to satisfy display requirements, write batch processing scripts, and execute automated rendering jobs through Docker commands.
1. Create the Dockerfile
GIMP relies on an X display server even when executing commands in
non-interactive batch mode. To run it headlessly, you must install GIMP
alongside xvfb (X Virtual Framebuffer) on a lightweight
Linux base image such as Debian or Ubuntu.
Create a file named Dockerfile:
FROM ubuntu:22.04
ENV DEBIAN_FRONTEND=noninteractive
# Install GIMP, Xvfb, and required dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
gimp \
xvfb \
python3 \
dbus-x11 \
&& rm -rf /var/lib/apt/lists/*
# Set up working directory
WORKDIR /workspace
# Create an entrypoint script
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]2. Configure the Headless Entrypoint Script
The entrypoint script starts an in-memory virtual display, exports
the DISPLAY environment variable, runs the GIMP batch
command, and cleanly terminates the virtual server when rendering
completes.
Create a file named entrypoint.sh:
#!/usr/bin/env bash
set -e
# Start Xvfb in the background on display :99
Xvfb :99 -screen 0 1024x768x24 -nolisten tcp &
XVFB_PID=$!
export DISPLAY=:99
# Execute passed arguments or default batch command
if [ "$#" -gt 0 ]; then
"$@"
else
echo "No command provided to GIMP container."
fi
# Terminate Xvfb
kill $XVFB_PID3. Write a GIMP Batch Script
GIMP accepts automation scripts via Script-Fu (Scheme) or Python-Fu. For simple server-side rendering, Script-Fu allows direct interaction via the command line without extra plugin configurations.
Create a sample Script-Fu file named render.scm:
(define (server-side-render filename output)
(let* ((image (car (gimp-file-load RUN-NONINTERACTIVE filename filename)))
(drawable (car (gimp-image-get-active-layer image))))
;; Apply an example filter: invert colors
(gimp-drawable-invert drawable FALSE)
;; Save and clean up
(gimp-file-save RUN-NONINTERACTIVE image drawable output output)
(gimp-image-delete image)))4. Build the Docker Image
Compile the container image using the Docker CLI:
docker build -t headless-gimp .5. Execute Automated Server-Side Rendering
Run the container using volume mounts to pass input assets to the container and retrieve processed output files.
Use GIMP's command-line flags:
-i: Runs GIMP non-interactively without graphical user interface windows.-b: Specifies the batch command to run or loads a custom Script-Fu expression.-b '(gimp-quit 0)': Ensures the GIMP process exits upon completion.
Execute the following command to render an image:
docker run --rm \
-v $(pwd)/workspace:/workspace \
headless-gimp \
gimp -i -b '(server-side-render "input.png" "output.png")' -b '(gimp-quit 0)'When integrating this into an automated CI/CD or cloud workflow,
mount cloud-storage buckets or network volumes into the
/workspace directory, allowing GIMP to pull source media
and output rendered artifacts programmatically.