Using libvips with Go in Docker: A Quick Setup Guide
Recently, I needed to build an image processing service that could handle both image compression and WebP conversion at scale. After evaluating several options, I chose bimg, which provides Go bindings for libvips - one of the fastest image processing libraries available.
However, getting libvips to work correctly in a Docker container turned out to be quite challenging. After spending considerable time debugging various build issues and runtime errors, I finally arrived at a reliable setup. I'm sharing this Dockerfile hoping it might save others some time.
# Build stage
FROM golang:1.20-alpine as build
WORKDIR /go/src/app
# Install build dependencies
RUN apk update && apk add --no-cache \
git \
build-base \
pkgconfig \
vips-dev
# Copy and download dependencies
COPY go.mod go.sum ./
RUN go mod download
COPY . .
# Build with CGO enabled but without static linking
ENV CGO_ENABLED=1
ENV GOOS=linux
ENV GOARCH=amd64
RUN go build -v -a -tags vips \
--ldflags="-s -w -linkmode external" \
-o app ./cmd/main.go
# Use at least version 3.20 of Alpine
FROM alpine:3.20
# Add edge repositories for latest libvips
RUN echo "https://dl-cdn.alpinelinux.org/alpine/v3.20/community" >> /etc/apk/repositories && \
echo "https://dl-cdn.alpinelinux.org/alpine/v3.20/main" >> /etc/apk/repositories
# Install runtime dependencies
RUN apk update && apk add --no-cache \
glib \
glib-dev \
util-linux
# Install image format dependencies
RUN apk add --no-cache \
libwebp \
libpng \
libjpeg-turbo \
libgomp \
tiff \
orc \
lcms2 \
libexif \
giflib
# Install vips packages
RUN apk add --no-cache \
vips \
vips-dev \
vips-tools
COPY --from=build /go/src/app/app /app
EXPOSE 8080
CMD ["/app"]Key Points
Multi-stage Build: Keeps the final image small and clean
Dynamic Linking: Avoids common static linking issues with libvips
Dependencies: Includes all common image format support


Thank you very much, fellow countryman.