Search code examples
.netdockerdockerfilelightgbmml.net

Unable to load shared library 'lib_lightgbm' or one of its dependencies with Docker and ML.NET


I am using ML.NET to train and create models with different algorithms. When I test the method locally on windows it works fine But when I run it with Docker this error comes up: System.DllNotFoundException: Unable to load shared library 'lib_lightgbm' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: liblib_lightgbm: cannot open shared object file: No such file or directory. This is my Dockerfile:


#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.

FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src

# Install dependencies for LightGBM
RUN apt-get update
RUN apt-get install git clang-3.9 cmake libunwind8 curl -y 
RUN apt-get install -y libomp-dev

# Clone the LightGBM repository
RUN git clone --recursive https://github.com/microsoft/LightGBM /src/LightGBM 

# Build LightGBM
WORKDIR /src/LightGBM
RUN mkdir build && cd build && cmake .. && make -j4


COPY /src/LightGBM/* /usr/lib/
RUN rm -rf /src/LightGBM

COPY ["MAS/MAS.csproj", "MAS/"]
COPY ["DAL/DAL.csproj", "DAL/"]
COPY ["Domain/Domain.csproj", "Domain/"]
COPY ["DI/DI.csproj", "DI/"]
COPY ["Notification/Notification.csproj", "Notification/"]

RUN dotnet restore "MAS/MAS.csproj"
COPY . .
WORKDIR "/src/MAS"
RUN dotnet build "MAS.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "MAS.csproj" -c Release -o /app/publish /p:UseAppHost=false

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .

COPY ["MAS/Configs/api-mappings.json", "Configs/"] 
ENV LD_DEBUG=all


ENTRYPOINT ["dotnet", "MAS.dll"]

I am very new to the Docker world. I added this commands on the Dockerfile and it didnt work:

RUN apt-get update && apt-get install -y build-essential cmake git

# Clone the lib_lightgbm repository and build it
RUN git clone https://github.com/microsoft/LightGBM.git && \
    cd LightGBM && mkdir build && cd build && \
    cmake .. && make -j`

Then on Docker Desktop on the terminal I installed it with the same commands:

apt-get update && apt-get install -y build-essential cmake git

# Clone the lib_lightgbm repository and build it
git clone https://github.com/microsoft/LightGBM.git && \
    cd LightGBM && mkdir build && cd build && \
    cmake .. && make -j`

It created a folder named LightGBM on my solution but it still didn't work. The same error comes up also the line where I add this: ENV LD_DEBUG=all doesn't work. Because I haven't got more details when debugging.

ADDED NOW:

The output of the ldd:

# ldd /src/LightGBM/build/lib_lightgbm.so
ldd: /src/LightGBM/build/lib_lightgbm.so: No such file or directory
# cd /src/LightGBM
# ldd /src/LightGBM/build/lib_lightgbm.so
ldd: /src/LightGBM/build/lib_lightgbm.so: No such file or directory
# 
# ldd /src/LightGBM/lib_lightgbm.so
        linux-vdso.so.1 (0x00007ffe0e5dc000)
        libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f27d527d000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f27d5139000)
        libomp.so.5 => /usr/lib/x86_64-linux-gnu/libomp.so.5 (0x00007f27d5041000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f27d5027000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f27d5005000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f27d4e31000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f27d5988000)
        libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f27d4e29000)

And the output of tree:

# cd /src/LightGBM
# tree
.
|-- CMakeLists.txt
|-- CODE_OF_CONDUCT.md
|-- CONTRIBUTING.md
|-- LICENSE
|-- R-package
|   etccccc
|      
|-- README.md
|-- SECURITY.md
|-- VERSION.txt
|-- build
|   |-- CMakeCache.txt
|   |-- CMakeFiles
|   |   |-- 3.18.4 etcc
|   |   |-- CMakeDirectoryInformation.cmake
|   |   |-- CMakeOutput.log
|   |   |-- CMakeTmp
|   |   |-- FindOpenMP
|   |   |   |-- OpenMPCheckVersion.c
|   |   |   |-- OpenMPCheckVersion.cpp
|   |   |   |-- OpenMPTryFlag.c
|   |   |   |-- OpenMPTryFlag.cpp
|   |   |   |-- ompver_C.bin
|   |   |   `-- ompver_CXX.bin
|   |   |-- Makefile.cmake
|   |   |-- Makefile2
|   |   |-- TargetDirectories.txt
|   |   |-- _lightgbm.dir
|   |   |   |-- DependInfo.cmake
|   |   |   |-- build.make
|   |   |   |-- cmake_clean.cmake
|   |   |   |-- depend.internal
|   |   |   |-- depend.make
|   |   |   |-- flags.make
|   |   |   |-- link.txt
|   |   |   `-- progress.make
|   |   |-- cmake.check_cache
|   |   |-- lightgbm.dir
|   |   |   |-- CXX.includecache
|   |   |   |-- DependInfo.cmake
|   |   |   |-- build.make
|   |   |   |-- cmake_clean.cmake
|   |   |   |-- depend.internal
|   |   |   |-- depend.make
|   |   |   |-- flags.make
|   |   |   |-- link.txt
|   |   |   |-- progress.make
|   |   |   `-- src
|   |   |       |-- application
|   |   |       |   `-- application.cpp.o
|   |   |       `-- main.cpp.o
|   |   |-- lightgbm_capi_objs.dir
|   |   |   |-- CXX.includecache
|   |   |   |-- DependInfo.cmake
|   |   |   |-- build.make
|   |   |   |-- cmake_clean.cmake
|   |   |   |-- depend.internal
|   |   |   |-- depend.make
|   |   |   |-- flags.make
|   |   |   |-- progress.make
|   |   |   `-- src
|   |   |       `-- c_api.cpp.o
|   |   |-- lightgbm_objs.dir
|   |   |   |-- CXX.includecache
|   |   |   |-- DependInfo.cmake
|   |   |   |-- build.make
|   |   |   |-- cmake_clean.cmake
|   |   |   |-- depend.internal
|   |   |   |-- depend.make
|   |   |   |-- flags.make
|   |   |   |-- progress.make
|   |   |   `-- src etccc
|   |   `-- progress.marks
|   |-- Makefile
|   `-- cmake_install.cmake
|-- build-cran-package.sh
|-- build-python.sh
|-- build_r.R
|-- cmake
|   |-- IntegratedOpenCL.cmake
|   |-- Sanitizer.cmake
|   `-- modules
|       `-- FindLibR.cmake
|-- docker
|   |-- README.md
|   |-- dockerfile-cli
|   |-- dockerfile-python
|   |-- dockerfile-r
|   `-- gpu
|       |-- README.md
|       |-- dockerfile-cli-only-distroless.gpu
|       |-- dockerfile-cli-only.gpu
|       `-- dockerfile.gpu
|-- docs
|-- examples
|-- lib_lightgbm.so
|-- lightgbm
|-- pmml
|   `-- README.md
|-- python-package
|   |-- README.rst
|   |-- lightgbm
|-- swig
|   |-- ChunkedArray_API_extensions.i
|   |-- StringArray.hpp
|   |-- StringArray.i
|   |-- StringArray_API_extensions.i
|   |-- lightgbmlib.i
|   `-- pointer_manipulation.i
|-- tests
|   |-- c_api_test
|   |   `-- test_.py
|   |-- cpp_tests
|   |-- data
|   |   `-- categorical.data
|   |-- distributed
|   |   |-- _test_distributed.py
|   |   `-- conftest.py
|   `-- python_package_test

`-- windows
    |-- LightGBM.sln
    |-- LightGBM.vcxproj
    `-- LightGBM.vcxproj.filters

I removed some of the elements because the body then exceeds the limit

But now i just tested it locally with Docker. I ran the command that were on the Dockerfile without the COPY and it worked. But live it still isnt working. When i close the container and try it again locally it still doesnt work. These are some of the logs when I run the commands on the container.Maybe these will be helpful:

-- Build files have been written to: /src/LightGBM/build
Scanning dependencies of target lightgbm_capi_objs
Scanning dependencies of target lightgbm_objs
.....
 92%] Built target lightgbm_objs
Scanning dependencies of target lightgbm
Scanning dependencies of target _lightgbm
[ 94%] Linking CXX shared library ../lib_lightgbm.so
[ 96%] Building CXX object CMakeFiles/lightgbm.dir/src/main.cpp.o
[ 98%] Building CXX object CMakeFiles/lightgbm.dir/src/application/application.cpp.o
[ 98%] Built target _lightgbm
[100%] Linking CXX executable ../lightgbm
[100%] Built target lightgbm

UPDATED:

Fixed by adding this

RUN apt-get update
RUN apt-get install git clang-3.9 cmake libunwind8 curl -y 
RUN apt-get install -y libomp-dev
# Clone the lib_lightgbm repository and build it
RUN git clone --recursive https://github.com/microsoft/LightGBM.git && \
    cd LightGBM && mkdir build && cd build && \
    cmake .. && make -j && make install

Thank you @ventsyv


Solution

  • When a program runs and tries to load the libraries it needs, Linux searches a certain set of directories. If the library is not found in those directories you get an error.

    What those directories are depends somewhat on the distro, but usually /lib, /lib64, or /usr/lib/ and /usr/lib64 are a good bet.

    In addition, if LD_LIBRARY_PATH is set, those paths will be search as well.

    Probably the easiest thing to do is to run the install target. Add the following to your docker file:

    RUN apt-get update && apt-get install -y build-essential cmake git
    
    # Clone the lib_lightgbm repository and build it
    RUN git clone https://github.com/microsoft/LightGBM.git && \
        cd LightGBM && mkdir build && cd build && \
        cmake .. && make -j && make install
    

    Basically, after you run compile, you run make install which will move the built artifacts in the correct system directories.