From f086cb2284ea6473a69ec28158ac8f337b826e67 Mon Sep 17 00:00:00 2001 From: Gus Date: Mon, 13 Oct 2025 15:05:46 +0800 Subject: [PATCH 1/6] Handle webp encoding without cgo --- pkg/images/image.go | 4 +--- pkg/images/image_test.go | 4 ++++ pkg/images/webp_encode_cgo.go | 19 +++++++++++++++++++ pkg/images/webp_encode_stub.go | 17 +++++++++++++++++ 4 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 pkg/images/webp_encode_cgo.go create mode 100644 pkg/images/webp_encode_stub.go diff --git a/pkg/images/image.go b/pkg/images/image.go index c7da413a..b84a639b 100644 --- a/pkg/images/image.go +++ b/pkg/images/image.go @@ -26,7 +26,6 @@ import ( _ "golang.org/x/image/webp" "github.com/andybalholm/brotli" - "github.com/chai2010/webp" "github.com/gen2brain/avif" "github.com/klauspost/compress/zstd" ) @@ -533,8 +532,7 @@ func Save(path string, img stdimage.Image, ext string, quality int) error { encoder := &png.Encoder{CompressionLevel: png.DefaultCompression} return encoder.Encode(fh, img) case ".webp": - options := &webp.Options{Lossless: false, Quality: float32(quality)} - return webp.Encode(fh, img, options) + return encodeWebp(fh, img, quality) default: options := &jpeg.Options{Quality: quality} return jpeg.Encode(fh, img, options) diff --git a/pkg/images/image_test.go b/pkg/images/image_test.go index 417f6ce0..53bedd7c 100644 --- a/pkg/images/image_test.go +++ b/pkg/images/image_test.go @@ -867,6 +867,10 @@ func TestSaveJPEG(t *testing.T) { func TestSaveWebP(t *testing.T) { t.Parallel() + if !webpEncodeSupported() { + t.Skip("webp encoding requires cgo") + } + dir := t.TempDir() path := filepath.Join(dir, "photo.webp") diff --git a/pkg/images/webp_encode_cgo.go b/pkg/images/webp_encode_cgo.go new file mode 100644 index 00000000..7fe24062 --- /dev/null +++ b/pkg/images/webp_encode_cgo.go @@ -0,0 +1,19 @@ +//go:build cgo + +package images + +import ( + stdimage "image" + "io" + + "github.com/chai2010/webp" +) + +func encodeWebp(w io.Writer, img stdimage.Image, quality int) error { + options := &webp.Options{Lossless: false, Quality: float32(quality)} + return webp.Encode(w, img, options) +} + +func webpEncodeSupported() bool { + return true +} diff --git a/pkg/images/webp_encode_stub.go b/pkg/images/webp_encode_stub.go new file mode 100644 index 00000000..a022cc8b --- /dev/null +++ b/pkg/images/webp_encode_stub.go @@ -0,0 +1,17 @@ +//go:build !cgo + +package images + +import ( + "errors" + stdimage "image" + "io" +) + +func encodeWebp(w io.Writer, img stdimage.Image, quality int) error { + return errors.New("webp encoding requires cgo support") +} + +func webpEncodeSupported() bool { + return false +} From e1639d6984fb0104dd7287db8fd20b13f24fe6f8 Mon Sep 17 00:00:00 2001 From: Gus Date: Mon, 13 Oct 2025 15:17:10 +0800 Subject: [PATCH 2/6] Use blank identifiers in WebP stub --- pkg/images/webp_encode_stub.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/images/webp_encode_stub.go b/pkg/images/webp_encode_stub.go index a022cc8b..098d5157 100644 --- a/pkg/images/webp_encode_stub.go +++ b/pkg/images/webp_encode_stub.go @@ -8,7 +8,7 @@ import ( "io" ) -func encodeWebp(w io.Writer, img stdimage.Image, quality int) error { +func encodeWebp(_ io.Writer, _ stdimage.Image, _ int) error { return errors.New("webp encoding requires cgo support") } From 6e901d79c087a60f32c603460d0d68747b19c949 Mon Sep 17 00:00:00 2001 From: Gus Date: Mon, 13 Oct 2025 15:17:19 +0800 Subject: [PATCH 3/6] Enable CGO WebP build deps in Dockerfile --- docker/dockerfile-api | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/docker/dockerfile-api b/docker/dockerfile-api index 2c16fd63..5ccb1686 100644 --- a/docker/dockerfile-api +++ b/docker/dockerfile-api @@ -41,10 +41,17 @@ ARG BINARY_NAME ARG APP_VERSION ARG BUILD_TAGS +# Install system dependencies required to build with CGO and libwebp support. +RUN apk add --no-cache \ + build-base \ + pkgconfig \ + libwebp-dev + # Configure Go build cache and module cache under our APP_DIR. ENV GOPATH=${APP_DIR}/.gopath ENV GOMODCACHE=${APP_DIR}/.gopath/pkg/mod ENV GOCACHE=${APP_DIR}/.gocache +ENV CGO_ENABLED=1 # Create the Go module & build cache directories. RUN mkdir -p ${GOMODCACHE} ${GOCACHE} @@ -59,14 +66,13 @@ RUN go mod download # Copy remaining source code into the builder. COPY . . -# Compile a statically-linked binary. +# Compile the application binary with CGO enabled so WebP encoding is available. # -# * CGO_ENABLED=0: disable CGO for static builds. # * -tags: apply build tags. # * -o: output binaries path/name. # * -ldflags: strip symbols and inject version. # -RUN CGO_ENABLED=0 go build \ +RUN go build \ -tags "${BUILD_TAGS}" \ -o ${APP_DIR}/${BINARY_NAME} \ -ldflags="-s -w -X main.Version=${APP_VERSION}" \ @@ -89,8 +95,8 @@ ARG MEDIA_DIR ARG FIXTURES_DIR ARG APP_HOST_PORT -# Install timezone data so Go’s time.* functions work correctly. -RUN apk add --no-cache tzdata +# Install timezone data and runtime dependencies for the CGO-enabled binary. +RUN apk add --no-cache tzdata libwebp ENV TZ=Asia/Singapore # Create the system group for our non-root user. From f3e3b52142350969648c7d5a665df004d8bd851f Mon Sep 17 00:00:00 2001 From: Gus Date: Mon, 13 Oct 2025 15:28:18 +0800 Subject: [PATCH 4/6] Pin Alpine package versions for WebP support --- docker/dockerfile-api | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docker/dockerfile-api b/docker/dockerfile-api index 5ccb1686..ca24d224 100644 --- a/docker/dockerfile-api +++ b/docker/dockerfile-api @@ -43,9 +43,9 @@ ARG BUILD_TAGS # Install system dependencies required to build with CGO and libwebp support. RUN apk add --no-cache \ - build-base \ - pkgconfig \ - libwebp-dev + build-base=0.5-r3 \ + pkgconf=2.4.3-r0 \ + libwebp-dev=1.5.0-r0 # Configure Go build cache and module cache under our APP_DIR. ENV GOPATH=${APP_DIR}/.gopath @@ -96,7 +96,7 @@ ARG FIXTURES_DIR ARG APP_HOST_PORT # Install timezone data and runtime dependencies for the CGO-enabled binary. -RUN apk add --no-cache tzdata libwebp +RUN apk add --no-cache tzdata=2025b-r0 libwebp=1.5.0-r0 ENV TZ=Asia/Singapore # Create the system group for our non-root user. From 54a8b04b605c0884fa9430b81dde4b9d8ad5d6dd Mon Sep 17 00:00:00 2001 From: Gus Date: Mon, 13 Oct 2025 15:32:21 +0800 Subject: [PATCH 5/6] Allow Docker timezone override --- docker/dockerfile-api | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docker/dockerfile-api b/docker/dockerfile-api index ca24d224..2ecd69e9 100644 --- a/docker/dockerfile-api +++ b/docker/dockerfile-api @@ -29,6 +29,7 @@ ARG STORAGE_DIR=storage ARG LOGS_DIR=logs ARG MEDIA_DIR=media ARG FIXTURES_DIR=fixture +ARG TZ=UTC # ---------------------------------------------------------------------------------------------------------------------- # BUILDER STAGE @@ -95,9 +96,12 @@ ARG MEDIA_DIR ARG FIXTURES_DIR ARG APP_HOST_PORT +# Timezone configuration (default to UTC for broad compatibility). +ARG TZ=UTC + # Install timezone data and runtime dependencies for the CGO-enabled binary. RUN apk add --no-cache tzdata=2025b-r0 libwebp=1.5.0-r0 -ENV TZ=Asia/Singapore +ENV TZ=${TZ} # Create the system group for our non-root user. RUN addgroup -S ${APP_GROUP} From 296b715fbb177799daac4367385012b3a1012734 Mon Sep 17 00:00:00 2001 From: Gus Date: Mon, 13 Oct 2025 15:39:28 +0800 Subject: [PATCH 6/6] Default TZ to Asia/Singapore --- docker/dockerfile-api | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docker/dockerfile-api b/docker/dockerfile-api index 2ecd69e9..f8e170cd 100644 --- a/docker/dockerfile-api +++ b/docker/dockerfile-api @@ -29,7 +29,7 @@ ARG STORAGE_DIR=storage ARG LOGS_DIR=logs ARG MEDIA_DIR=media ARG FIXTURES_DIR=fixture -ARG TZ=UTC +ARG TZ=Asia/Singapore # ---------------------------------------------------------------------------------------------------------------------- # BUILDER STAGE @@ -96,8 +96,8 @@ ARG MEDIA_DIR ARG FIXTURES_DIR ARG APP_HOST_PORT -# Timezone configuration (default to UTC for broad compatibility). -ARG TZ=UTC +# Timezone configuration (default to Asia/Singapore). +ARG TZ=Asia/Singapore # Install timezone data and runtime dependencies for the CGO-enabled binary. RUN apk add --no-cache tzdata=2025b-r0 libwebp=1.5.0-r0