From b02ce204da0008d970a31b04a2e2ff64fbcf6f30 Mon Sep 17 00:00:00 2001 From: Stephen DeRosa Date: Thu, 9 Apr 2026 21:13:07 -0600 Subject: [PATCH 1/4] docker base image --- .github/workflows/builds.yml | 44 +-- .github/workflows/docker-images.yml | 363 +++++++++++++++++++++++++ .github/workflows/docker-validate.yml | 111 ++++++++ docker/{Dockerfile => Dockerfile.base} | 36 +-- docker/Dockerfile.sdk | 56 ++++ 5 files changed, 560 insertions(+), 50 deletions(-) create mode 100644 .github/workflows/docker-images.yml create mode 100644 .github/workflows/docker-validate.yml rename docker/{Dockerfile => Dockerfile.base} (66%) create mode 100644 docker/Dockerfile.sdk diff --git a/.github/workflows/builds.yml b/.github/workflows/builds.yml index 7d307c7..8abfbbe 100644 --- a/.github/workflows/builds.yml +++ b/.github/workflows/builds.yml @@ -14,7 +14,8 @@ on: - build.cmd - vcpkg.json - CMakePresets.json - - docker/Dockerfile + - docker/Dockerfile.base + - docker/Dockerfile.sdk - .github/workflows/** pull_request: branches: ["main"] @@ -29,7 +30,8 @@ on: - build.cmd - vcpkg.json - CMakePresets.json - - docker/Dockerfile + - docker/Dockerfile.base + - docker/Dockerfile.sdk - .github/workflows/** workflow_dispatch: @@ -306,6 +308,7 @@ jobs: docker-build-x64: name: Build (docker-linux-x64) runs-on: ubuntu-latest + if: github.event_name == 'pull_request' steps: - name: Checkout (with submodules) @@ -325,17 +328,20 @@ jobs: docker-images: true swap-storage: true - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 + - name: Build base Docker image + run: | + docker build \ + -t livekit-cpp-sdk-base-x64:${{ github.sha }} \ + -f docker/Dockerfile.base \ + docker - - name: Build Docker image + - name: Build SDK Docker image run: | - docker buildx build \ - --platform linux/amd64 \ - --load \ + docker build \ + --build-arg BASE_IMAGE=livekit-cpp-sdk-base-x64:${{ github.sha }} \ -t livekit-cpp-sdk-x64:${{ github.sha }} \ . \ - -f docker/Dockerfile + -f docker/Dockerfile.sdk - name: Verify installed SDK inside image run: | @@ -356,6 +362,7 @@ jobs: docker-build-linux-arm64: name: Build (docker-linux-arm64) runs-on: ubuntu-24.04-arm + if: github.event_name == 'pull_request' steps: - name: Checkout (with submodules) @@ -375,17 +382,20 @@ jobs: docker-images: true swap-storage: true - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 + - name: Build base Docker image + run: | + docker build \ + -t livekit-cpp-sdk-base-arm64:${{ github.sha }} \ + -f docker/Dockerfile.base \ + docker - - name: Build Docker image + - name: Build SDK Docker image run: | - docker buildx build \ - --platform linux/arm64 \ - --load \ + docker build \ + --build-arg BASE_IMAGE=livekit-cpp-sdk-base-arm64:${{ github.sha }} \ -t livekit-cpp-sdk:${{ github.sha }} \ . \ - -f docker/Dockerfile + -f docker/Dockerfile.sdk - name: Verify installed SDK inside image run: | @@ -407,6 +417,7 @@ jobs: name: Build (cpp-example-collection-linux-arm64) runs-on: ubuntu-24.04-arm needs: docker-build-linux-arm64 + if: github.event_name == 'pull_request' steps: - name: Download Docker image artifact @@ -433,6 +444,7 @@ jobs: name: Build (cpp-example-collection-x64) runs-on: ubuntu-latest needs: docker-build-x64 + if: github.event_name == 'pull_request' steps: - name: Download Docker image artifact diff --git a/.github/workflows/docker-images.yml b/.github/workflows/docker-images.yml new file mode 100644 index 0000000..acbcdfc --- /dev/null +++ b/.github/workflows/docker-images.yml @@ -0,0 +1,363 @@ +name: Docker Images + +on: + push: + branches: ["main"] + paths: + - src/** + - include/** + - bridge/** + - client-sdk-rust/** + - CMakeLists.txt + - build.sh + - build.cmd + - build.h.in + - CMakePresets.json + - cmake/** + - data/** + - docker/Dockerfile.base + - docker/Dockerfile.sdk + +permissions: + contents: read + packages: write + +jobs: + detect-changes: + name: Detect Docker image changes + runs-on: ubuntu-latest + outputs: + base_changed: ${{ steps.changes.outputs.base_changed }} + sdk_changed: ${{ steps.changes.outputs.sdk_changed }} + base_hash: ${{ steps.hash.outputs.base_hash }} + base_image: ${{ steps.refs.outputs.base_image }} + sdk_image: ${{ steps.refs.outputs.sdk_image }} + steps: + - name: Checkout + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 + with: + fetch-depth: 0 + + - name: Resolve GHCR image names + id: refs + shell: bash + run: | + set -euo pipefail + owner="$(echo "${GITHUB_REPOSITORY_OWNER}" | tr '[:upper:]' '[:lower:]')" + echo "base_image=ghcr.io/${owner}/client-sdk-cpp-base" >> "$GITHUB_OUTPUT" + echo "sdk_image=ghcr.io/${owner}/client-sdk-cpp" >> "$GITHUB_OUTPUT" + + - name: Hash base Dockerfile + id: hash + shell: bash + run: | + set -euo pipefail + base_hash="$(shasum -a 256 docker/Dockerfile.base | awk '{print substr($1,1,12)}')" + echo "base_hash=${base_hash}" >> "$GITHUB_OUTPUT" + + - name: Detect changed inputs + id: changes + shell: bash + run: | + set -euo pipefail + + if [[ "${{ github.event.before }}" == "0000000000000000000000000000000000000000" ]]; then + changed_files="$(git ls-tree -r --name-only "${{ github.sha }}")" + else + changed_files="$(git diff --name-only "${{ github.event.before }}" "${{ github.sha }}")" + fi + + echo "Changed files:" + if [[ -n "${changed_files}" ]]; then + while IFS= read -r path; do + [[ -z "${path}" ]] && continue + echo " ${path}" + done <<< "${changed_files}" + else + echo " " + fi + + base_changed=false + sdk_changed=false + + while IFS= read -r path; do + [[ -z "${path}" ]] && continue + + if [[ "${path}" == "docker/Dockerfile.base" ]]; then + base_changed=true + sdk_changed=true + fi + + case "${path}" in + docker/Dockerfile.sdk|src/*|include/*|bridge/*|client-sdk-rust/*|cmake/*|data/*|CMakeLists.txt|build.sh|build.cmd|build.h.in|CMakePresets.json) + sdk_changed=true + ;; + esac + done <<< "${changed_files}" + + echo "base_changed=${base_changed}" >> "$GITHUB_OUTPUT" + echo "sdk_changed=${sdk_changed}" >> "$GITHUB_OUTPUT" + + build-base-amd64: + name: Publish base image (amd64) + runs-on: ubuntu-latest + needs: detect-changes + if: needs.detect-changes.outputs.base_changed == 'true' + + steps: + - name: Checkout + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 + + - name: Free disk space + uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 + with: + tool-cache: false + android: true + dotnet: true + haskell: true + large-packages: true + docker-images: true + swap-storage: true + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 + + - name: Login to GHCR + shell: bash + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + set -euo pipefail + echo "${GITHUB_TOKEN}" | docker login ghcr.io -u "${{ github.actor }}" --password-stdin + + - name: Build and push base image + shell: bash + run: | + set -euxo pipefail + docker buildx build \ + --platform linux/amd64 \ + --push \ + -t "${{ needs.detect-changes.outputs.base_image }}:base-${{ needs.detect-changes.outputs.base_hash }}-amd64" \ + -t "${{ needs.detect-changes.outputs.base_image }}:base-main-amd64" \ + -f docker/Dockerfile.base \ + docker + + build-base-arm64: + name: Publish base image (arm64) + runs-on: ubuntu-24.04-arm + needs: detect-changes + if: needs.detect-changes.outputs.base_changed == 'true' + + steps: + - name: Checkout + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 + + - name: Free disk space + uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 + with: + tool-cache: false + android: true + dotnet: true + haskell: true + large-packages: true + docker-images: true + swap-storage: true + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 + + - name: Login to GHCR + shell: bash + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + set -euo pipefail + echo "${GITHUB_TOKEN}" | docker login ghcr.io -u "${{ github.actor }}" --password-stdin + + - name: Build and push base image + shell: bash + run: | + set -euxo pipefail + docker buildx build \ + --platform linux/arm64 \ + --push \ + -t "${{ needs.detect-changes.outputs.base_image }}:base-${{ needs.detect-changes.outputs.base_hash }}-arm64" \ + -t "${{ needs.detect-changes.outputs.base_image }}:base-main-arm64" \ + -f docker/Dockerfile.base \ + docker + + publish-base-manifest: + name: Publish base manifest + runs-on: ubuntu-latest + needs: + - detect-changes + - build-base-amd64 + - build-base-arm64 + if: needs.detect-changes.outputs.base_changed == 'true' + + steps: + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 + + - name: Login to GHCR + shell: bash + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + set -euo pipefail + echo "${GITHUB_TOKEN}" | docker login ghcr.io -u "${{ github.actor }}" --password-stdin + + - name: Publish base manifest tags + shell: bash + run: | + set -euxo pipefail + docker buildx imagetools create \ + -t "${{ needs.detect-changes.outputs.base_image }}:base-${{ needs.detect-changes.outputs.base_hash }}" \ + -t "${{ needs.detect-changes.outputs.base_image }}:base-main" \ + "${{ needs.detect-changes.outputs.base_image }}:base-${{ needs.detect-changes.outputs.base_hash }}-amd64" \ + "${{ needs.detect-changes.outputs.base_image }}:base-${{ needs.detect-changes.outputs.base_hash }}-arm64" + + build-sdk-amd64: + name: Publish SDK image (amd64) + runs-on: ubuntu-latest + needs: + - detect-changes + - build-base-amd64 + if: | + always() && + needs.detect-changes.outputs.sdk_changed == 'true' && + needs.build-base-amd64.result != 'failure' && + needs.build-base-amd64.result != 'cancelled' + + steps: + - name: Checkout + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 + with: + submodules: recursive + fetch-depth: 0 + + - name: Free disk space + uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 + with: + tool-cache: false + android: true + dotnet: true + haskell: true + large-packages: true + docker-images: true + swap-storage: true + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 + + - name: Login to GHCR + shell: bash + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + set -euo pipefail + echo "${GITHUB_TOKEN}" | docker login ghcr.io -u "${{ github.actor }}" --password-stdin + + - name: Build and push SDK image + shell: bash + run: | + set -euxo pipefail + docker buildx build \ + --platform linux/amd64 \ + --build-arg BASE_IMAGE="${{ needs.detect-changes.outputs.base_image }}:base-${{ needs.detect-changes.outputs.base_hash }}-amd64" \ + --push \ + -t "${{ needs.detect-changes.outputs.sdk_image }}:sha-${{ github.sha }}-amd64" \ + -t "${{ needs.detect-changes.outputs.sdk_image }}:main-amd64" \ + . \ + -f docker/Dockerfile.sdk + + build-sdk-arm64: + name: Publish SDK image (arm64) + runs-on: ubuntu-24.04-arm + needs: + - detect-changes + - build-base-arm64 + if: | + always() && + needs.detect-changes.outputs.sdk_changed == 'true' && + needs.build-base-arm64.result != 'failure' && + needs.build-base-arm64.result != 'cancelled' + + steps: + - name: Checkout + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 + with: + submodules: recursive + fetch-depth: 0 + + - name: Free disk space + uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 + with: + tool-cache: false + android: true + dotnet: true + haskell: true + large-packages: true + docker-images: true + swap-storage: true + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 + + - name: Login to GHCR + shell: bash + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + set -euo pipefail + echo "${GITHUB_TOKEN}" | docker login ghcr.io -u "${{ github.actor }}" --password-stdin + + - name: Build and push SDK image + shell: bash + run: | + set -euxo pipefail + docker buildx build \ + --platform linux/arm64 \ + --build-arg BASE_IMAGE="${{ needs.detect-changes.outputs.base_image }}:base-${{ needs.detect-changes.outputs.base_hash }}-arm64" \ + --push \ + -t "${{ needs.detect-changes.outputs.sdk_image }}:sha-${{ github.sha }}-arm64" \ + -t "${{ needs.detect-changes.outputs.sdk_image }}:main-arm64" \ + . \ + -f docker/Dockerfile.sdk + + publish-sdk-manifest: + name: Publish SDK manifest + runs-on: ubuntu-latest + needs: + - detect-changes + - build-sdk-amd64 + - build-sdk-arm64 + if: | + always() && + needs.detect-changes.outputs.sdk_changed == 'true' && + needs.build-sdk-amd64.result != 'failure' && + needs.build-sdk-amd64.result != 'cancelled' && + needs.build-sdk-arm64.result != 'failure' && + needs.build-sdk-arm64.result != 'cancelled' + + steps: + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 + + - name: Login to GHCR + shell: bash + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + set -euo pipefail + echo "${GITHUB_TOKEN}" | docker login ghcr.io -u "${{ github.actor }}" --password-stdin + + - name: Publish SDK manifest tags + shell: bash + run: | + set -euxo pipefail + docker buildx imagetools create \ + -t "${{ needs.detect-changes.outputs.sdk_image }}:sha-${{ github.sha }}" \ + -t "${{ needs.detect-changes.outputs.sdk_image }}:main" \ + "${{ needs.detect-changes.outputs.sdk_image }}:sha-${{ github.sha }}-amd64" \ + "${{ needs.detect-changes.outputs.sdk_image }}:sha-${{ github.sha }}-arm64" diff --git a/.github/workflows/docker-validate.yml b/.github/workflows/docker-validate.yml new file mode 100644 index 0000000..68ce475 --- /dev/null +++ b/.github/workflows/docker-validate.yml @@ -0,0 +1,111 @@ +name: Docker Validate + +on: + workflow_run: + workflows: ["Docker Images"] + types: [completed] + +permissions: + contents: read + packages: read + +env: + # Pinned commit for cpp-example-collection smoke build (https://github.com/livekit-examples/cpp-example-collection) + CPP_EXAMPLE_COLLECTION_REF: f231c0c75028d1dcf13edcecd369d030d2c7c8d4 + +jobs: + validate-x64: + name: Validate Docker image (linux-x64) + runs-on: ubuntu-latest + if: | + github.event.workflow_run.conclusion == 'success' && + github.event.workflow_run.event == 'push' && + github.event.workflow_run.head_branch == 'main' + + steps: + - name: Resolve image name + id: refs + shell: bash + run: | + set -euo pipefail + owner="$(echo "${GITHUB_REPOSITORY_OWNER}" | tr '[:upper:]' '[:lower:]')" + echo "sdk_image=ghcr.io/${owner}/client-sdk-cpp:sha-${{ github.event.workflow_run.head_sha }}" >> "$GITHUB_OUTPUT" + + - name: Login to GHCR + shell: bash + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + set -euo pipefail + echo "${GITHUB_TOKEN}" | docker login ghcr.io -u "${{ github.actor }}" --password-stdin + + - name: Pull SDK image + shell: bash + run: | + set -euxo pipefail + time docker pull "${{ steps.refs.outputs.sdk_image }}" + + - name: Verify installed SDK inside image + run: | + docker run --rm "${{ steps.refs.outputs.sdk_image }}" bash -c \ + 'test -f /opt/livekit-sdk/lib/cmake/LiveKit/LiveKitConfig.cmake' + + - name: Build cpp-example-collection against installed SDK + run: | + docker run -e CPP_EX_REF="${{ env.CPP_EXAMPLE_COLLECTION_REF }}" --rm "${{ steps.refs.outputs.sdk_image }}" bash -lc ' + set -euxo pipefail + git clone https://github.com/livekit-examples/cpp-example-collection.git /tmp/cpp-example-collection + cd /tmp/cpp-example-collection + git fetch --depth 1 origin "$CPP_EX_REF" + git checkout "$CPP_EX_REF" + cmake -S . -B build -DLIVEKIT_LOCAL_SDK_DIR=/opt/livekit-sdk + cmake --build build --parallel + ' + + validate-arm64: + name: Validate Docker image (linux-arm64) + runs-on: ubuntu-24.04-arm + if: | + github.event.workflow_run.conclusion == 'success' && + github.event.workflow_run.event == 'push' && + github.event.workflow_run.head_branch == 'main' + + steps: + - name: Resolve image name + id: refs + shell: bash + run: | + set -euo pipefail + owner="$(echo "${GITHUB_REPOSITORY_OWNER}" | tr '[:upper:]' '[:lower:]')" + echo "sdk_image=ghcr.io/${owner}/client-sdk-cpp:sha-${{ github.event.workflow_run.head_sha }}" >> "$GITHUB_OUTPUT" + + - name: Login to GHCR + shell: bash + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + set -euo pipefail + echo "${GITHUB_TOKEN}" | docker login ghcr.io -u "${{ github.actor }}" --password-stdin + + - name: Pull SDK image + shell: bash + run: | + set -euxo pipefail + time docker pull "${{ steps.refs.outputs.sdk_image }}" + + - name: Verify installed SDK inside image + run: | + docker run --rm "${{ steps.refs.outputs.sdk_image }}" bash -c \ + 'test -f /opt/livekit-sdk/lib/cmake/LiveKit/LiveKitConfig.cmake' + + - name: Build cpp-example-collection against installed SDK + run: | + docker run -e CPP_EX_REF="${{ env.CPP_EXAMPLE_COLLECTION_REF }}" --rm "${{ steps.refs.outputs.sdk_image }}" bash -lc ' + set -euxo pipefail + git clone https://github.com/livekit-examples/cpp-example-collection.git /tmp/cpp-example-collection + cd /tmp/cpp-example-collection + git fetch --depth 1 origin "$CPP_EX_REF" + git checkout "$CPP_EX_REF" + cmake -S . -B build -DLIVEKIT_LOCAL_SDK_DIR=/opt/livekit-sdk + cmake --build build --parallel + ' diff --git a/docker/Dockerfile b/docker/Dockerfile.base similarity index 66% rename from docker/Dockerfile rename to docker/Dockerfile.base index d2bd116..aa252ef 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile.base @@ -13,16 +13,15 @@ # limitations under the License. # # Build with: -# docker build -t livekit-cpp-sdk . -f docker/Dockerfile +# docker build -t livekit-cpp-sdk-base . -f docker/Dockerfile.base # From repo root. # Run with: -# docker run -it --network host livekit-cpp-sdk:latest bash +# docker run -it --network host livekit-cpp-sdk-base:latest bash FROM ubuntu:22.04 ENV DEBIAN_FRONTEND=noninteractive ENV HOME=/root -ENV SDK_INSTALL_PREFIX=/opt/livekit-sdk # Install make, pkg-config, and base build deps (pkg-config + libglib2.0-dev for Rust glib-sys, libasound2-dev for alsa-sys) RUN apt-get update && apt-get install -y --no-install-recommends \ @@ -106,34 +105,3 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ libxi-dev \ libxrandr-dev \ && rm -rf /var/lib/apt/lists/* - -# Copy project source (build context = repo root) -WORKDIR /client-sdk-cpp -RUN mkdir -p /client-sdk-cpp -COPY src /client-sdk-cpp/src -COPY include /client-sdk-cpp/include -COPY bridge /client-sdk-cpp/bridge -COPY build.sh /client-sdk-cpp/build.sh -COPY CMakePresets.json /client-sdk-cpp/CMakePresets.json -COPY build.cmd /client-sdk-cpp/build.cmd -COPY client-sdk-rust /client-sdk-cpp/client-sdk-rust -COPY data /client-sdk-cpp/data -COPY cmake /client-sdk-cpp/cmake -COPY CMakeLists.txt /client-sdk-cpp/CMakeLists.txt -COPY build.h.in /client-sdk-cpp/build.h.in - -# Configure Rust linker: use full GCC path so liblto_plugin.so is found (not /home/installs/ which has no plugin) -RUN mkdir -p /client-sdk-cpp/client-sdk-rust/.cargo \ - && printf '%s\n' '[target.x86_64-unknown-linux-gnu]' 'linker = "/root/gcc-14/bin/g++"' \ - '[target.aarch64-unknown-linux-gnu]' 'linker = "/root/gcc-14/bin/g++"' > /client-sdk-cpp/client-sdk-rust/.cargo/config.toml - -# Build and install the SDK into a fixed prefix so downstream projects can -# consume the image as a prebuilt LiveKit SDK environment. -RUN LLVM_VERSION="$(llvm-config --version | cut -d. -f1)" \ - && export LIBCLANG_PATH="/usr/lib/llvm-${LLVM_VERSION}/lib" \ - && export CXXFLAGS="-Wno-deprecated-declarations" \ - && export CFLAGS="-Wno-deprecated-declarations" \ - && chmod +x /client-sdk-cpp/build.sh \ - && cd /client-sdk-cpp \ - && ./build.sh release --bundle --prefix "${SDK_INSTALL_PREFIX}" \ - && test -f "${SDK_INSTALL_PREFIX}/lib/cmake/LiveKit/LiveKitConfig.cmake" diff --git a/docker/Dockerfile.sdk b/docker/Dockerfile.sdk new file mode 100644 index 0000000..fd308a6 --- /dev/null +++ b/docker/Dockerfile.sdk @@ -0,0 +1,56 @@ +# Copyright 2026 LiveKit +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Build with: +# docker build -t livekit-cpp-sdk-base . -f docker/Dockerfile.base +# docker build --build-arg BASE_IMAGE=livekit-cpp-sdk-base -t livekit-cpp-sdk . -f docker/Dockerfile.sdk +# From repo root. +# Run with: +# docker run -it --network host livekit-cpp-sdk:latest bash + +ARG BASE_IMAGE=livekit-cpp-sdk-base +FROM ${BASE_IMAGE} + +ENV SDK_INSTALL_PREFIX=/opt/livekit-sdk + +# Copy project source (build context = repo root) +WORKDIR /client-sdk-cpp +RUN mkdir -p /client-sdk-cpp +COPY src /client-sdk-cpp/src +COPY include /client-sdk-cpp/include +COPY bridge /client-sdk-cpp/bridge +COPY build.sh /client-sdk-cpp/build.sh +COPY CMakePresets.json /client-sdk-cpp/CMakePresets.json +COPY build.cmd /client-sdk-cpp/build.cmd +COPY client-sdk-rust /client-sdk-cpp/client-sdk-rust +COPY data /client-sdk-cpp/data +COPY cmake /client-sdk-cpp/cmake +COPY CMakeLists.txt /client-sdk-cpp/CMakeLists.txt +COPY build.h.in /client-sdk-cpp/build.h.in + +# Configure Rust linker: use full GCC path so liblto_plugin.so is found (not /home/installs/ which has no plugin) +RUN mkdir -p /client-sdk-cpp/client-sdk-rust/.cargo \ + && printf '%s\n' '[target.x86_64-unknown-linux-gnu]' 'linker = "/root/gcc-14/bin/g++"' \ + '[target.aarch64-unknown-linux-gnu]' 'linker = "/root/gcc-14/bin/g++"' > /client-sdk-cpp/client-sdk-rust/.cargo/config.toml + +# Build and install the SDK into a fixed prefix so downstream projects can +# consume the image as a prebuilt LiveKit SDK environment. +RUN LLVM_VERSION="$(llvm-config --version | cut -d. -f1)" \ + && export LIBCLANG_PATH="/usr/lib/llvm-${LLVM_VERSION}/lib" \ + && export CXXFLAGS="-Wno-deprecated-declarations" \ + && export CFLAGS="-Wno-deprecated-declarations" \ + && chmod +x /client-sdk-cpp/build.sh \ + && cd /client-sdk-cpp \ + && ./build.sh release --bundle --prefix "${SDK_INSTALL_PREFIX}" \ + && test -f "${SDK_INSTALL_PREFIX}/lib/cmake/LiveKit/LiveKitConfig.cmake" From aa3422641c72d52fb6d306f8e66faafaed5ddbc2 Mon Sep 17 00:00:00 2001 From: stavied <40528896+stephen-derosa@users.noreply.github.com> Date: Fri, 10 Apr 2026 10:34:54 -0600 Subject: [PATCH 2/4] Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .github/workflows/docker-images.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-images.yml b/.github/workflows/docker-images.yml index acbcdfc..5b45fc8 100644 --- a/.github/workflows/docker-images.yml +++ b/.github/workflows/docker-images.yml @@ -89,7 +89,7 @@ jobs: fi case "${path}" in - docker/Dockerfile.sdk|src/*|include/*|bridge/*|client-sdk-rust/*|cmake/*|data/*|CMakeLists.txt|build.sh|build.cmd|build.h.in|CMakePresets.json) + docker/Dockerfile.sdk|src/*|src/*/*|include/*|include/*/*|bridge/*|bridge/*/*|client-sdk-rust/*|client-sdk-rust/*/*|cmake/*|cmake/*/*|data/*|data/*/*|CMakeLists.txt|build.sh|build.cmd|build.h.in|CMakePresets.json) sdk_changed=true ;; esac From 37c1b0f9e13da487d4dfc692f943a64bc1b66bb6 Mon Sep 17 00:00:00 2001 From: stavied <40528896+stephen-derosa@users.noreply.github.com> Date: Fri, 10 Apr 2026 13:20:35 -0600 Subject: [PATCH 3/4] Update .github/workflows/builds.yml to use TARGETARCH Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .github/workflows/builds.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/builds.yml b/.github/workflows/builds.yml index 8abfbbe..029efb4 100644 --- a/.github/workflows/builds.yml +++ b/.github/workflows/builds.yml @@ -331,6 +331,7 @@ jobs: - name: Build base Docker image run: | docker build \ + --build-arg TARGETARCH=amd64 \ -t livekit-cpp-sdk-base-x64:${{ github.sha }} \ -f docker/Dockerfile.base \ docker From d6100997d0cc8fee361efa3226d6760c89391be0 Mon Sep 17 00:00:00 2001 From: stavied <40528896+stephen-derosa@users.noreply.github.com> Date: Fri, 10 Apr 2026 13:20:49 -0600 Subject: [PATCH 4/4] Update .github/workflows/builds.yml to use TARGETARCH Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .github/workflows/builds.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/builds.yml b/.github/workflows/builds.yml index 029efb4..f55663c 100644 --- a/.github/workflows/builds.yml +++ b/.github/workflows/builds.yml @@ -386,6 +386,7 @@ jobs: - name: Build base Docker image run: | docker build \ + --build-arg TARGETARCH=arm64 \ -t livekit-cpp-sdk-base-arm64:${{ github.sha }} \ -f docker/Dockerfile.base \ docker