davidbyttow / govips

A lightning fast image processing and resizing library for Go

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Ubuntu: Unable to locate `libvips.42.so` on application startup

tylermmorton opened this issue · comments

Hi! So far I've been using govips locally on my Intel Mac and it's been great. I started experiencing a lot of thorny issues when I went to package my application up for deployment, though. Perhaps this is due to my inexperience using C/C++ libraries within ubuntu images but this is the error I've been stuck on for a while:

error while loading shared libraries: libvips.so.42: cannot open shared object file: No such file or directory

I've done a lot of digging and I've attempted everything I can think of minus building from source.

Any additional resources or things to try would be much appreciated. TYIA!

# The base image is a ubuntu image with Homebrew pre-installed.
FROM homebrew/brew:latest as base
RUN brew update-reset

FROM base as base-apt-install
RUN sudo apt update
RUN sudo apt install build-essential -y --no-install-recommends
RUN sudo apt install software-properties-common -y --no-install-recommends

# https://github.com/davidbyttow/govips#ubuntu
RUN sudo add-apt-repository -y ppa:strukturag/libde265
RUN sudo add-apt-repository -y ppa:strukturag/libheif

RUN sudo apt install libvips -y --no-install-recommends
RUN sudo apt install libvips42 -y --no-install-recommends
RUN sudo apt install libvips-dev -y --no-install-recommends

# Install all system-level dependencies using brew
FROM base-apt-install as base-brew-install
WORKDIR /src

COPY Brewfile Brewfile.lock.json ./
RUN brew bundle

# Create a workspace for the project and assign permissions
FROM base-brew-install as base-workspace
USER root
RUN mkdir -p /src
RUN chmod +rwx /src
RUN git config --global --add safe.directory '/src'
WORKDIR /src

RUN sudo ldconfig

FROM base-workspace as go-install
WORKDIR /src
COPY go.mod go.sum ./

RUN go mod download

ENV PATH="/root/go/bin:$PATH"
RUN go install github.com/tylermmorton/tmpl/cmd/tmpl@latest

FROM go-install as go-build
WORKDIR /src
COPY . .

ENV GOOS=linux
ENV GO111MODULE=on
ENV CGO_ENABLED=1
ENV CGO_CFLAGS_ALLOW="-Xpreprocessor"

RUN go generate ./...
RUN go build -v -o ./.build/bin/app ./app
RUN chmod +x ./.build/bin/app

FROM ubuntu:latest as production
COPY --from=go-build /src/.build/bin/app /bin/app

EXPOSE 8080
ENTRYPOINT [ "/bin/app" ]

Brewfile:

brew "node"
brew "golang"
brew "go-task"
# https://github.com/davidbyttow/govips
brew "vips"
brew "pkg-config"

Turns out I missed something obvious. None of the shared libraries were being copied to the production image. Here's an updated docker container:

# The base image is a ubuntu image with Homebrew pre-installed.
FROM homebrew/brew:latest as base
RUN brew update-reset
# HOMEBREW_DIR is the directory where Homebrew is installed.
ENV HOMEBREW_DIR=/home/linuxbrew/.linuxbrew

# Install all system-level dependencies using brew
FROM base as base-brew-install
WORKDIR /src

COPY Brewfile Brewfile.lock.json ./
RUN brew bundle

# Create a workspace for the project and assign permissions
FROM base-brew-install as base-workspace
USER root
RUN mkdir -p /src
RUN chmod +rwx /src
RUN git config --global --add safe.directory '/src'
WORKDIR /src

ENV CGO_ENABLED=1
ENV CGO_CFLAGS_ALLOW="-Xpreprocessor"
ENV CGO_CFLAGS="-I${HOMEBREW_DIR}/include"
ENV CGO_LDFLAGS="-L${HOMEBREW_DIR}/lib"
ENV GOOS=linux
ENV GO111MODULE=on
ENV JS_MINIFY=true
ENV JS_TREE_SHAKING=true
ENV PATH="/root/go/bin:$PATH"
ENV PKG_CONFIG_PATH="${PKG_CONFIG_PATH}:${HOMEBREW_DIR}/lib/pkgconfig"

RUN sudo ldconfig -v

# Install all Go dependencies
FROM base-workspace as go-install
WORKDIR /src
COPY go.mod go.sum ./

RUN go mod download
# TODO: implement module vendoring

RUN go install github.com/matryer/moq@latest
RUN go install github.com/tylermmorton/tmpl/cmd/tmpl@latest

# Build the Go binary
FROM go-install as go-build
WORKDIR /src
COPY . .

RUN go generate ./...
RUN go build -v -o ./.build/bin/app ./app
RUN chmod +x ./.build/bin/app

RUN ls -la ./.build
RUN ls -la ./.build/bin

# Build the production image
FROM ubuntu:latest as prod-base
RUN apt update
RUN apt install libvips -y --no-install-recommends

FROM prod-base as prod
COPY --from=go-build /src/.build/bin/app /bin/app

EXPOSE 8080
ENTRYPOINT [ "/bin/app" ]

I tried using base-workspace with all of the pre-installed homebrew dependencies as the starting point for the production image but the final product ended up being 5GB in size. Instead I added apt install libvips to a base ubuntu image. The application is able to start now, at least.