salilab / imp

The Integrative Modeling Platform
https://integrativemodeling.org
GNU General Public License v3.0
74 stars 30 forks source link

build binaries for docker container? #1079

Closed dsclassen closed 1 year ago

dsclassen commented 1 year ago

I'm attempting to build foxs and multi_foxs to run in a Docker container, but am running into an issue with missing libraries.

foxs: error while loading shared libraries: libimp_foxs.so.2.18.0: cannot open shared object file: No such file or directory

Now I understand this is probably more about my lack of Docker experience, but I thought I would post my issue here in case someone might have an idea of what I need to do.

I'm building the image in stages as per the recommendations

Here is an abbreviated excerpt from my Dockerfile:

FROM debian:bullseye AS builder
RUN apt-get update && apt-get install -y cmake gcc gfortran g++

FROM builder AS build_imp
RUN apt-get install -y \
  libboost-all-dev \
  libeigen3-dev \
  google-perftools \
  libcgal-dev \
  graphviz \
  libgsl-dev \
  libhdf5-dev \
  swig \
  fftw-dev \
  opencv-data \
  python3-dev \
  python3-numpy
WORKDIR /usr/local/src
COPY ./scripts/imp-2.18.0.tar.gz .
RUN tar zxvf imp-2.18.0.tar.gz
RUN mkdir imp_release
WORKDIR /usr/local/src/imp_release
RUN cmake /usr/local/src/imp-2.18.0
RUN make -j8

FROM node:18-bullseye
COPY --from=build_imp /usr/local/src/imp_release/bin/foxs /usr/local/bin/
COPY --from=build_imp /usr/local/src/imp_release/bin/multi_foxs /usr/local/bin/

So I build IMP in the build_imp stage then copy it to my final container. However, I guess this leaves all the library files behind. I have done this with other compiled binaries without problems. This probably has something to do with "static" vs "dynamic" library linking. So I have 2 questions.

  1. Has anyone else deployed IMP binaries like this?
  2. is there an option I can give to cmake to allow static libraries?
dsclassen commented 1 year ago

Well I found the IMP_STATIC flag while exploring ccmake and tried this:

cmake /usr/local/src/imp-2.18.0 -DIMP_STATIC=On

but now have this error (I cut most of the preceeding output):

#0 165.7 /usr/bin/ld: /usr/lib/x86_64-linux-gnu/libboost_regex.a(static_mutex.o): in function `boost::scoped_static_mutex_lock::scoped_static_mutex_lock(boost::static_mutex&, bool)':
#0 165.7 (.text+0x18): undefined reference to `pthread_mutex_lock'
#0 165.7 /usr/bin/ld: /usr/lib/x86_64-linux-gnu/libboost_regex.a(static_mutex.o): in function `boost::scoped_static_mutex_lock::lock()':
#0 165.7 (.text+0x68): undefined reference to `pthread_mutex_lock'
#0 165.7 /usr/bin/ld: /usr/lib/x86_64-linux-gnu/libboost_regex.a(static_mutex.o): in function `boost::scoped_static_mutex_lock::unlock()':
#0 165.7 (.text+0x98): undefined reference to `pthread_mutex_unlock'
#0 165.7 /usr/bin/ld: /usr/lib/x86_64-linux-gnu/libboost_regex.a(static_mutex.o): in function `boost::scoped_static_mutex_lock::~scoped_static_mutex_lock()':
#0 165.7 (.text+0x44): undefined reference to `pthread_mutex_unlock'
#0 165.9 collect2: error: ld returned 1 exit status
#0 165.9 make[2]: *** [modules/example/utility/CMakeFiles/IMP.example-example_program.dir/build.make:140: module_bin/example/example_program] Error 1
#0 165.9 make[1]: *** [CMakeFiles/Makefile2:11080: modules/example/utility/CMakeFiles/IMP.example-example_program.dir/all] Error 2
#0 165.9 make: *** [Makefile:160: all] Error 2

Perhaps there is some way to ONLY build foxs and multi_foxs? and not the example_program ?

benmwebb commented 1 year ago

I'm attempting to build foxs and multi_foxs to run in a Docker container, but am running into an issue with missing libraries.

Any reason you don't just install an existing binary? We already provide .deb packages at https://integrativemodeling.org/download-linux.html, so that should be straightforward, maybe something like

FROM ubuntu:22.04
RUN echo "deb https://integrativemodeling.org/latest/download jammy/" >> /etc/apt/sources.list && wget -O /etc/apt/trusted.gpg.d/salilab.asc https://salilab.org/~ben/pubkey256.asc && apt-get update && apt-get install -y imp

This is basically the same as using IMP at Google Colaboratory, see e.g. https://colab.research.google.com/github/salilab/foxs_tutorial/blob/main/foxs-colab.ipynb

foxs: error while loading shared libraries: libimp_foxs.so.2.18.0: cannot open shared object file: No such file or directory

Right, the foxs binary will need a bunch of IMP libraries, and also some data files (e.g. form factors). make install would be the usual way to get those all in the right place.

2. is there an option I can give to `cmake` to allow static libraries?

I would not recommend static linking - in fact, I don't think anybody does these days - but as you've discovered, there is a cmake flag that'll get you part way there. You will likely need to mess with linker flags by hand though, as static linking is sensitive to the ordering of dependent libraries. And you won't get any of the Python extensions this way, as they have to be dynamic. But you can see the logs from our static build of 2.18.0 (we build on CentOS 7) at https://integrativemodeling.org/nightly/results/?p=platform&plat=12&branch=main

If your intention is to build a container with IMP that is as small as possible but still maximally useful, I would dynamically link but disable modules you don't need by setting the IMP_DISABLED_MODULES cmake variable. Disabling em2d would remove the dependency on OpenCV, for example, which is a large library with a lot of dependencies of its own (and yes, you can disable the example module there too - although I think then you'd just get link errors with the next binary you try to link, looks like you need a -lpthread somewhere). Perhaps build a minimal .deb and install that into your base image. You can use our existing Debian build in IMP's tools/debian directory as a starting point.