Go Docker Alpine

Product: pdftron-go

Product Version: github.com/pdftron/pdftron-go/v2

Please give a brief summary of your issue: Build go project in Alpine linux

Please describe your issue and provide steps to reproduce it:
What is the instruction to build Apryse server SDK in Go project using alpine image?

Please provide a link to a minimal sample where the issue is reproducible:
This is my docker file

FROM golang:1.23-alpine

WORKDIR /app

COPY go.mod go.sum ./
RUN go mod download

COPY . .

RUN go build -o server .

EXPOSE 8080

CMD ["./server"]

I’m getting this error:

=> ERROR [6/6] RUN go build -o server .                                                                                                                                          0.6s
------                                                                                                                                                                                 
 > [6/6] RUN go build -o server .:                                                                                                                                                     
0.568 package pdf-annotates-location                                                                                                                                                   
0.568   imports pdf-annotates-location/pdf
0.568   imports github.com/pdftron/pdftron-go/v2: build constraints exclude all Go files in /go/pkg/mod/github.com/pdftron/pdftron-go/v2@v2.3.3
------
Dockerfile:10
--------------------
   8 |     COPY . .
   9 |     
  10 | >>> RUN go build -o server .
  11 |     
  12 |     EXPOSE 8080
--------------------
ERROR: failed to solve: process "/bin/sh -c go build -o server ." did not complete successfully: exit code: 1

imports github.com/pdftron/pdftron-go/v2: build constraints exclude all Go files in /go/pkg/mod/github.com/pdftron/pdftron-go/v2@v2.3.3

The “build constraints exclude …” can be several issues but I think the most common is that the system file permissions are not allowing the user to access the go pkg folder “/go/pkg/mod/github.com/pdftron/pdftron-go/v2@v2.3.3”. You can see the same result testing in a local Linux instance running the Apryse SDK GO examples by running:

go install github.com/pdftron/pdftron-go/v2@2.3.3

And running the included tests as a non root user. You will need to adjust the permissions for your specific user.

I’ve updated my Dockerfile

FROM golang:1.23.4-alpine

# Set the working directory inside the container
WORKDIR /app

RUN apk update && apk add --no-cache gcc libc-dev g++

# Copy the Go module files and install dependencies
COPY go.mod go.sum ./
RUN go mod download

# Copy the source code into the container
COPY . .

# Build the Go app
RUN CGO_ENABLED=1 go build -o apryse ./cmd/test/main.go

But I’ve got new error

/usr/lib/gcc/x86_64-alpine-linux-musl/14.2.0/…/…/…/…/x86_64-alpine-linux-musl/bin/ld: /go/pkg/mod/github.com/pdftron/pdftron-go/v2@v2.4.1/shared_libs/unix_x86_64/Lib/libPDFNetC.so: undefined reference to `longjmp@GLIBC_2.2.5’

It looks like this is the problem with glibc in Alpine Linux, According to this page Apryse SDK can run on Alpine Linux, can you please let me know what dependencies I need to install to be able to compile my code?

1 Like

We do not maintain a list of what dependencies need to be installed for specific Linux distributions. What you can do is run ldd on libPDFNetC.so to list any missing required shared objects.

1 Like

Does the Go SDK work with Alpine Linux? if it does can you provide a Dockerfile example?

We’re using golang:1.24-bookworm and the image size is huge: 2.83GB

FROM golang:1.24-bookworm

# Set the working directory
WORKDIR /app

# Copy Go module files and download dependencies first to leverage Docker cache
COPY go.mod go.sum ./
RUN go mod download

# Copy the rest of the source code
COPY . .

# Build the application as a static binary
RUN GOOS=linux GOARCH=amd64 go build -o app-binary ./main.go

CMD [ "./app-binary" ]

Does the Go SDK work with Alpine Linux? if it does can you provide a Dockerfile example?
Yes. Alpine is included in the normal Go package and will work the same as any other Go package. We do not maintain Dockerfile(s) for different Linux distributions. You should be able to generate one and install required dependencies as other distributions.

Yes. Alpine is included in the normal Go package and will work the same as any other Go package.

Correct me if I’m wrong, but I don’t believe it’s included with Go package, I’ve downloaded the Go package https://github.com/ApryseSDK/pdftron-go and run ldd on all shared_libs but I don’t see libc.musl as dependency like Alpine C++ SDK

PDFNetC64/Lib/libPDFNetC.so

  1. linux-vdso.so.1
  2. libc.musl-x86_64.so.1

pdftron-go-2.4.5/shared_libs/unix/Lib/libPDFNetC.so

  1. linux-vdso.so.1
  2. librt.so.1
  3. libdl.so.2
  4. libpthread.so.0
  5. libm.so.6
  6. libc.so.6
  7. /lib64/ld-linux-x86-64.so.2

pdftron-go-2.4.5/shared_libs/unix_aarch64/Lib/libPDFNetC.so: not a dynamic executable

pdftron-go-2.4.5/shared_libs/unix_x86_64/Lib/libPDFNetC.so

  1. linux-vdso.so.1
  2. librt.so.1
  3. libdl.so.2
  4. libpthread.so.0
  5. libm.so.6
  6. libc.so.6
  7. /lib64/ld-linux-x86-64.so.2

in my case I’m able to reduce the image size to 151MB by using multi stages build, here is my Dockerfile

# Use a Debian-based Go image which includes glibc. Name this stage "builder".
FROM golang:1.24-bookworm AS builder

# Set the working directory
WORKDIR /app

# Install build-essential which contains C/C++ compilers and related tools
RUN apt-get update && apt-get install -y build-essential

# Copy Go module files and download dependencies first to leverage Docker cache
COPY go.mod go.sum ./
RUN go mod download

# Copy the rest of the source code
COPY . .

# Build the application as a dynamically linked binary
# The CGO_ENABLED=1 is implicitly set when using cgo, but it's good to be explicit.
RUN CGO_ENABLED=1 go build -o app-binary ./main.go

# --- Second Stage ---
# Use a distroless base image for a smaller and more secure final image.
# This image contains glibc and can run dynamically linked binaries.
# Use the distroless "cc" image which includes C/C++ runtime libraries like libstdc++.so.6.
FROM gcr.io/distroless/cc-debian12

# Set the working directory
WORKDIR /app

# Copy the binary from the builder stage
COPY --from=builder /app/app-binary /app/app-binary

# Copy the required shared libraries from the pdftron package into a dedicated directory
COPY --from=builder /go/pkg/mod/github.com/pdftron/pdftron-go/v2@v2.4.5/shared_libs/unix_x86_64/Lib/ /pdftron/lib/

# Set the library path so the binary can find the shared libraries at runtime
ENV LD_LIBRARY_PATH=/pdftron/lib/

CMD ["./app-binary"]