Build your own docker images¶
Docker build has to be called from the root of the repository (i.e. docker
build .
or bash tools/docker/multibuild.sh
).
You can build a custom image using --build-arg
and several config files :
- Ubuntu :
BASE_IMG
should accept any version, for additional packages see tools/docker/build-deps-cli.txt and tools/docker/build-deps-gui.txt. - TensorFlow :
TF
arg for the git branch or tag + build-env-tf.sh and BZL_* arguments for the build configuration.ZIP_TF_BIN
allows you to save compiled binaries if you want to install it elsewhere. - OrfeoToolBox :
OTB
arg for the git branch or tag + tools/docker/build-flags-otb.txt to edit cmake flags. SetKEEP_SRC_OTB
in order to preserve OTB git directory.
Base images¶
Default arguments¶
BASE_IMG # mandatory
CPU_RATIO=1
GUI=false
NUMPY_SPEC="==1.19.*"
TF=v2.12.0
OTB=8.1.0
BZL_TARGETS="//tensorflow:libtensorflow_cc.so //tensorflow/tools/pip_package:build_pip_package"
BZL_CONFIGS="--config=nogcp --config=noaws --config=nohdfs --config=opt"
BZL_OPTIONS="--verbose_failures --remote_cache=http://localhost:9090"
ZIP_TF_BIN=false
KEEP_SRC_OTB=false
SUDO=true
# NumPy version requirement :
# TF < 2.4 : "numpy<1.19.0,>=1.16.0"
# TF >= 2.4 : "numpy==1.19.*"
# TF >= 2.8 : "numpy==1.22.*"
Bazel remote cache daemon¶
If you just need to rebuild with different GUI or KEEP_SRC arguments, or may
be a different branch of OTB, bazel cache will help you to rebuild everything
except TF, even if the docker cache was purged (after docker
[system|builder] prune
).
In order to recycle the cache, bazel config and TF git tag should be exactly
the same, any change in tools/docker/build-env-tf.sh and --build-arg
(if related to bazel env, cuda, mkl, xla...) may result in a fresh new build.
Start a cache daemon - here with max 20GB but 10GB should be enough to save 2 TF builds (GPU and CPU):
mkdir -p $HOME/.cache/bazel-remote
docker run --detach -u 1000:1000 -v $HOME/.cache/bazel-remote:/data \
-p 9090:8080 buchgr/bazel-remote-cache --max_size=20
Then just add --network='host'
to the docker build command, or connect
bazel to a remote server - see 'BZL_OPTIONS'.
The other way of docker is a virtual bridge, but you'll need to edit the IP
address.
Images build examples¶
# Build for CPU using default Dockerfiles args (without AWS, HDFS or GCP
# support)
docker build --network='host' -t otbtf:cpu --build-arg BASE_IMG=ubuntu:22.04 .
# Clear bazel config var (deactivate default optimizations and unset
# noaws/nogcp/nohdfs)
docker build --network='host' -t otbtf:cpu \
--build-arg BASE_IMG=ubuntu:22.04 \
--build-arg BZL_CONFIGS= .
# Enable MKL
MKL_CONFIG="--config=nogcp --config=noaws --config=nohdfs --config=opt --config=mkl"
docker build --network='host' -t otbtf:cpu-mkl \
--build-arg BZL_CONFIGS="$MKL_CONFIG" \
--build-arg BASE_IMG=ubuntu:22.04 .
# Build for GPU (if you're building for your system only you should edit
# CUDA_COMPUTE_CAPABILITIES in build-env-tf.sh)
docker build --network='host' -t otbtf:gpu \
--build-arg BASE_IMG=nvidia/cuda:12.1.0-devel-ubuntu22.04 .
# Build latest TF and OTB, set git branches/tags to clone
docker build --network='host' -t otbtf:gpu-dev \
--build-arg BASE_IMG=nvidia/cuda:12.1.0-devel-ubuntu22.04 \
--build-arg KEEP_SRC_OTB=true \
--build-arg TF=nightly \
--build-arg OTB=develop .
# Build old release (TF-2.1)
docker build --network='host' -t otbtf:oldstable-gpu \
--build-arg BASE_IMG=nvidia/cuda:10.1-cudnn7-devel-ubuntu18.04 \
--build-arg TF=r2.1 \
--build-arg NUMPY_SPEC="<1.19" \
--build-arg BAZEL_OPTIONS="--noincompatible_do_not_split_linking_cmdline --verbose_failures --remote_cache=http://localhost:9090" .
# You could edit the Dockerfile in order to clone an old branch of the repo
# instead of copying files from the build context
Build for another machine and save TF compiled files¶
Example with TF 2.5
# Use same ubuntu and CUDA version than your target machine, beware of CC
# optimization and CPU compatibility (set env variable CC_OPT_FLAGS and avoid
# "-march=native" if your Docker's CPU is optimized with AVX2/AVX512 but your
# target CPU isn't)
docker build --network='host' -t otbtf:custom \
--build-arg BASE_IMG=nvidia/cuda:11.2.2-cudnn8-devel-ubuntu20.04 \
--build-arg TF=v2.5.0 \
--build-arg ZIP_TF_BIN=true .
# Retrieve zip file
docker run -v $HOME:/home/otbuser/volume otbtf:custom \
cp /opt/otbtf/tf-v2.5.0.zip /home/otbuser/volume
# Target machine shell
cd $HOME
unzip tf-v2.5.0.zip
sudo mkdir -p /opt/tensorflow/lib
sudo mv tf-v2.5.0/libtensorflow_cc* /opt/tensorflow/lib
# You may need to create a virtualenv, here TF and dependencies are installed
# next to user's pip packages
pip3 install -U pip wheel mock six future deprecated "numpy==1.19.*"
pip3 install --no-deps keras_applications keras_preprocessing
pip3 install tf-v2.5.0/tensorflow-2.5.0-cp38-cp38-linux_x86_64.whl
TF_WHEEL_DIR="$HOME/.local/lib/python3.8/site-packages/tensorflow"
# If you installed the wheel as regular user, with root pip it should be in
# /usr/local/lib/python3.*, or in your virtualenv lib/ directory
mv tf-v2.5.0/tag_constants.h $TF_WHEEL_DIR/include/tensorflow/cc/saved_model/
# Then recompile OTB with OTBTF using libraries in /opt/tensorflow/lib and
# instructions in build_from_sources.md.
cmake $OTB_GIT \
-DOTB_USE_TENSORFLOW=ON -DModule_OTBTensorflow=ON \
-DTENSORFLOW_CC_LIB=/opt/tensorflow/lib/libtensorflow_cc.so.2 \
-Dtensorflow_include_dir=$TF_WHEEL_DIR/include \
-DTENSORFLOW_FRAMEWORK_LIB=$TF_WHEEL_DIR/libtensorflow_framework.so.2 \
&& make install -j
Debug build¶
If you fail to build, you can log into the last layer and check CMake logs.
Run docker images
, find the latest layer ID and run a tmp container
(docker run -it d60496d9612e bash
).
You may also need to split some multi-command layers in the Dockerfile.
If you see OOM errors during SuperBuild you should decrease CPU_RATIO (e.g.
0.75).
Container examples¶
# Pull GPU image and create a new container with your home directory as volume
# (requires apt package nvidia-docker2 and CUDA>=11.0)
docker create --gpus=all --volume $HOME:/home/otbuser/volume -it \
--name otbtf-gpu mdl4eo/otbtf:3.3.2-gpu
# Run interactive
docker start -i otbtf-gpu
# Run in background
docker start otbtf-gpu
docker exec otbtf-gpu \
python -c 'import tensorflow as tf; print(tf.test.is_gpu_available())'
Rebuild OTB with more modules¶
Enter a development ready docker image:
docker create --gpus=all -it --name otbtf-gpu-dev mdl4eo/otbtf:3.3.2-gpu-dev
docker start -i otbtf-gpu-dev
Then, from the container shell:
sudo -i
cd /src/otb/otb/Modules/Remote
git clone https://gitlab.irstea.fr/raffaele.gaetano/otbSelectiveHaralickTextures.git
cd /src/otb/build/OTB/build
cmake -DModule_OTBAppSelectiveHaralickTextures=ON /src/otb/otb && make install -j
Container with GUI¶
GUI is disabled by default in order to save space, and because docker xvfb isn't working properly with OpenGL. OTB GUI seems OK but monteverdi isn't working