diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index dc42355..27731f5 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -2,16 +2,10 @@ name: Docker on: push: - # Publish `master` as Docker `latest` image. branches: - - master - - # Publish `v1.2.3` tags as releases. + - jambonz tags: - - v* - -env: - IMAGE_NAME: rtpengine + - '*' jobs: push: @@ -20,32 +14,48 @@ jobs: if: github.event_name == 'push' steps: - - uses: actions/checkout@v2 - - - name: Build image - run: docker build . --file Dockerfile --tag $IMAGE_NAME + - name: Checkout code + uses: actions/checkout@v4 - - name: Log into registry - run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin - - - name: Push image + - name: prepare tag + id: prepare_tag run: | - IMAGE_ID=ghcr.io/${{ github.repository_owner }}/$IMAGE_NAME - - # Change all uppercase to lowercase - IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]') - - # Strip git ref prefix from version - VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,') - - # Strip "v" prefix from tag name - [[ "${{ github.ref }}" == "refs/tags/"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//') - - # Use Docker `latest` tag convention - [ "$VERSION" == "master" ] && VERSION=latest - - echo IMAGE_ID=$IMAGE_ID - echo VERSION=$VERSION - - docker tag $IMAGE_NAME $IMAGE_ID:$VERSION - docker push $IMAGE_ID:$VERSION + IMAGE_ID=jambonz/rtpengine + + # Strip git ref prefix from version + VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,') + + # Strip "v" prefix from tag name + [[ "${{ github.ref }}" == "refs/tags/"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//') + + # Use Docker `latest` tag convention + [ "$VERSION" == "jambonz" ] && VERSION=latest + + echo IMAGE_ID=$IMAGE_ID + echo VERSION=$VERSION + + echo "image_id=$IMAGE_ID" >> $GITHUB_OUTPUT + echo "version=$VERSION" >> $GITHUB_OUTPUT + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + with: + version: "lab:latest" + driver: cloud + endpoint: "drachtio/freeswitch-builder" + + - name: Build and push + uses: docker/build-push-action@v5 + with: + context: . + tags: ${{ steps.prepare_tag.outputs.image_id }}:${{ steps.prepare_tag.outputs.version }} + build-args: BUILD_CPUS=16 + # For pull requests, export results to the build cache. + # Otherwise, push to a registry. + outputs: ${{ github.event_name == 'pull_request' && 'type=cacheonly' || 'type=registry,push=true' }} diff --git a/Dockerfile b/Dockerfile index df46570..31be0e4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,16 +1,31 @@ -FROM debian:stretch - +FROM debian:bookworm-slim +ARG BUILD_CPUS=1 RUN apt-get update \ + && apt-get remove --auto-remove nftables \ + && apt-get purge nftables \ && apt-get -y --quiet --force-yes upgrade curl iproute2 \ - && apt-get install -y --no-install-recommends ca-certificates gcc g++ make build-essential git iptables-dev libavfilter-dev \ - libevent-dev libpcap-dev libxmlrpc-core-c3-dev markdown \ + && apt-get install -y --no-install-recommends ca-certificates gcc g++ make cmake build-essential git libavfilter-dev \ + libevent-dev libpcap-dev libxmlrpc-core-c3-dev markdown jq \ libjson-glib-dev default-libmysqlclient-dev libhiredis-dev libssl-dev \ - libcurl4-openssl-dev libavcodec-extra gperf libspandsp-dev libwebsockets-dev\ + libcurl4-openssl-dev libavcodec-extra gperf libspandsp-dev \ + libxtables-dev libip6tc-dev libip4tc-dev libiptc-dev \ + libjpeg-dev libsqlite3-dev libpcre3-dev libldns-dev libmnl-dev libnftnl-dev pandoc \ + libspeex-dev libspeexdsp-dev libedit-dev libtiff-dev yasm libswscale-dev haveged \ + libopus-dev libopusfile-dev libsndfile-dev libshout3-dev libmpg123-dev libmp3lame-dev \ + && cd /usr/local/src \ + && git clone https://github.com/BelledonneCommunications/bcg729.git \ + && cd bcg729 \ + && echo "building bcg729" \ + && cmake . -DCMAKE_INSTALL_PREFIX=/usr && make -j ${BUILD_CPUS} && make install \ && cd /usr/local/src \ - && git clone https://github.com/sipwise/rtpengine.git \ + && git clone https://github.com/warmcat/libwebsockets.git -b v4.3.3 \ + && cd /usr/local/src/libwebsockets \ + && mkdir -p build && cd build && cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=RelWithDebInfo && make -j ${BUILD_CPUS} && make install \ + && git clone https://github.com/sipwise/rtpengine.git -b mr11.5.1.31 \ && cd rtpengine/daemon \ - && make && make install \ - && cp /usr/local/src/rtpengine/daemon/rtpengine /usr/local/bin/rtpengine \ + && make -j ${BUILD_CPUS} with_transcoding=yes \ + && find . -name rtpengine \ + && cp rtpengine /usr/local/bin/rtpengine \ && rm -Rf /usr/local/src/rtpengine \ && apt-get purge -y --quiet --force-yes --auto-remove \ ca-certificates gcc g++ make build-essential git markdown \ @@ -23,12 +38,10 @@ RUN apt-get update \ VOLUME ["/tmp"] -EXPOSE 23000-32768/udp 22222/udp +EXPOSE 40000-60000/udp 22222/udp COPY ./entrypoint.sh /entrypoint.sh -COPY ./rtpengine.conf /etc - ENTRYPOINT ["/entrypoint.sh"] CMD ["rtpengine"] diff --git a/LICENSE b/LICENSE index 96a7461..cee71aa 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2017 Dave Horton +Copyright (c) 2017-2022 Dave Horton Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/entrypoint.sh b/entrypoint.sh index 78d4370..a760c9f 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -7,38 +7,81 @@ case $CLOUD in gcp) LOCAL_IP=$(curl -s -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/ip) PUBLIC_IP=$(curl -s -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/instance/network-interfaces/0/access-configs/0/external-ip) + PRIVATE_INTERFACE="private/${LOCAL_IP}" + PUBLIC_INTERFACE="public/${LOCAL_IP}!${PUBLIC_IP}" ;; aws) - LOCAL_IP=$(curl -s http://169.254.169.254/latest/meta-data/local-ipv4) - PUBLIC_IP=$(curl -s http://169.254.169.254/latest/meta-data/public-ipv4) - ;; - scaleway) - LOCAL_IP=$(curl -s --local-port 1-1024 http://169.254.42.42/conf | grep PRIVATE_IP | cut -d = -f 2) - PUBLIC_IP=$(curl -s --local-port 1-1024 http://169.254.42.42/conf | grep PUBLIC_IP_ADDRESS | cut -d = -f 2) + if [ -z "$IMDSv2" ]; then + LOCAL_IP=$(curl -s http://169.254.169.254/latest/meta-data/local-ipv4) + PUBLIC_IP=$(curl -s http://169.254.169.254/latest/meta-data/public-ipv4) + else + LOCAL_IP=$(TOKEN=`curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` && curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/local-ipv4) + PUBLIC_IP=$(TOKEN=`curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` && curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/public-ipv4) + fi + PRIVATE_INTERFACE="private/${LOCAL_IP}" + PUBLIC_INTERFACE="public/${LOCAL_IP}!${PUBLIC_IP}" ;; digitalocean) LOCAL_IP=$(curl -s http://169.254.169.254/metadata/v1/interfaces/private/0/ipv4/address) PUBLIC_IP=$(curl -s http://169.254.169.254/metadata/v1/interfaces/public/0/ipv4/address) + PRIVATE_INTERFACE="private/${LOCAL_IP}" + PUBLIC_INTERFACE="public/${PUBLIC_IP}" ;; azure) - LOCAL_IP=$(curl -H Metadata:true "http://169.254.169.254/metadata/instance/network/interface/0/ipv4/ipAddress/0/privateIpAddress?api-version=2017-08-01&format=text") - PUBLIC_IP=$(curl -H Metadata:true "http://169.254.169.254/metadata/instance/network/interface/0/ipv4/ipAddress/0/publicIpAddress?api-version=2017-08-01&format=text") + if [ "$LB_IMDS" = true ]; then + LOCAL_IP=$(curl -H "Metadata:true" --noproxy "*" "http://169.254.169.254:80/metadata/loadbalancer?api-version=2020-10-01&format=text" | jq -r '.loadbalancer.publicIpAddresses[0].privateIpAddress') + PUBLIC_IP=$(curl -H "Metadata:true" --noproxy "*" "http://169.254.169.254:80/metadata/loadbalancer?api-version=2020-10-01&format=text" | jq -r '.loadbalancer.publicIpAddresses[0].frontendIpAddress') + else + LOCAL_IP=$(curl -H Metadata:true "http://169.254.169.254/metadata/instance/network/interface/0/ipv4/ipAddress/0/privateIpAddress?api-version=2017-08-01&format=text") + PUBLIC_IP=$(curl -H Metadata:true "http://169.254.169.254/metadata/instance/network/interface/0/ipv4/ipAddress/0/publicIpAddress?api-version=2017-08-01&format=text") + fi + PRIVATE_INTERFACE="private/${LOCAL_IP}" + PUBLIC_INTERFACE="public/${LOCAL_IP}!${PUBLIC_IP}" + ;; + scaleway) + LOCAL_IP=$(curl -s --local-port 1-1024 http://169.254.42.42/conf | grep PRIVATE_IP | cut -d = -f 2) + PUBLIC_IP=$(curl -s --local-port 1-1024 http://169.254.42.42/conf | grep PUBLIC_IP_ADDRESS | cut -d = -f 2) + PRIVATE_INTERFACE="private/${LOCAL_IP}" + PUBLIC_INTERFACE="public/${LOCAL_IP}!${PUBLIC_IP}" ;; *) ;; esac -if [ -n "$PUBLIC_IP" ]; then - MY_IP="$LOCAL_IP"!"$PUBLIC_IP" -else - MY_IP=`ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1 -d'/'` +if [ -z "$PUBLIC_IP" ]; then + LOCAL_IP=`ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1 -d'/'` + PUBLIC_IP=`ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1 -d'/'` + PRIVATE_INTERFACE="private/${LOCAL_IP}" + PUBLIC_INTERFACE="public/${LOCAL_IP}!${PUBLIC_IP}" fi -sed -i -e "s/MY_IP/$MY_IP/g" /etc/rtpengine.conf +if [ -z "$RTP_START_PORT" ]; then + RTP_START_PORT=40000 +fi +if [ -z "$RTP_END_PORT" ]; then + RTP_END_PORT=60000 +fi +if [ -z "$LOGLEVEL" ]; then + LOGLEVEL=5 +fi + +echo "LOGLEVEL is $LOGLEVEL" if [ "$1" = 'rtpengine' ]; then shift - exec rtpengine --config-file /etc/rtpengine.conf "$@" + exec rtpengine \ + --interface ${PRIVATE_INTERFACE} --interface ${PUBLIC_INTERFACE} \ + --port-min ${RTP_START_PORT} --port-max ${RTP_END_PORT} \ + --log-level ${LOGLEVEL} --port-min ${RTP_START_PORT} --port-max ${RTP_END_PORT} \ + --listen-ng=22222 --listen-http=8080 --listen-udp=12222 \ + --dtmf-log-dest=127.0.0.1:22223 \ + --listen-cli=127.0.0.1:9900 \ + --pidfile /var/run/rtpengine.pid \ + --recording-dir /tmp --recording-method pcap --recording-format eth \ + --delete-delay 0 \ + --log-stderr \ + --foreground \ + $@ +else + exec "$@" fi - -exec "$@" diff --git a/rtpengine.conf b/rtpengine.conf deleted file mode 100644 index a2dae72..0000000 --- a/rtpengine.conf +++ /dev/null @@ -1,13 +0,0 @@ -[rtpengine] -interface=MY_IP -foreground=true -log-stderr=true -listen-ng=MY_IP:22222 -port-min=23000 -port-max=32768 -recording-dir=/tmp -recording-method=pcap -recording-format=eth -log-level=6 -delete-delay=0 -listen-http=MY_IP:8080