├── .gitignore ├── LICENSE ├── README.md ├── bin ├── mkbuilder.sh └── mkslim.sh └── etc ├── Dockerfile └── config.sh /.gitignore: -------------------------------------------------------------------------------- 1 | slim.report.json 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Ciprian Dosoftei 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | slimswitch 3 | 4 | 5 | # Build minimal FreeSWITCH Docker images 6 | 7 | [![Docker Pulls](https://img.shields.io/docker/pulls/rtckit/slimswitch-builder.svg)](https://hub.docker.com/r/rtckit/slimswitch-builder) 8 | [![License](https://img.shields.io/badge/license-MIT-blue)](LICENSE) 9 | 10 | Tooling for creating lean FreeSWITCH Docker images; resulting containers are efficient and expose a reduced attack surface. This is achieved by layering only the FreeSWITCH core, select modules and their runtime dependencies. 11 | 12 | ## Quickstart 13 | 14 | Decide which FreeSWITCH modules should be included and provide a basic XML core/modules configuration file! 15 | 16 | ```sh 17 | git clone https://github.com/rtckit/slimswitch.git 18 | cd slimswitch 19 | 20 | ./bin/mkslim.sh \ 21 | -m mod_commands -m mod_dptools -m mod_sofia \ 22 | -s local/awesome-switch 23 | docker run --rm -it \ 24 | -v "$(pwd)/freeswitch.xml":/etc/freeswitch/freeswitch.xml \ 25 | local/awesome-switch:v1.10.10 26 | ``` 27 | 28 | ![Quickstart](https://raw.github.com/rtckit/media/master/slimswitch/demo.gif) 29 | 30 | ## Requirements 31 | 32 | [Docker](https://docs.docker.com/get-docker/) and [slimtoolkit](https://slimtoolkit.org/) must be installed in the building environment. 33 | 34 | ## How it works 35 | 36 | A generic reusable [builder image](etc/Dockerfile) is created first; the goal is to build the FreeSWITCH core and most of its modules, so then they can be mixed-and-matched as needed. The resulting image can also serve as a base for compiling third party modules. This phase is handled by the [./bin/mkbuilder.sh](./bin/mkbuilder.sh) script. Images corresponding to official FreeSWITCH releases are also [publicly available](https://hub.docker.com/r/rtckit/slimswitch-builder). 37 | 38 | The trimming is achieved via the [./bin/mkslim.sh](./bin/mkslim.sh) script, which is essentially a wrapper for slimtoolkit; specifically, it leverages its static analysis features so dynamic dependencies are accounted for when the final image is created. 39 | 40 | ## License 41 | 42 | MIT, see [LICENSE file](LICENSE). 43 | 44 | ### Acknowledgments 45 | 46 | * [FreeSWITCH](https://github.com/signalwire/freeswitch), FreeSWITCH is a registered trademark of Anthony Minessale II 47 | * [Docker](https://docker.com), Docker is a registered trademark of Docker, Inc 48 | * [slimtoolkit](https://github.com/slimtoolkit/slim) 49 | 50 | ### Contributing 51 | 52 | Bug reports (and small patches) can be submitted via the [issue tracker](https://github.com/rtckit/slimswitch/issues). Forking the repository and submitting a Pull Request is preferred for substantial patches. 53 | -------------------------------------------------------------------------------- /bin/mkbuilder.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ETC_PATH="`dirname $0`"/../etc 4 | 5 | . ${ETC_PATH}/config.sh 6 | 7 | if [ ! -x "$(command -v docker)" ]; then 8 | printf "Cannot find docker\n" 9 | exit 1 10 | fi 11 | 12 | # Process arguments 13 | while :; do 14 | case $1 in 15 | -d) 16 | if [ -n "$2" ]; then 17 | DEBIAN_RELEASE=$2 18 | shift 19 | else 20 | printf "Cannot pass -d without Debian release argument (e.g. ${DEBIAN_RELEASE})\n" >&2 21 | exit 1 22 | fi 23 | ;; 24 | -t) 25 | if [ -n "$2" ]; then 26 | FREESWITCH_TAG=$2 27 | shift 28 | else 29 | printf "Cannot pass -t without FreeSWITCH tag argument (e.g. ${FREESWITCH_TAG})\n" >&2 30 | exit 1 31 | fi 32 | ;; 33 | -r) 34 | if [ -n "$2" ]; then 35 | BUILDER_REPOSITORY=$2 36 | shift 37 | else 38 | printf "Cannot pass -r without builder Docker image repository name argument (e.g. ${BUILDER_REPOSITORY})\n" >&2 39 | exit 1 40 | fi 41 | ;; 42 | -h) 43 | printf "slimswitch mkbuilder.sh utility\n" 44 | printf "https://github.com/rtckit/slimswitch\n\n" 45 | printf "Usage: %s [-d ] [-t ] [-r ]\n" "$0" 46 | printf "\t-d Base Debian image tag (default: %s)\n" "${DEBIAN_RELEASE}" 47 | printf "\t-t Builder image tag (default: %s)\n" "${FREESWITCH_TAG}" 48 | printf "\t-r Builder image repository (default: %s)\n" "${BUILDER_REPOSITORY}" 49 | exit 0 50 | ;; 51 | -?*) 52 | printf "Unknown argument %s\n" "$1" >&2 53 | exit 1 54 | ;; 55 | *) 56 | break 57 | esac 58 | 59 | shift 60 | done 61 | 62 | docker build \ 63 | --build-arg FREESWITCH_TAG=${FREESWITCH_TAG} \ 64 | -t ${BUILDER_REPOSITORY}:${FREESWITCH_TAG} \ 65 | -f ${ETC_PATH}/Dockerfile ${ETC_PATH} 66 | -------------------------------------------------------------------------------- /bin/mkslim.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ETC_PATH="`dirname $0`"/../etc 4 | 5 | . ${ETC_PATH}/config.sh 6 | 7 | if [ ! -x "$(command -v docker)" ]; then 8 | printf "Cannot find docker\n" 9 | exit 1 10 | fi 11 | 12 | if [ ! -x "$(command -v slim)" ]; then 13 | printf "Cannot find slim (slimtoolkit)\n" 14 | exit 1 15 | fi 16 | 17 | SLIM_REPOSITORY="" 18 | MODULE_FLAGS="" 19 | INCLUDE_FLAGS="" 20 | 21 | # Process arguments 22 | while :; do 23 | case $1 in 24 | -t) 25 | if [ -n "$2" ]; then 26 | FREESWITCH_TAG=$2 27 | shift 28 | else 29 | printf "Cannot pass -t without FreeSWITCH tag argument (e.g. ${FREESWITCH_TAG})\n" >&2 30 | exit 1 31 | fi 32 | ;; 33 | -r) 34 | if [ -n "$2" ]; then 35 | BUILDER_REPOSITORY=$2 36 | shift 37 | else 38 | printf "Cannot pass -r without builder Docker image repository name argument (e.g. ${BUILDER_REPOSITORY})\n" >&2 39 | exit 1 40 | fi 41 | ;; 42 | -s) 43 | if [ -n "$2" ]; then 44 | SLIM_REPOSITORY=$2 45 | shift 46 | else 47 | printf "Cannot pass -s without slim Docker image repository name argument\n" >&2 48 | exit 1 49 | fi 50 | ;; 51 | -m) 52 | if [ -n "$2" ]; then 53 | MODULE_FLAGS="${MODULE_FLAGS} --include-exe=/usr/lib/freeswitch/mod/$2.so" 54 | shift 55 | else 56 | printf "Cannot pass -m without FreeSWSITCH module name argument (e.g. mod_commands)\n" >&2 57 | exit 1 58 | fi 59 | ;; 60 | -i) 61 | if [ -n "$2" ]; then 62 | INCLUDE_FLAGS="${INCLUDE_FLAGS} --include-path=$2" 63 | shift 64 | else 65 | printf "Cannot pass -i without include path argument (e.g. /usr/share/freeswitch/sounds)\n" >&2 66 | exit 1 67 | fi 68 | ;; 69 | -h) 70 | printf "slimswitch mkslim.sh utility\n" 71 | printf "https://github.com/rtckit/slimswitch\n\n" 72 | printf "Usage: %s [-t ] [-r ] [-s ] [-m ] [-i ]\n" "$0" 73 | printf "\t-t Builder image tag (default: %s)\n" "${FREESWITCH_TAG}" 74 | printf "\t-r Builder image repository (default: %s)\n" "${BUILDER_REPOSITORY}" 75 | printf "\t-s Slim image repository (e.g. -s my-org/telco-project)\n" 76 | printf "\t-m FreeSWITCH module, can be used multiple times (e.g. -m mod_mariadb -m mod_shout)\n" 77 | printf "\t-i Keep path from builder image, can be used multiple times (e.g. -i /usr/share/freeswitch/sounds)\n" 78 | exit 0 79 | ;; 80 | -?*) 81 | printf "Unknown argument %s\n" "$1" >&2 82 | exit 1 83 | ;; 84 | *) 85 | break 86 | esac 87 | 88 | shift 89 | done 90 | 91 | docker image inspect ${BUILDER_REPOSITORY}:${FREESWITCH_TAG} > /dev/null 2>&1 92 | LOCAL_BUILDER=$? 93 | 94 | if [ $LOCAL_BUILDER -ne 0 ]; then 95 | printf "Local builder image not found, checking public DockerHub images ...\n" 96 | 97 | curl --silent -f -lSL https://index.docker.io/v1/repositories/${BUILDER_REPOSITORY}/tags/${FREESWITCH_TAG} > /dev/null 2>&1 98 | DOCKERHUB_BUILDER=$? 99 | 100 | if [ $DOCKERHUB_BUILDER -ne 0 ]; then 101 | printf "Builder image not found on DockerHub, creating it locally ...\n" 102 | "`dirname $0`"/mkbuilder.sh 103 | else 104 | printf "Pulling builder image from DockerHub ...\n" 105 | docker pull ${BUILDER_REPOSITORY}:${FREESWITCH_TAG} 106 | fi 107 | else 108 | printf "Using local builder docker image ...\n" 109 | fi 110 | 111 | if [ -z "$SLIM_REPOSITORY" ]; then 112 | SLIM_REPOSITORY=$(printf '%s' "$BUILDER_REPOSITORY" | sed -e 's/-builder/-slim/g') 113 | fi 114 | 115 | slim build \ 116 | --http-probe-off \ 117 | --continue-after 1 \ 118 | --include-cert-all \ 119 | --entrypoint=/bin/true \ 120 | --include-bin=/lib/x86_64-linux-gnu/libnss_dns.so.2 \ 121 | --include-exe=/usr/bin/freeswitch ${MODULE_FLAGS} \ 122 | ${INCLUDE_FLAGS} \ 123 | --exclude-pattern=/bin/true \ 124 | --target ${BUILDER_REPOSITORY}:${FREESWITCH_TAG} \ 125 | --tag ${SLIM_REPOSITORY}:${FREESWITCH_TAG} 126 | -------------------------------------------------------------------------------- /etc/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG DEBIAN_RELEASE=bookworm 2 | 3 | # Userland environment of choice 4 | FROM debian:${DEBIAN_RELEASE} 5 | 6 | # Git references for dependencies built from source 7 | ARG LIB_BROADVOICE_TAG=85752d8 8 | ARG LIB_ILBC_TAG=e186393 9 | ARG LIB_KS_TAG=v2.0.3 10 | ARG LIB_SILK_TAG=627102d 11 | ARG LIB_SPANDSP_TAG=d540fdf 12 | ARG LIB_SOFIA_TAG=v1.13.17 13 | ARG LIB_SW_C_CLIENT=v2.0.0 14 | 15 | # FreeSWITCH git reference 16 | ARG FREESWITCH_TAG=v1.10.10 17 | 18 | # Prerequisites 19 | RUN apt-get update && \ 20 | apt-get install -y autoconf automake build-essential bison cmake debhelper default-jdk devscripts doxygen dpkg-dev erlang-dev flite1-dev g++ gcc git ladspa-sdk libasound2-dev libavformat-dev libc6-dev libcodec2-dev libcurl4-openssl-dev libdb-dev libedit-dev libexpat1-dev libflac-dev libgdbm-compat-dev libgdbm-dev libglib2.0-dev libhiredis-dev libjpeg62-turbo-dev libldap2-dev libldns-dev liblua5.1-0-dev liblua5.2-dev libmagickcore-dev libmariadb-dev libmemcached-dev libmono-2.0-dev libmp3lame-dev libmpg123-dev libncurses5-dev libogg-dev libopencore-amrnb-dev libopencv-dev libopus-dev libopusfile-dev libpcre3-dev libperl-dev libpq-dev librabbitmq-dev libshout3-dev libsndfile1-dev libsnmp-dev libsoundtouch-dev libspeex-dev libspeexdsp-dev libsqlite3-dev libssl-dev libssl-dev libswscale-dev libtiff5-dev libtool libtool-bin libtpl-dev libnode-dev libvlc-dev libvorbis-dev libyaml-dev make mono-mcs pkg-config portaudio19-dev python3-dev python3-distutils-extra texlive unixodbc-dev uuid-dev wget yasm zlib1g-dev 21 | 22 | RUN mkdir -p /usr/src 23 | WORKDIR /usr/src 24 | 25 | # Build libbroadvoice 26 | RUN wget https://codeload.github.com/freeswitch/libbroadvoice/tar.gz/${LIB_BROADVOICE_TAG} -O - | tar zvx && \ 27 | cd /usr/src/libbroadvoice-${LIB_BROADVOICE_TAG} && \ 28 | ./autogen.sh && ./configure --prefix=/usr --disable-doc --enable-shared && \ 29 | make -j && make install 30 | 31 | # Build libilbc 32 | RUN wget https://codeload.github.com/freeswitch/libilbc/tar.gz/${LIB_ILBC_TAG} -O - | tar zvx && \ 33 | cd /usr/src/libilbc-${LIB_ILBC_TAG} && \ 34 | ./bootstrap.sh && ./configure --prefix=/usr --disable-doc --enable-shared && \ 35 | make -j && make install 36 | 37 | # Build libks 38 | RUN git clone -b ${LIB_KS_TAG} https://github.com/signalwire/libks.git && \ 39 | cd /usr/src/libks && \ 40 | cmake . -DCMAKE_INSTALL_PREFIX:PATH=/usr && \ 41 | make -j && make install 42 | 43 | # Build libsilk 44 | RUN wget https://codeload.github.com/freeswitch/libsilk/tar.gz/${LIB_SILK_TAG} -O - | tar zvx && \ 45 | cd /usr/src/libsilk-${LIB_SILK_TAG} && \ 46 | ./bootstrap.sh && ./configure --prefix=/usr --disable-doc --enable-shared && \ 47 | make -j && make install 48 | 49 | # Build libspandsp 50 | RUN wget https://codeload.github.com/freeswitch/spandsp/tar.gz/${LIB_SPANDSP_TAG} -O - | tar zvx && \ 51 | cd /usr/src/spandsp-${LIB_SPANDSP_TAG} && \ 52 | ./bootstrap.sh && ./configure --prefix=/usr --disable-doc --enable-shared && \ 53 | make -j && make install 54 | 55 | # Build libsofia 56 | RUN wget https://codeload.github.com/freeswitch/sofia-sip/tar.gz/${LIB_SOFIA_TAG} -O - | tar zvx && \ 57 | cd /usr/src/sofia-sip-* && \ 58 | ./autogen.sh && ./configure --prefix=/usr --disable-doc --enable-shared && \ 59 | make -j && make install 60 | 61 | # Build signalwire-c-client 62 | RUN git clone -b ${LIB_SW_C_CLIENT} https://github.com/signalwire/signalwire-c.git && \ 63 | cd /usr/src/signalwire-c && \ 64 | cmake . -DCMAKE_INSTALL_PREFIX:PATH=/usr && \ 65 | make -j && make install 66 | 67 | # Pull specific FreeSWITCH tag/release 68 | RUN wget https://codeload.github.com/signalwire/freeswitch/tar.gz/${FREESWITCH_TAG} -O - | tar zvx 69 | 70 | # Configure 71 | RUN cd /usr/src/freeswitch* && \ 72 | ./bootstrap.sh -j && \ 73 | ./configure --with-python3 --prefix=/usr --sysconfdir=/etc --localstatedir=/var --disable-debug 74 | 75 | # Enable most modules 76 | RUN cd /usr/src/freeswitch* && \ 77 | cp ./build/modules.conf.most modules.conf && \ 78 | sed -i \ 79 | -e "s/#databases\/mod_mariadb/databases\/mod_mariadb/g" \ 80 | -e "s/applications\/mod_mongo/#applications\/mod_mongo/g" \ 81 | -e "s/applications\/mod_mp4/#applications\/mod_mp4/g" \ 82 | -e "s/codecs\/mod_sangoma_codec/#codecs\/mod_sangoma_codec/g" \ 83 | -e "s/codecs\/mod_siren/#codecs\/mod_siren/g" \ 84 | modules.conf 85 | 86 | # Build and install 87 | RUN cd /usr/src/freeswitch* && make -j && make install 88 | 89 | # Install audio files 90 | RUN cd /usr/src/freeswitch* && make sounds-install && make moh-install 91 | 92 | ENTRYPOINT ["/usr/bin/freeswitch", "-nonat"] 93 | -------------------------------------------------------------------------------- /etc/config.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Default configuration 4 | export DEBIAN_RELEASE=bookworm 5 | export FREESWITCH_TAG=v1.10.10 6 | export BUILDER_REPOSITORY=rtckit/slimswitch-builder 7 | --------------------------------------------------------------------------------