diff --git a/docker/Dockerfile b/docker/Dockerfile index 7ecec3649..27cf03881 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -3,38 +3,228 @@ # # Base image Ubuntu 18.04 -FROM ubuntu:18.04 -ENV DEBIAN_FRONTEND=noninteractive -ENV MEDIA_SDK_VER=18.4.0 +FROM ubuntu:18.04 AS owt-build +WORKDIR /home + +# COMMON BUILD TOOLS +RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install -y -q --no-install-recommends build-essential autoconf make git wget pciutils cpio libtool lsb-release ca-certificates pkg-config bison flex libcurl4-gnutls-dev zlib1g-dev nasm yasm m4 autoconf libtool automake cmake libfreetype6-dev + + +# Build libnice +ARG NICE_VER="0.1.4" +ARG NICE_REPO=http://nice.freedesktop.org/releases/libnice-${NICE_VER}.tar.gz +ARG LIBNICE_PATCH_VER="4.3" +ARG LIBNICE_PATCH_REPO=https://github.com/open-webrtc-toolkit/owt-server/archive/v${LIBNICE_PATCH_VER}.tar.gz + +RUN apt-get update && apt-get install -y -q --no-install-recommends libglib2.0-dev + +RUN wget -O - ${NICE_REPO} | tar xz && \ + cd libnice-${NICE_VER} && \ + wget -O - ${LIBNICE_PATCH_REPO} | tar xz && \ + patch -p1 < owt-server-${LIBNICE_PATCH_VER}/scripts/patches/libnice014-agentlock.patch && \ + patch -p1 < owt-server-${LIBNICE_PATCH_VER}/scripts/patches/libnice014-agentlock-plus.patch && \ + patch -p1 < owt-server-${LIBNICE_PATCH_VER}/scripts/patches/libnice014-removecandidate.patch && \ + patch -p1 < owt-server-${LIBNICE_PATCH_VER}/scripts/patches/libnice014-keepalive.patch && \ + patch -p1 < owt-server-${LIBNICE_PATCH_VER}/scripts/patches/libnice014-startcheck.patch && \ + ./configure --prefix="/usr/local" --libdir=/usr/local/lib/x86_64-linux-gnu && \ + make -s V=0 && \ + make install + + +# Build open ssl +ARG OPENSSL_BASE="1.0.2" +ARG OPENSSL_VER="1.0.2t" +ARG OPENSSL_REPO=http://www.openssl.org/source/old/${OPENSSL_BASE}/openssl-${OPENSSL_VER}.tar.gz + +RUN wget -O - ${OPENSSL_REPO} | tar xz && \ + cd openssl-${OPENSSL_VER} && \ + ./config no-ssl3 --prefix="/usr/local" -fPIC && \ + make depend && \ + make -s V=0 && \ + make install + + +# Build libre +ARG LIBRE_VER="v0.4.16" +ARG LIBRE_REPO=https://github.com/creytiv/re.git + +RUN git clone ${LIBRE_REPO} && \ + cd re && \ + git checkout ${LIBRE_VER} && \ + make SYSROOT_ALT="/usr" RELEASE=1 && \ + make install SYSROOT_ALT="/usr" RELEASE=1 PREFIX="/usr" + + +# Build usrsctp +ARG USRSCTP_VERSION="30d7f1bd0b58499e1e1f2415e84d76d951665dc8" +ARG USRSCTP_FILE="${USRSCTP_VERSION}.tar.gz" +ARG USRSCTP_EXTRACT="usrsctp-${USRSCTP_VERSION}" +ARG USRSCTP_URL="https://github.com/sctplab/usrsctp/archive/${USRSCTP_FILE}" + +RUN wget -O - ${USRSCTP_URL} | tar xz && \ + mv ${USRSCTP_EXTRACT} usrsctp && \ + cd usrsctp && \ + ./bootstrap && \ + ./configure --prefix="/usr/local" --libdir=/usr/local/lib/x86_64-linux-gnu && \ + make && \ + make install + + +# Build libsrtp2 +ARG SRTP2_VER="2.1.0" +ARG SRTP2_REPO=https://codeload.github.com/cisco/libsrtp/tar.gz/v${SRTP2_VER} + +RUN apt-get update && apt-get install -y -q --no-install-recommends curl + +RUN curl -o libsrtp-${SRTP2_VER}.tar.gz ${SRTP2_REPO} && \ + tar xzf libsrtp-${SRTP2_VER}.tar.gz && \ + cd libsrtp-${SRTP2_VER} && \ + export PKG_CONFIG_PATH="/usr/local/lib/x86_64-linux-gnu/pkgconfig" && \ + export CFLAGS="-fPIC" && \ + ./configure --enable-openssl --prefix="/usr/local" --with-openssl-dir="/usr/local" && \ + make -s V=0 && \ + make install + + +# Fetch FFmpeg source +ARG FFMPEG_VER="4.1.3" +ARG FFMPEG_DIR="ffmpeg-${FFMPEG_VER}" +ARG FFMPEG_SRC="${FFMPEG_DIR}.tar.bz2" +ARG FFMPEG_SRC_URL="http://ffmpeg.org/releases/${FFMPEG_SRC}" +ARG FFMPEG_SRC_MD5SUM="9985185a8de3678e5b55b1c63276f8b5" + +RUN wget ${FFMPEG_SRC_URL} && tar xf ${FFMPEG_SRC} && mv ${FFMPEG_DIR} FFmpeg && \ + cd FFmpeg ; +# Compile FFmpeg +RUN cd /home/FFmpeg && \ + export PKG_CONFIG_PATH="/usr/local/lib/x86_64-linux-gnu/pkgconfig" && \ + ./configure --prefix="/usr/local" --libdir=/usr/local/lib/x86_64-linux-gnu --enable-shared --disable-static --disable-libvpx --disable-vaapi --enable-libfreetype && \ + make -j8 && \ + make install + + +# Install node +ARG NODE_VER=v8.15.0 +ARG NODE_REPO=https://nodejs.org/dist/${NODE_VER}/node-${NODE_VER}-linux-x64.tar.xz + +RUN wget ${NODE_REPO} && \ + tar xf node-${NODE_VER}-linux-x64.tar.xz && \ + cp node-*/* /usr/local -rf && rm -rf node-* + + +# Fetch SVT-HEVC +ARG SVT_HEVC_VER=v1.3.0 +ARG SVT_HEVC_REPO=https://github.com/intel/SVT-HEVC + +RUN git clone ${SVT_HEVC_REPO} && \ + cd SVT-HEVC/Build/linux && \ + export PKG_CONFIG_PATH="/usr/local/lib/x86_64-linux-gnu/pkgconfig" && \ + git checkout ${SVT_HEVC_VER} && \ + mkdir -p ../../Bin/Release && \ + cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local -DCMAKE_INSTALL_LIBDIR=lib/x86_64-linux-gnu -DCMAKE_ASM_NASM_COMPILER=yasm ../.. && \ + make -j8 && \ + make install + + +# Install json_hpp +ARG JSON_VER=v3.6.1 +ARG JSON_LINK=https://github.com/nlohmann/json/releases/download/${JSON_VER}/json.hpp + +RUN wget -c ${JSON_LINK} && mv json.hpp /usr/include/ + + +# Build OWT specific modules +ARG OWTSERVER_REPO=https://github.com/open-webrtc-toolkit/owt-server.git +ARG OPENH264_MAJOR=1 +ARG OPENH264_MINOR=7 +ARG OPENH264_SOVER=4 +ARG OPENH264_SOURCENAME=v${OPENH264_MAJOR}.${OPENH264_MINOR}.0.tar.gz +ARG OPENH264_SOURCE=https://github.com/cisco/openh264/archive/v${OPENH264_MAJOR}.${OPENH264_MINOR}.0.tar.gz +ARG OPENH264_BINARYNAME=libopenh264-${OPENH264_MAJOR}.${OPENH264_MINOR}.0-linux64.${OPENH264_SOVER}.so +ARG OPENH264_BINARY=https://github.com/cisco/openh264/releases/download/v${OPENH264_MAJOR}.${OPENH264_MINOR}.0/${OPENH264_BINARYNAME}.bz2 +ARG LICODE_COMMIT="8b4692c88f1fc24dedad66b4f40b1f3d804b50ca" +ARG LICODE_REPO=https://github.com/lynckia/licode.git +ARG WEBRTC_REPO=https://github.com/open-webrtc-toolkit/owt-deps-webrtc.git +ARG SVT_VER=v1.3.0 +ARG SVT_REPO=https://github.com/intel/SVT-HEVC.git +ARG SERVER_PATH=/home/owt-server +ARG OWT_SDK_REPO=https://github.com/open-webrtc-toolkit/owt-client-javascript.git +ARG OWT_BRANCH=master ARG IMG_APP_PATH=/app_data/ ENV APP_PATH=${IMG_APP_PATH} -# Update the system -RUN apt-get update +RUN apt-get update && apt-get install -y -q --no-install-recommends python libglib2.0-dev rabbitmq-server mongodb libboost-thread-dev libboost-system-dev liblog4cxx-dev + +# 1. Clone OWT server source code +# 2. Clone licode source code and patch +# 3. Clone webrtc source code and patch +RUN git config --global user.email "you@example.com" && \ + git config --global user.name "Your Name" && \ + git clone --depth=1 -b ${OWT_BRANCH} ${OWTSERVER_REPO} && \ + + # Install node modules for owt + npm install -g --loglevel error node-gyp grunt-cli underscore jsdoc && \ + cd owt-server && npm install nan && \ + + # Get openh264 for owt + cd third_party && \ + mkdir openh264 && cd openh264 && \ + wget ${OPENH264_SOURCE} && \ + wget ${OPENH264_BINARY} && \ + tar xzf ${OPENH264_SOURCENAME} openh264-${OPENH264_MAJOR}.${OPENH264_MINOR}.0/codec/api && \ + ln -s -v openh264-${OPENH264_MAJOR}.${OPENH264_MINOR}.0/codec codec && \ + bzip2 -d ${OPENH264_BINARYNAME}.bz2 && \ + ln -s -v ${OPENH264_BINARYNAME} libopenh264.so.${OPENH264_SOVER} && \ + ln -s -v libopenh264.so.${OPENH264_SOVER} libopenh264.so && \ + echo 'const char* stub() {return "this is a stub lib";}' > pseudo-openh264.cpp && \ + gcc pseudo-openh264.cpp -fPIC -shared -o pseudo-openh264.so + +# Get licode for owt +RUN cd ${SERVER_PATH}/third_party && git clone ${LICODE_REPO} && \ + cd licode && \ + git reset --hard ${LICODE_COMMIT} && \ + git am ${SERVER_PATH}/scripts/patches/licode/*.patch + +# Install webrtc for owt +RUN cd ${SERVER_PATH}/third_party && mkdir webrtc && cd webrtc &&\ + export GIT_SSL_NO_VERIFY=1 && \ + git clone -b 59-server ${WEBRTC_REPO} src && \ + ./src/tools-woogeen/install.sh && \ + ./src/tools-woogeen/build.sh + +# Install webrtc79 for owt +RUN mkdir ${SERVER_PATH}/third_party/webrtc-m79 && \ + cd ${SERVER_PATH}/third_party/webrtc-m79 && \ + /bin/bash ${SERVER_PATH}/scripts/installWebrtc.sh -# Install utils -RUN apt-get install -y ca-certificates git lsb-release mongodb nodejs npm sudo wget +# Get js client sdk for owt +RUN cd /home && git clone --depth=1 -b ${OWT_BRANCH} ${OWT_SDK_REPO} && cd owt-client-javascript/scripts && npm install && grunt && \ + mkdir ${SERVER_PATH}/third_party/quic-lib && \ + export LD_LIBRARY_PATH=/usr/local/lib/x86_64-linux-gnu && \ + cd ${SERVER_PATH}/third_party/quic-lib && wget https://github.com/open-webrtc-toolkit/owt-deps-quic/releases/download/v0.1/dist.tgz && tar xzf dist.tgz && \ + #Build and pack owt + cd ${SERVER_PATH} && export PKG_CONFIG_PATH=/usr/local/lib/x86_64-linux-gnu/pkgconfig && ./scripts/build.js -t mcu-all -r -c && \ + ./scripts/pack.js -t all --install-module --no-pseudo --app-path /home/owt-client-javascript/dist/samples/conference -RUN npm install -g grunt-cli node-gyp -# Keep proxy environment for sudo -RUN bash -c "echo \"Defaults env_keep = \\\"http_proxy https_proxy no_proxy \\\"\" >> /etc/sudoers" -RUN wget https://github.com/Intel-Media-SDK/MediaSDK/releases/download/intel-mediasdk-$MEDIA_SDK_VER/MediaStack.tar.gz -P /tmp -RUN cd /tmp && tar -zxf MediaStack.tar.gz && cd MediaStack && ./install_media.sh -RUN rm /tmp/MediaStack.tar.gz && rm -rf /tmp/MediaStack -ENV MFX_HOME=/opt/intel/mediasdk +FROM ubuntu:18.04 AS owt-run +LABEL Description="This is the image for building OWT on Ubuntu 18.04" +LABEL Vendor="Intel Corporation" +WORKDIR /home -RUN git clone https://github.com/open-webrtc-toolkit/owt-server.git --depth=1 -RUN mkdir -p ${APP_PATH} +# Prerequisites +# Install node +ARG NODE_VER=v8.15.0 +ARG NODE_REPO=https://nodejs.org/dist/${NODE_VER}/node-${NODE_VER}-linux-x64.tar.xz -WORKDIR /owt-server +COPY --from=owt-build /home/owt-server/dist /home/owt +COPY startowt.sh /home/ -# This is needed to patch licode -RUN git config --global user.email "you@example.com" && \ - git config --global user.name "Your Name" +RUN apt-get update && apt-get install -y -q --no-install-recommends ca-certificates wget xz-utils rabbitmq-server mongodb libboost-system-dev libboost-thread-dev liblog4cxx-dev libglib2.0-0 libfreetype6-dev curl -RUN ./scripts/installDepsUnattended.sh +RUN wget ${NODE_REPO} && \ + tar xf node-${NODE_VER}-linux-x64.tar.xz && \ + cp node-*/* /usr/local -rf && rm -rf node-* -# Set workpath to where the app should be installed for the next step of the multibuild -WORKDIR ${APP_PATH} +ENV LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/x86_64-linux-gnu diff --git a/docker/README.md b/docker/README.md new file mode 100644 index 000000000..567a471da --- /dev/null +++ b/docker/README.md @@ -0,0 +1,53 @@ +This document is used for generating OWT build and all-in-one OWT running environment images. + +## Prequisites + + * Docker is setup in your local environment and related proxy is set so that Docker can access to external network (including Google because OWT will download WebRTC related code and patch from Google) + +## Build OWT images + +1. Run following command to generate Docker image containing OWT source code and dependencies. A dist folder will be generated with all OWT running binaries. You can run OWT service using this image directly in case you want to modify OWT source code and debug. + + ```shell + docker build --target owt-build -t owt:build \ + --build-arg http_proxy=${HTTP_PROXY} \ + --build-arg https_proxy=${HTTPS_PROXY} \ + . + ``` +The default sample web app will be packed into the OWT package, you can modify Dockerfile to copy your own web app into the image and specify your app path in pack.js: + +``` + ./scripts/pack.js -t all --install-module --no-pseudo --app-path /home/owt-client-javascript/dist/samples/conference +``` +Or you can refer conference/build_server.sh to see how to use docker swarm to pack your app into image. + +2. Run following command to generate OWT running environment Docker image with OWT binaries generated in step 1, not including source code. + ```shell + docker build --target owt-run -t owt:run \ + --build-arg http_proxy=${HTTP_PROXY} \ + --build-arg https_proxy=${HTTPS_PROXY} \ + . + ``` +Or you can simply run `build_docker_image.sh` to generate both 2 images. +We provide a `startowt.sh` to launch OWT and expose following parameters to configure: + +``` + --rabbit rabbitmq server address if rabbitmq service is deployed on a different device + --mongo mongodb server address if mongo service is deployed on a different device, like --mongo=xx.xx.xx.xx/owtdb + --externalip external ip of host device if there are internal and external ip for host device + --network_interface network interface for external ip of host device if there are external and internal ip for host device +``` +Note that `externalip` and `network_interface` should be both set if there are external and internal ip on host device. `startowt.sh` is just a reference, you can customize Dockerfile and script to generate the Docker images for cluster deployment. For example, separate each OWT modules into different Docker images. + +2. Launch OWT service + + a) Launch a Docker container with following command to simply try OWT: + + ```shell + docker run -itd --name=owt --net=host owt:run /home/startowt.sh + ``` + Then OWT service should be launched and you can connect to https://localhost:3004 to start your OWT journey. + + b) Launch OWT service with Docker swarm with script ```conference/build_server.sh``` + + c) Customize different OWT module images and launch OWT service with Kubernetes. \ No newline at end of file diff --git a/docker/build_docker_image.sh b/docker/build_docker_image.sh new file mode 100755 index 000000000..8d8ae2e43 --- /dev/null +++ b/docker/build_docker_image.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +docker build --target owt-build -t owt:build \ + --build-arg http_proxy=${HTTP_PROXY} \ + --build-arg https_proxy=${HTTPS_PROXY} \ + . + +docker build --target owt-run -t owt:run \ + --build-arg http_proxy=${HTTP_PROXY} \ + --build-arg https_proxy=${HTTPS_PROXY} \ + . diff --git a/docker/startowt.sh b/docker/startowt.sh new file mode 100755 index 000000000..91f8c848a --- /dev/null +++ b/docker/startowt.sh @@ -0,0 +1,74 @@ +#!/bin/bash + +# change workdir +cd /home/owt + +mongourl=localhost/owtdb +LOG=/dev/null + +service mongodb start & +service rabbitmq-server start & + +while ! mongo --quiet --eval "db.adminCommand('listDatabases')" >>$LOG 2>&1 +do + echo mongo is not ready. Waiting + sleep 1 +done + +while ! rabbitmqctl -q status >> $LOG 2>&1 +do + echo RabbitMQ is not ready. Waiting... + sleep 1 +done + +# format the parameters +set -- $(getopt -u -l rabbit:,mongo:,hostname:,externalip:,network_interface:: -- -- "$@") +# get the parameters +while [ -n "$1" ] +do + case "$1" in + --rabbit ) rabbitmqip=$2; shift; shift ;; + --mongo ) mongourl=$2; shift; shift ;; + --hostname ) hostname=$2; shift; shift ;; + --externalip ) externalip=$2; shift; shift ;; + --network_interface ) networkinterface=$2; shift; shift ;; + * ) break;; + esac +done + +alltoml=$(find . -maxdepth 2 -name "*.toml") +echo ${mongourl} +echo ${rabbitmqip} +for toml in $alltoml; do + if [ ! -z "${mongourl}" ];then + sed -i "/^dataBaseURL = /c \dataBaseURL = \"${mongourl}\"" $toml + fi + + if [ ! -z "${rabbitmqip}" ];then + if [[ $toml == *"management_console"* ]]; then + echo "Do not modify management_console" + else + sed -i "/^host = /c \host = \"${rabbitmqip}\"" $toml + fi + + fi +done + +if [ ! -z "${hostname}" ];then + echo ${hostname} + sed -i "/^hostname = /c \hostname = \"${hostname}\"" portal/portal.toml +fi + +if [ ! -z "${externalip}" ] && [ ! -z "{network_interface}" ];then + echo ${externalip} + sed -i "/^network_interfaces =/c \network_interfaces = [{name = \"${networkinterface}\", replaced_ip_address = \"${externalip}\"}]" webrtc_agent/agent.toml + sed -i "/^ip_address = /c \ip_address = \"${externalip}\"" portal/portal.toml +fi + +./management_api/init.sh --dburl=${mongourl} + +./video_agent/install_openh264.sh + +./bin/start-all.sh + +sleep infinity