From f65716b81201f499b66f47aa290f1dfc5a430740 Mon Sep 17 00:00:00 2001 From: Servando German Date: Wed, 23 Jan 2019 08:44:37 +0000 Subject: [PATCH] Docker: Add truly generic docker support Unify docker support with a new (and more generic) set of docker files. Two main images are created: - Base image containing an Ubuntu installation with all dependencies - Build image containing a pre-built Autoware When Cuda support is enabled, there is a further Base+Cuda support image. These Dockerfiles can be used for both AArch64 and x86_64 images. Co-authored-by: Filipe Rinaldi --- .dockerignore | 6 ++ docker/96boards/Dockerfile.kinetic | 87 ---------------- docker/96boards/README.md | 22 ---- docker/96boards/build.sh | 10 -- docker/96boards/run.sh | 35 ------- docker/generic/Dockerfile | 18 ++++ docker/generic/Dockerfile.base | 97 ++++++++++++++++++ docker/generic/Dockerfile.cuda | 90 ++++++++++++++++ docker/generic/Dockerfile.kinetic | 81 --------------- docker/generic/README.md | 63 ++++++++---- docker/generic/build.sh | 109 ++++++++++++++++++-- docker/generic/entrypoint.sh | 22 ++++ docker/generic/hooks/build | 27 +++++ docker/generic/hooks/env | 15 +++ docker/generic/hooks/post_push | 17 +++ docker/generic/run.sh | 159 +++++++++++++++++++++++------ 16 files changed, 562 insertions(+), 296 deletions(-) create mode 100644 .dockerignore delete mode 100644 docker/96boards/Dockerfile.kinetic delete mode 100644 docker/96boards/README.md delete mode 100755 docker/96boards/build.sh delete mode 100755 docker/96boards/run.sh create mode 100644 docker/generic/Dockerfile create mode 100644 docker/generic/Dockerfile.base create mode 100644 docker/generic/Dockerfile.cuda delete mode 100644 docker/generic/Dockerfile.kinetic create mode 100755 docker/generic/entrypoint.sh create mode 100644 docker/generic/hooks/build create mode 100644 docker/generic/hooks/env create mode 100755 docker/generic/hooks/post_push diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000000..1dbd884144b --- /dev/null +++ b/.dockerignore @@ -0,0 +1,6 @@ +.git* +ros/build* +ros/devel* +ros/install* +ros/log* +ros/coverage_* diff --git a/docker/96boards/Dockerfile.kinetic b/docker/96boards/Dockerfile.kinetic deleted file mode 100644 index d73305ad2c7..00000000000 --- a/docker/96boards/Dockerfile.kinetic +++ /dev/null @@ -1,87 +0,0 @@ -FROM ubuntu:16.04 -MAINTAINER Kenji Funaoka - -# Develop -RUN apt-get update && apt-get install -y \ - software-properties-common \ - wget curl git cmake cmake-curses-gui \ - libboost-all-dev \ - libflann-dev \ - libgsl0-dev \ - libgoogle-perftools-dev \ - libeigen3-dev - -# Intall some basic GUI and sound libs -RUN apt-get update && apt-get install -y \ - xz-utils file locales dbus-x11 pulseaudio dmz-cursor-theme \ - fonts-dejavu fonts-liberation hicolor-icon-theme \ - libcanberra-gtk3-0 libcanberra-gtk-module libcanberra-gtk3-module \ - libasound2 libgtk2.0-0 libdbus-glib-1-2 libxt6 libexif12 \ - libgl1-mesa-glx libgl1-mesa-dri language-pack-en \ - && update-locale LANG=en_US.UTF-8 LC_MESSAGES=POSIX - -# Intall some basic GUI tools -RUN apt-get update && apt-get install -y \ - cmake-qt-gui \ - gnome-terminal - -# Intall ROS -RUN sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list' -RUN apt-key adv --keyserver hkp://ha.pool.sks-keyservers.net:80 --recv-key 421C365BD9FF1F717815A3895523BAEEB01FA116 -RUN apt-get update && apt-get install -y ros-kinetic-desktop-full ros-kinetic-nmea-msgs ros-kinetic-nmea-navsat-driver ros-kinetic-sound-play ros-kinetic-jsk-visualization ros-kinetic-grid-map ros-kinetic-gps-common -RUN apt-get update && apt-get install -y ros-kinetic-controller-manager ros-kinetic-ros-control ros-kinetic-ros-controllers ros-kinetic-gazebo-ros-control ros-kinetic-joystick-drivers -RUN apt-get update && apt-get install -y libnlopt-dev freeglut3-dev qtbase5-dev libqt5opengl5-dev libssh2-1-dev libarmadillo-dev libpcap-dev libgl1-mesa-dev libglew-dev python-wxgtk3.0 software-properties-common libmosquitto-dev libyaml-cpp-dev python-flask python-requests - -# Add basic user -ENV USERNAME autoware -ENV PULSE_SERVER /run/pulse/native -RUN useradd -m $USERNAME && \ - echo "$USERNAME:$USERNAME" | chpasswd && \ - usermod --shell /bin/bash $USERNAME && \ - usermod -aG sudo $USERNAME && \ - echo "$USERNAME ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/$USERNAME && \ - chmod 0440 /etc/sudoers.d/$USERNAME && \ - # Replace 1000 with your user/group id - usermod --uid 1000 $USERNAME && \ - groupmod --gid 1000 $USERNAME - -# Setup .bashrc for ROS -RUN echo "source /opt/ros/kinetic/setup.bash" >> /home/$USERNAME/.bashrc && \ - #Fix for qt and X server errors - echo "export QT_X11_NO_MITSHM=1" >> /home/$USERNAME/.bashrc && \ - # cd to home on login - echo "cd" >> /home/$USERNAME/.bashrc - -# Install colcon -RUN apt-get install -y python3-pip python3-setuptools -RUN pip3 install -U setuptools -RUN apt-get install -y python3-colcon-common-extensions - -# Change user -USER autoware - -RUN sudo rosdep init \ - && rosdep update \ - && echo "source /opt/ros/kinetic/setup.bash" >> ~/.bashrc - -# YOLO_V2 -> Unable to install because CMakeLists.txt in vision_yolo2_detect depends on CUDA - -# Install Autoware -RUN cd && git clone https://github.com/CPFL/Autoware.git /home/$USERNAME/Autoware -RUN /bin/bash -c 'source /opt/ros/kinetic/setup.bash; cd /home/$USERNAME/Autoware/ros/src; git submodule update --init --recursive; cd ../; ./colcon_release -j2' -RUN echo "source /home/$USERNAME/Autoware/ros/devel/setup.bash" >> /home/$USERNAME/.bashrc - -# Setting -ENV LANG="en_US.UTF-8" -RUN echo "export LANG=\"en_US.UTF-8\"" >> /home/$USERNAME/.bashrc - -# Install dev tools -RUN sudo apt-get -y install vim tmux - -# Change Terminal Color -RUN gconftool-2 --set "/apps/gnome-terminal/profiles/Default/use_theme_background" --type bool false -RUN gconftool-2 --set "/apps/gnome-terminal/profiles/Default/use_theme_colors" --type bool false -RUN gconftool-2 --set "/apps/gnome-terminal/profiles/Default/background_color" --type string "#000000" - -# Default CMD -CMD ["/bin/bash"] diff --git a/docker/96boards/README.md b/docker/96boards/README.md deleted file mode 100644 index 3f0285b03f2..00000000000 --- a/docker/96boards/README.md +++ /dev/null @@ -1,22 +0,0 @@ -# Autoware Docker on 96boards - -See [Wiki](https://github.com/CPFL/Autoware/wiki/Docker) for more information. - -## How to Build -``` -$ cd Autoware/docker/96boards/ - -# Ubuntu 16.04 (Kinetic) -$ sh build.sh kinetic -``` - -## How to Run -``` -# Default shared directory path is /home/$USER/shared_dir - -# Ubuntu 16.04 (Kinetic) -$ sh run.sh kinetic - -# If you select your shared directory path -$ sh run.sh kinetic {SHARED_DIR_PATH} -``` diff --git a/docker/96boards/build.sh b/docker/96boards/build.sh deleted file mode 100755 index 946c1872c0b..00000000000 --- a/docker/96boards/build.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -# Build Docker Image -if [ "$1" = "kinetic" ] -then - echo "Use $1" - docker build -t autoware-$1 -f Dockerfile.$1 . --no-cache -else - echo "Set distribution, kinetic" -fi diff --git a/docker/96boards/run.sh b/docker/96boards/run.sh deleted file mode 100755 index dbb0fa7fcc7..00000000000 --- a/docker/96boards/run.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/sh - -XSOCK=/tmp/.X11-unix -XAUTH=/home/$USER/.Xauthority -SHARED_DIR=/home/autoware/shared_dir -HOST_DIR=/home/$USER/shared_dir - -if [ "$1" = "kinetic" ] -then - echo "Use $1" -else - echo "Set distribution, kinetic" - exit -fi - -if [ "$2" = "" ] -then - # Create Shared Folder - mkdir -p $HOST_DIR -else - HOST_DIR=$2 -fi -echo "Shared directory: ${HOST_DIR}" - -docker run \ - -it --rm \ - --volume=$XSOCK:$XSOCK:rw \ - --volume=$XAUTH:$XAUTH:rw \ - --volume=$HOST_DIR:$SHARED_DIR:rw \ - --env="XAUTHORITY=${XAUTH}" \ - --env="DISPLAY=${DISPLAY}" \ - -u autoware \ - --privileged -v /dev/bus/usb:/dev/bus/usb \ - --net=host \ - autoware-$1 diff --git a/docker/generic/Dockerfile b/docker/generic/Dockerfile new file mode 100644 index 00000000000..e9abe9b715c --- /dev/null +++ b/docker/generic/Dockerfile @@ -0,0 +1,18 @@ +ARG FROM_ARG +ARG ROS_DISTRO +FROM ${FROM_ARG} + +ENV USERNAME autoware + +# Build Autoware +COPY --chown=autoware ./ /home/$USERNAME/Autoware +RUN su -c "bash -c 'source /opt/ros/$ROS_DISTRO/setup.bash; \ + cd /home/$USERNAME/Autoware/ros/src; \ + catkin_init_workspace; \ + cd ../; \ + ./catkin_make_release'" $USERNAME +RUN echo "source /home/$USERNAME/Autoware/ros/devel/setup.bash" >> \ + /home/$USERNAME/.bashrc + +COPY ./docker/generic/entrypoint.sh /tmp +ENTRYPOINT ["/tmp/entrypoint.sh"] diff --git a/docker/generic/Dockerfile.base b/docker/generic/Dockerfile.base new file mode 100644 index 00000000000..94444cfad49 --- /dev/null +++ b/docker/generic/Dockerfile.base @@ -0,0 +1,97 @@ +# +# Install ROS packages used by Autoware. +# +ARG ROS_DISTRO +FROM ros:$ROS_DISTRO + +# +# Install tools and libraries required by Autoware +# +RUN apt-get update && apt-get install -y \ + cmake-curses-gui \ + cmake-qt-gui \ + dbus-x11 \ + dmz-cursor-theme \ + fonts-dejavu \ + gconf2 \ + gnome-terminal \ + gstreamer0.10-plugins-good \ + language-pack-en \ + libarmadillo-dev \ + libcanberra-gtk-module \ + libcanberra-gtk3-0 \ + libcanberra-gtk3-module \ + libdbus-glib-1-2 \ + libgflags-dev \ + libglew-dev \ + libgoogle-glog-dev \ + libgoogle-perftools-dev \ + libgsl0-dev \ + libmosquitto-dev \ + libopencv-dev \ + libopenni2-dev \ + libpcap-dev \ + libssh2-1-dev \ + locales \ + pulseaudio \ + python-flask \ + python-requests \ + python3-colcon-common-extensions \ + python3-pip \ + python3-setuptools \ + sudo \ + tmux \ + v4l-utils \ + vim \ + wget && \ + pip3 install -U setuptools && \ + rm -rf /var/lib/apt/lists/* + +# +# Configure environmet +# + +RUN update-locale LANG=en_US.UTF-8 LC_MESSAGES=POSIX + +# Add user +ENV USERNAME autoware +ARG USER_ID=1000 +ARG GROUP_ID=15214 +ENV PULSE_SERVER /run/pulse/native + +RUN groupadd --gid $GROUP_ID $USERNAME && \ + useradd --gid $GROUP_ID -m $USERNAME && \ + echo "$USERNAME:$USERNAME" | chpasswd && \ + usermod --shell /bin/bash $USERNAME && \ + usermod -aG sudo $USERNAME && \ + usermod --uid $USER_ID $USERNAME && \ + echo "$USERNAME ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/$USERNAME && \ + chmod 0440 /etc/sudoers.d/$USERNAME + +# Startup scripts +ENV LANG="en_US.UTF-8" +RUN echo "source /opt/ros/$ROS_DISTRO/setup.bash" >> /etc/profile.d/ros.sh && \ + # Fix for QT and X server errors + echo "export QT_X11_NO_MITSHM=1" >> /etc/profile.d/autoware.sh && \ + # Set defaut language + echo "export LANG=\"en_US.UTF-8\"" >> /etc/profile.d/autoware.sh + +# +# Scan Autoware packages to install dependencies +# +COPY ./ /tmp/Autoware +RUN apt-get update && \ + apt-get install -y ros-$ROS_DISTRO-desktop-full && \ + rosdep install -y --from-paths /tmp/Autoware/ros/src --ignore-src && \ + rm -rf /var/lib/apt/lists/* && \ + rm -rf /tmp/Autoware # Removed for clean environment + +RUN su -c "rosdep update" autoware + +# Configure terminal colors +RUN su -c "gconftool-2 --set \"/apps/gnome-terminal/profiles/Default/use_theme_background\" --type bool false" autoware && \ + su -c "gconftool-2 --set \"/apps/gnome-terminal/profiles/Default/use_theme_colors\" --type bool false" autoware && \ + su -c "gconftool-2 --set \"/apps/gnome-terminal/profiles/Default/background_color\" --type string \"#000000\"" autoware + +COPY ./docker/generic/entrypoint.sh /tmp +ENTRYPOINT ["/tmp/entrypoint.sh"] diff --git a/docker/generic/Dockerfile.cuda b/docker/generic/Dockerfile.cuda new file mode 100644 index 00000000000..23c663eb88c --- /dev/null +++ b/docker/generic/Dockerfile.cuda @@ -0,0 +1,90 @@ +ARG FROM_ARG +FROM ${FROM_ARG} +USER root + + +# From nvidia cuda 9.0 base: https://gitlab.com/nvidia/cuda/tree/ubuntu16.04/9.0/base/Dockerfile + +RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates apt-transport-https gnupg-curl && \ + rm -rf /var/lib/apt/lists/* && \ + NVIDIA_GPGKEY_SUM=d1be581509378368edeec8c1eb2958702feedf3bc3d17011adbf24efacce4ab5 && \ + NVIDIA_GPGKEY_FPR=ae09fe4bbd223a84b2ccfce3f60f4b3d7fa2af80 && \ + apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/7fa2af80.pub && \ + apt-key adv --export --no-emit-version -a $NVIDIA_GPGKEY_FPR | tail -n +5 > cudasign.pub && \ + echo "$NVIDIA_GPGKEY_SUM cudasign.pub" | sha256sum -c --strict - && rm cudasign.pub && \ + echo "deb https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64 /" > /etc/apt/sources.list.d/cuda.list && \ + echo "deb https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1604/x86_64 /" > /etc/apt/sources.list.d/nvidia-ml.list + +ENV CUDA_VERSION 9.0.176 + +ENV CUDA_PKG_VERSION 9-0=$CUDA_VERSION-1 +RUN apt-get update && apt-get install -y --no-install-recommends \ + cuda-cudart-$CUDA_PKG_VERSION && \ + ln -s cuda-9.0 /usr/local/cuda && \ + rm -rf /var/lib/apt/lists/* + +RUN echo "/usr/local/nvidia/lib" >> /etc/ld.so.conf.d/nvidia.conf && \ + echo "/usr/local/nvidia/lib64" >> /etc/ld.so.conf.d/nvidia.conf + +ENV PATH /usr/local/nvidia/bin:/usr/local/cuda/bin:${PATH} +ENV LD_LIBRARY_PATH /usr/local/nvidia/lib:/usr/local/nvidia/lib64 + +# nvidia-container-runtime +ENV NVIDIA_VISIBLE_DEVICES all +ENV NVIDIA_DRIVER_CAPABILITIES compute,utility +ENV NVIDIA_REQUIRE_CUDA "cuda>=9.0" + + +# From nvidia cuda 9.0 runtime: https://gitlab.com/nvidia/cuda/blob/ubuntu16.04/9.0/runtime/Dockerfile + +ENV NCCL_VERSION 2.3.7 + +RUN apt-get update && apt-get install -y --no-install-recommends \ + cuda-libraries-$CUDA_PKG_VERSION \ + cuda-cublas-9-0=9.0.176.4-1 \ + libnccl2=$NCCL_VERSION-1+cuda9.0 && \ + apt-mark hold libnccl2 && \ + rm -rf /var/lib/apt/lists/* + +# From nvidia cuda 9.0 devel: https://gitlab.com/nvidia/cuda/blob/ubuntu16.04/9.0/devel/Dockerfile + +RUN apt-get update && apt-get install -y --no-install-recommends \ + cuda-libraries-dev-$CUDA_PKG_VERSION \ + cuda-nvml-dev-$CUDA_PKG_VERSION \ + cuda-minimal-build-$CUDA_PKG_VERSION \ + cuda-command-line-tools-$CUDA_PKG_VERSION \ + cuda-core-9-0=9.0.176.3-1 \ + cuda-cublas-dev-9-0=9.0.176.4-1 \ + libnccl-dev=$NCCL_VERSION-1+cuda9.0 && \ + rm -rf /var/lib/apt/lists/* + +ENV LIBRARY_PATH /usr/local/cuda/lib64/stubs + +# Support for Nvidia docker v2 + +RUN apt-get update && apt-get install -y --no-install-recommends \ + pkg-config \ + libxau-dev \ + libxdmcp-dev \ + libxcb1-dev \ + libxext-dev \ + libx11-dev && \ + rm -rf /var/lib/apt/lists/* +COPY --from=nvidia/opengl:1.0-glvnd-runtime-ubuntu16.04 \ + /usr/local/lib/x86_64-linux-gnu \ + /usr/local/lib/x86_64-linux-gnu +COPY --from=nvidia/opengl:1.0-glvnd-runtime-ubuntu16.04 \ + /usr/local/share/glvnd/egl_vendor.d/10_nvidia.json \ + /usr/local/share/glvnd/egl_vendor.d/10_nvidia.json +RUN echo '/usr/local/lib/x86_64-linux-gnu' >> /etc/ld.so.conf.d/glvnd.conf && \ + ldconfig && \ + echo '/usr/local/$LIB/libGL.so.1' >> /etc/ld.so.preload && \ + echo '/usr/local/$LIB/libEGL.so.1' >> /etc/ld.so.preload +RUN apt update +# nvidia-container-runtime +ENV NVIDIA_VISIBLE_DEVICES \ + ${NVIDIA_VISIBLE_DEVICES:-all} +ENV NVIDIA_DRIVER_CAPABILITIES \ + ${NVIDIA_DRIVER_CAPABILITIES:+$NVIDIA_DRIVER_CAPABILITIES,}graphics + +ENTRYPOINT ["/tmp/entrypoint.sh"] diff --git a/docker/generic/Dockerfile.kinetic b/docker/generic/Dockerfile.kinetic deleted file mode 100644 index 62b41dc6081..00000000000 --- a/docker/generic/Dockerfile.kinetic +++ /dev/null @@ -1,81 +0,0 @@ -FROM nvidia/cuda:9.0-devel-ubuntu16.04 -MAINTAINER Yuki Iida - -# Develop -RUN apt-get update && apt-get install -y \ - software-properties-common \ - wget curl git cmake cmake-curses-gui \ - libboost-all-dev \ - libflann-dev \ - libgsl0-dev \ - libgoogle-perftools-dev \ - libeigen3-dev - -# Intall some basic GUI and sound libs -RUN apt-get update && apt-get install -y \ - xz-utils file locales dbus-x11 pulseaudio dmz-cursor-theme \ - fonts-dejavu fonts-liberation hicolor-icon-theme \ - libcanberra-gtk3-0 libcanberra-gtk-module libcanberra-gtk3-module \ - libasound2 libgtk2.0-0 libdbus-glib-1-2 libxt6 libexif12 \ - libgl1-mesa-glx libgl1-mesa-dri language-pack-en \ - && update-locale LANG=en_US.UTF-8 LC_MESSAGES=POSIX - -# Intall some basic GUI tools -RUN apt-get update && apt-get install -y \ - cmake-qt-gui \ - gnome-terminal - -# Intall ROS -RUN sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list' -RUN apt-key adv --keyserver hkp://ha.pool.sks-keyservers.net:80 --recv-key 421C365BD9FF1F717815A3895523BAEEB01FA116 -RUN apt-get update && apt-get install -y ros-kinetic-desktop-full ros-kinetic-nmea-msgs ros-kinetic-nmea-navsat-driver ros-kinetic-sound-play ros-kinetic-jsk-visualization ros-kinetic-grid-map ros-kinetic-gps-common -RUN apt-get update && apt-get install -y ros-kinetic-controller-manager ros-kinetic-ros-control ros-kinetic-ros-controllers ros-kinetic-gazebo-ros-control ros-kinetic-joystick-drivers -RUN apt-get update && apt-get install -y libnlopt-dev freeglut3-dev qtbase5-dev libqt5opengl5-dev libssh2-1-dev libarmadillo-dev libpcap-dev libgl1-mesa-dev libglew-dev python-wxgtk3.0 software-properties-common libmosquitto-dev libyaml-cpp-dev python-flask python-requests - -# Add basic user -ENV USERNAME autoware -ENV PULSE_SERVER /run/pulse/native -RUN useradd -m $USERNAME && \ - echo "$USERNAME:$USERNAME" | chpasswd && \ - usermod --shell /bin/bash $USERNAME && \ - usermod -aG sudo $USERNAME && \ - echo "$USERNAME ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/$USERNAME && \ - chmod 0440 /etc/sudoers.d/$USERNAME && \ - # Replace 1000 with your user/group id - usermod --uid 1000 $USERNAME && \ - groupmod --gid 1000 $USERNAME - -# Setup .bashrc for ROS -RUN echo "source /opt/ros/kinetic/setup.bash" >> /home/$USERNAME/.bashrc && \ - #Fix for qt and X server errors - echo "export QT_X11_NO_MITSHM=1" >> /home/$USERNAME/.bashrc && \ - # cd to home on login - echo "cd" >> /home/$USERNAME/.bashrc - -# Change user -USER autoware - -RUN sudo rosdep init \ - && rosdep update \ - && echo "source /opt/ros/kinetic/setup.bash" >> ~/.bashrc - -# Install Autoware -RUN cd && mkdir /home/$USERNAME/Autoware -COPY --chown=autoware ./ /home/$USERNAME/Autoware/ -RUN /bin/bash -c 'source /opt/ros/kinetic/setup.bash; cd /home/$USERNAME/Autoware/ros/src; git submodule update --init --recursive; catkin_init_workspace; cd ../; rosdep install -y --from-paths /home/$USERNAME/Autoware/ros/src --ignore-src --rosdistro kinetic; ./catkin_make_release' -RUN echo "source /home/$USERNAME/Autoware/ros/devel/setup.bash" >> /home/$USERNAME/.bashrc - -# Setting -ENV LANG="en_US.UTF-8" -RUN echo "export LANG=\"en_US.UTF-8\"" >> /home/$USERNAME/.bashrc - -# Install dev tools -RUN sudo apt-get -y install vim tmux - -# Change Terminal Color -RUN gconftool-2 --set "/apps/gnome-terminal/profiles/Default/use_theme_background" --type bool false -RUN gconftool-2 --set "/apps/gnome-terminal/profiles/Default/use_theme_colors" --type bool false -RUN gconftool-2 --set "/apps/gnome-terminal/profiles/Default/background_color" --type string "#000000" - -# Default CMD -CMD ["/bin/bash"] diff --git a/docker/generic/README.md b/docker/generic/README.md index c2bab4c2ab4..a5f05d4a549 100644 --- a/docker/generic/README.md +++ b/docker/generic/README.md @@ -1,29 +1,54 @@ -# Autoware Docker -To use the Autoware Docker, first make sure the NVIDIA drivers, Docker and nvidia-docker are properly installed. +Autoware Docker +=============== -[Docker installation](https://docs.docker.com/engine/installation/linux/docker-ce/ubuntu/) +Docker can be used to allow developers to quickly get a development +environment ready to try and develop Autoware. +The main Docker images are: +* Base image - Provides a container with all the dependencies to build and +run Autoware. When creating a container using this image, the Autoware +source code is mounted as a volume allowing the user to develop and build +Autoware. +* Pre-built Autoware - Provides a container with a copy of Autoware +pre-built. This image is built on top of the base image. -[nvidia-docker installation](https://github.com/NVIDIA/nvidia-docker) +When Cuda is enabled, a new base image is created which is then used to build +the pre-built Autoware image. Images containing Cuda support have the suffix +_-cuda_ allowing cuda and non-cuda images existing without conflict. -## How to Build -``` -$ cd Autoware/docker/generic/ +This set of Dockerfiles can be used to build and run containers natively on +both AArch64 and x86_64 systems. -# Ubuntu 16.04 (Kinetic) -$ sh build.sh kinetic -``` +Requirements +------------ + +* Recent version of [Docker CE](https://docs.docker.com/install/linux/docker-ce/ubuntu/) +* [NVIDIA Docker](https://github.com/NVIDIA/nvidia-docker) if your system +has Cuda support + +How to build +------------ + +To build the docker image(s), use the build.sh script. +For details on the parameters available, try: -## How to Run ``` +./build.sh --help +``` + +How to run +---------- -# Ubuntu 16.04 (Kinetic) -$ ./run.sh -t latest-kinetic +To start a container use the run.sh tool. Which container will start +depends on the parameters passed to run.sh. For details on the parameters +available, try: + +``` +./run.sh --help ``` -|Option|Default|Description| -|---|---|---| -|-h||Show `Usage: $0 [-t ] [-r ] [-s ]`| -|-t|latest-kinetic|Specify tag| -|-r|autoware/autoware|Specify repo| -|-s|/home/$USER/shared_dir|Specify shared dir| +__Note__: The default values for the __--image__ and __--tag-prefix__ +parameters in build.sh and run.sh are different. This is because run.sh +defaults to values used to retrieve images from Docker Hub. When running +containers from images you have built, make sure the parameters mentioned +match. diff --git a/docker/generic/build.sh b/docker/generic/build.sh index 3989afb14e0..6f7ffdd5894 100755 --- a/docker/generic/build.sh +++ b/docker/generic/build.sh @@ -1,10 +1,101 @@ -#!/bin/sh - -# Build Docker Image -if [ "$1" = "kinetic" ] -then - echo "Use $1" - docker build -t autoware-$1 -f Dockerfile.$1 ./../.. --no-cache -else - echo "Select distribution, kinetic" +#!/bin/bash + +# Default settings +CUDA="on" +IMAGE_NAME="autoware/autoware" +TAG_PREFIX="local" +ROS_DISTRO="kinetic" +BASE_ONLY="false" + +function usage() { + echo "Usage: $0 [OPTIONS]" + echo " -b,--base-only Build the base image(s) only." + echo " Default:$BASE_ONLY" + echo " -c,--cuda Enable Cuda support in the Docker." + echo " Default:$CUDA" + echo " -h,--help Display the usage and exit." + echo " -i,--image Set docker images name." + echo " Default:$IMAGE_NAME" + echo " -t,--tag-prefix Tag prefix use for the docker images." + echo " Default:$TAG_PREFIX" +} + +OPTS=`getopt --options bc:hi:t: \ + --long base-only,cuda:,help,image-name:,tag-prefix: \ + --name "$0" -- "$@"` +eval set -- "$OPTS" + +while true; do + case $1 in + -b|--base-only) + BASE_ONLY="true" + shift 1 + ;; + -c|--cuda) + param=$(echo $2 | tr '[:upper:]' '[:lower:]') + case "${param}" in + "on"|"off") CUDA="${param}" ;; + *) echo "Invalid cuda option: $2"; exit 1 ;; + esac + shift 2 + ;; + -h|--help) + usage + exit 0 + ;; + -i|--image-name) + IMAGE_NAME="$2" + shift 2 + ;; + -t|--tag-prefix) + TAG_PREFIX="$2" + shift 2 + ;; + --) + if [ ! -z $2 ]; + then + echo "Invalid parameter: $2" + exit 1 + fi + break + ;; + *) + echo "Invalid option" + exit 1 + ;; + esac +done + +echo "Using options:" +echo -e "\tROS distro: $ROS_DISTRO" +echo -e "\tImage name: $IMAGE_NAME" +echo -e "\tTag prefix: $TAG_PREFIX" +echo -e "\tCuda support: $CUDA" +echo -e "\tBase only: $BASE_ONLY" + +BASE=$IMAGE_NAME:$TAG_PREFIX-$ROS_DISTRO-base + +docker build \ + --tag $BASE \ + --build-arg ROS_DISTRO=$ROS_DISTRO \ + --file Dockerfile.base ./../.. + +CUDA_SUFFIX="" +if [ $CUDA == "on" ]; then + CUDA_SUFFIX="-cuda" + docker build \ + --tag $BASE$CUDA_SUFFIX \ + --build-arg FROM_ARG=$BASE \ + --file Dockerfile.cuda . fi + +if [ "$BASE_ONLY" == "true" ]; then + echo "Finished building the base image(s) only." + exit 0 +fi + +docker build \ + --tag $IMAGE_NAME:$TAG_PREFIX-$ROS_DISTRO$CUDA_SUFFIX \ + --build-arg FROM_ARG=$BASE$CUDA_SUFFIX \ + --build-arg ROS_DISTRO=$ROS_DISTRO \ + --file Dockerfile ./../.. diff --git a/docker/generic/entrypoint.sh b/docker/generic/entrypoint.sh new file mode 100755 index 00000000000..ca1db766814 --- /dev/null +++ b/docker/generic/entrypoint.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +set -e + +DEFAULT_USER_ID=1000 + +# +# Ensure host and container have the same user ID. This is to allow both sides +# to read and write the shared directories. +# +if [ "$USER_ID" != "$DEFAULT_USER_ID" ]; then + echo "Changing autoware user ID to match your host's user ID ($USER_ID)." + echo "This operation can take a while..." + + usermod --uid $USER_ID autoware + + # Ensure all files in the home directory are owned by the new user ID + find /home/autoware -user $DEFAULT_USER_ID -exec chown -h $USER_ID {} \; +fi + +# Start an interactive shell using user 'autoware' +sudo -iu autoware diff --git a/docker/generic/hooks/build b/docker/generic/hooks/build new file mode 100644 index 00000000000..816502bb475 --- /dev/null +++ b/docker/generic/hooks/build @@ -0,0 +1,27 @@ +#!/bin/bash + +. ./hooks/env + +# $IMAGE_NAME var is injected into the build so the tag is correct. +echo "[***] Build hook running" + +# Build base dependencies +docker build \ + -t $BASE \ + --build-arg ROS_DISTRO=$ROS_DISTRO \ + -f Dockerfile.base ./../.. +docker push $BASE + +# Build cuda dependencies +docker build \ + -t $BASE_CUDA \ + --build-arg FROM_ARG=$BASE \ + -f Dockerfile.cuda . +docker push $BASE_CUDA + +# Build autoware-cuda +docker build \ + -t $IMAGE_NAME \ + --build-arg FROM_ARG=$BASE_CUDA \ + --build-arg ROS_DISTRO=$ROS_DISTRO \ + -f Dockerfile ./../.. diff --git a/docker/generic/hooks/env b/docker/generic/hooks/env new file mode 100644 index 00000000000..439a375cac1 --- /dev/null +++ b/docker/generic/hooks/env @@ -0,0 +1,15 @@ +[ -n "$SOURCE_BRANCH" ] || SOURCE_BRANCH=$(git symbolic-ref -q --short HEAD) +[ -n "$GIT_SHA1" ] || GIT_SHA1=$(git rev-parse -q HEAD) + +# $IMAGE_NAME of type XXX-ROS_DISTRO-cuda | XXX-ROS_DISTRO-cuda-rc + +BASE=${IMAGE_NAME:0: -5}-base #remove '-cuda' from $IMAGE_NAME string +BASE_CUDA=$BASE-cuda +LATEST_TAG="ON" +if [[ "${SOURCE_BRANCH}" =~ "release/" ]]; then + BASE=${IMAGE_NAME:0: -8}-base-rc #remove '-cuda-rc' from $IMAGE_NAME string + BASE_CUDA=$BASE-cuda-rc + LATEST_TAG="OFF" +fi + +ROS_DISTRO=kinetic diff --git a/docker/generic/hooks/post_push b/docker/generic/hooks/post_push new file mode 100755 index 00000000000..ed474c82833 --- /dev/null +++ b/docker/generic/hooks/post_push @@ -0,0 +1,17 @@ +#!/bin/bash + +set -e + +. ./hooks/env + +if [[ "${LATEST_TAG}" =~ "ON" ]]; then + # Tag and push image for latest tag + docker tag $BASE ${DOCKER_REPO}:latest-$ROS_DISTRO-base + docker push ${DOCKER_REPO}:latest-$ROS_DISTRO-base + + docker tag $BASE_CUDA ${DOCKER_REPO}:latest-$ROS_DISTRO-base-cuda + docker push ${DOCKER_REPO}:latest-$ROS_DISTRO-base-cuda + + docker tag $IMAGE_NAME ${DOCKER_REPO}:latest-$ROS_DISTRO-cuda + docker push ${DOCKER_REPO}:latest-$ROS_DISTRO-cuda +fi diff --git a/docker/generic/run.sh b/docker/generic/run.sh index e0b7cc73486..923b75a23f8 100755 --- a/docker/generic/run.sh +++ b/docker/generic/run.sh @@ -1,52 +1,145 @@ #!/bin/bash -usage() { echo "Usage: $0 [-t ] [-r ] [-s ]" 1>&2; exit 1; } +# Default settings +CUDA="on" +IMAGE_NAME="autoware/autoware" +TAG_PREFIX="latest" +ROS_DISTRO="kinetic" +BASE_ONLY="false" +PRE_RELEASE="off" +AUTOWARE_GROUP_ID=15214 -# Defaults -XSOCK=/tmp/.X11-unix -XAUTH=/home/$USER/.Xauthority -SHARED_DIR=/home/autoware/shared_dir -HOST_DIR=/home/$USER/shared_dir -DOCKER_HUB_REPO="autoware/autoware" -TAG="latest-kinetic" - -while getopts ":ht:r:s:" opt; do - case $opt in - h) +function usage() { + echo "Usage: $0 [OPTIONS]" + echo " -b,--base-only Run the base image only." + echo " Default:$BASE_ONLY" + echo " -c,--cuda Enable Cuda support in the Docker." + echo " Default:$CUDA" + echo " -h,--help Display the usage and exit." + echo " -i,--image Set docker images name." + echo " Default:$IMAGE_NAME" + echo " -p,--pre-release Use pre-release image." + echo " Default:$PRE_RELEASE" + echo " -t,--tag-prefix Tag prefix use for the docker images." + echo " Default:$TAG_PREFIX" +} + +# Convert a relative directory path to absolute +function abspath() { + local path=$1 + if [ ! -d $path ]; then + exit 1 + fi + pushd $path > /dev/null + echo $(pwd) + popd > /dev/null +} + +OPTS=`getopt --options bc:hi:p:t: \ + --long base-only,cuda:,help,image-name:,pre-release:,tag-prefix: \ + --name "$0" -- "$@"` +eval set -- "$OPTS" + +while true; do + case $1 in + -b|--base-only) + BASE_ONLY="true" + shift 1 + ;; + -c|--cuda) + param=$(echo $2 | tr '[:upper:]' '[:lower:]') + case "${param}" in + "on"|"off") CUDA="${param}" ;; + *) echo "Invalid cuda option: $2"; exit 1 ;; + esac + shift 2 + ;; + -h|--help) usage - exit + exit 0 ;; - t) - TAG=$OPTARG + -i|--image-name) + IMAGE_NAME="$2" + shift 2 ;; - r ) - DOCKER_HUB_REPO=$OPTARG + -p|--pre-release) + param=$(echo $2 | tr '[:upper:]' '[:lower:]') + case "${param}" in + "on"|"off") PRE_RELEASE="${param}" ;; + *) echo "Invalid pre-release option: $2"; exit 1 ;; + esac + shift 2 ;; - s) - HOST_DIR=$OPTARG + -t|--tag-prefix) + TAG_PREFIX="$2" + shift 2 ;; - \?) - echo "Invalid option: -$OPTARG" >&2 - exit 1 + --) + if [ ! -z $2 ]; + then + echo "Invalid parameter: $2" + exit 1 + fi + break ;; - :) - echo "Option -$OPTARG requires an argument." >&2 + *) + echo "Invalid option" exit 1 ;; esac done -echo "Using $DOCKER_HUB_REPO:$TAG" -echo "Shared directory: ${HOST_DIR}" +echo "Using options:" +echo -e "\tROS distro: $ROS_DISTRO" +echo -e "\tImage name: $IMAGE_NAME" +echo -e "\tTag prefix: $TAG_PREFIX" +echo -e "\tCuda support: $CUDA" +echo -e "\tBase only: $BASE_ONLY" +echo -e "\tPre-release version: $PRE_RELEASE" + +SUFFIX="" +RUNTIME="" + +XSOCK=/tmp/.X11-unix +XAUTH=$HOME/.Xauthority + +SHARED_DOCKER_DIR=/home/autoware/shared_dir +SHARED_HOST_DIR=$HOME/shared_dir + +AUTOWARE_DOCKER_DIR=/home/autoware/Autoware +AUTOWARE_HOST_DIR=$(abspath "../..") + +VOLUMES="--volume=$XSOCK:$XSOCK:rw + --volume=$XAUTH:$XAUTH:rw + --volume=$SHARED_HOST_DIR:$SHARED_DOCKER_DIR:rw" + +if [ "$BASE_ONLY" == "true" ]; then + SUFFIX=$SUFFIX"-base" + VOLUMES="$VOLUMES --volume=$AUTOWARE_HOST_DIR:$AUTOWARE_DOCKER_DIR " +fi + +if [ $CUDA == "on" ]; then + SUFFIX=$SUFFIX"-cuda" + RUNTIME="--runtime=nvidia" +fi + +if [ $PRE_RELEASE == "on" ]; then + SUFFIX=$SUFFIX"-rc" +fi + +# Create the shared directory in advance to ensure it is owned by the host user +mkdir -p $SHARED_HOST_DIR + +IMAGE=$IMAGE_NAME:$TAG_PREFIX-$ROS_DISTRO$SUFFIX +echo "Launching $IMAGE" -nvidia-docker run \ +docker run \ -it --rm \ - --volume=$XSOCK:$XSOCK:rw \ - --volume=$XAUTH:$XAUTH:rw \ - --volume=$HOST_DIR:$SHARED_DIR:rw \ + $VOLUMES \ --env="XAUTHORITY=${XAUTH}" \ --env="DISPLAY=${DISPLAY}" \ - -u autoware \ - --privileged -v /dev/bus/usb:/dev/bus/usb \ + --env="USER_ID=$(id -u)" \ + --privileged \ --net=host \ - $DOCKER_HUB_REPO:$TAG + $RUNTIME \ + $IMAGE