diff --git a/.github/workflows/docker-vulkan.yml b/.github/workflows/docker-vulkan.yml new file mode 100644 index 000000000000..70637440bca8 --- /dev/null +++ b/.github/workflows/docker-vulkan.yml @@ -0,0 +1,130 @@ +name: Create and publish docker image (Vulkan) + +on: + workflow_dispatch: + schedule: + - cron: "0 20 */1 * *" + push: + tags: + - "v*" + - "!*-dev.*" + - "!vscode@*" + - '!vim@*' + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.ref_name }} + + # If this is enabled it will cancel current running and start latest + cancel-in-progress: true + +env: + RUST_TOOLCHAIN: 1.82.0 + +jobs: + release-docker: + runs-on: buildjet-2vcpu-ubuntu-2204 + permissions: + contents: read + packages: write + # This is used to complete the identity challenge + # with sigstore/fulcio when running outside of PRs. + id-token: write + + strategy: + matrix: + device-type: [vulkan] + include: + - device-type: vulkan + image-suffix: "-vulkan" + + steps: + - name: Free Disk Space (Ubuntu) + uses: jlumbroso/free-disk-space@main + with: + # this might remove tools that are actually needed, + # if set to "true" but frees about 6 GB + tool-cache: true + + # all of these default to true, but feel free to set to + # "false" if necessary for your workflow + android: true + dotnet: true + haskell: true + large-packages: false + swap-storage: true + + - name: Checkout repository + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Setup QEMU + uses: docker/setup-qemu-action@v3 + + # Workaround: https://github.com/docker/build-push-action/issues/461 + - name: Setup Docker buildx + uses: docker/setup-buildx-action@v3 + + # Login against a Docker registry except on PR + # https://github.com/docker/login-action + - name: Log into GitHub Container registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Log into Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Generate image name + env: + IMAGE_SUFFIX: ${{ matrix.image-suffix }} + run: | + echo "IMAGE_NAME=${GITHUB_REPOSITORY,,}${IMAGE_SUFFIX}" >>${GITHUB_ENV} + + - uses: int128/docker-build-cache-config-action@v1 + id: cache + with: + image: ghcr.io/${{ env.IMAGE_NAME }}/cache + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + # list of Docker images to use as base name for tags + images: | + ghcr.io/${{ env.IMAGE_NAME }} + ${{ env.IMAGE_NAME }} + # generate Docker tags based on the following events/attributes + tags: | + type=raw,value={{branch}}-{{sha}},enable=${{ startsWith(github.ref, 'refs/heads') }} + type=schedule,pattern=nightly + type=schedule,pattern={{date 'YYYYMMDD'}} + type=semver,pattern={{version}} + + # Build and push Docker image with Buildx (don't push on PR) + # https://github.com/docker/build-push-action + - name: Build and push Docker image + id: build-and-push + uses: docker/build-push-action@v5 + with: + file: docker/Dockerfile.${{ matrix.device-type }} + platforms: linux/amd64,linux/arm64 + push: true + context: . + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: ${{ steps.cache.outputs.cache-from }} + cache-to: ${{ steps.cache.outputs.cache-to }} + build-args: RUST_TOOLCHAIN=${{ env.RUST_TOOLCHAIN }} + + - name: Docker Hub Description + uses: peter-evans/dockerhub-description@v4 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + repository: tabbyml/tabby diff --git a/docker/Dockerfile.vulkan b/docker/Dockerfile.vulkan new file mode 100644 index 000000000000..3527757f9cb0 --- /dev/null +++ b/docker/Dockerfile.vulkan @@ -0,0 +1,80 @@ +ARG UBUNTU_VERSION=24.04 + +# Target the VULKAN build image +ARG BASE_VULKAN_DEV_CONTAINER=ubuntu:${UBUNTU_VERSION} +# Target the VULKAN runtime image +ARG BASE_VULKAN_RUN_CONTAINER=ubuntu:${UBUNTU_VERSION} + +FROM ${BASE_VULKAN_DEV_CONTAINER} AS build + +# Rust toolchain version +ARG RUST_TOOLCHAIN=stable + +ENV DEBIAN_FRONTEND=noninteractive +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + curl \ + ca-certificates \ + pkg-config \ + libssl-dev \ + libvulkan-dev \ + glslc \ + protobuf-compiler \ + git \ + cmake \ + build-essential \ + && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +# setup rust. +RUN curl https://sh.rustup.rs -sSf | bash -s -- --default-toolchain ${RUST_TOOLCHAIN} -y +ENV PATH="/root/.cargo/bin:${PATH}" + +WORKDIR /root/workspace + +RUN mkdir -p /opt/tabby/bin +RUN mkdir -p /opt/tabby/lib +RUN mkdir -p target + +COPY . . + +RUN --mount=type=cache,target=/usr/local/cargo/registry \ + --mount=type=cache,target=/root/workspace/target \ + cargo build --no-default-features --features vulkan,prod --release --package tabby && \ + cp target/release/llama-server /opt/tabby/bin/ && \ + cp target/release/tabby /opt/tabby/bin/ + +# For compatibility with the legacy cpu build. +RUN cp /opt/tabby/bin/tabby /opt/tabby/bin/tabby-cpu + +FROM ${BASE_VULKAN_RUN_CONTAINER} AS runtime + +ENV DEBIAN_FRONTEND=noninteractive +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + git \ + curl \ + unzip \ + openssh-client \ + ca-certificates \ + libgomp1 \ + libvulkan1 \ + && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +# Disable safe directory in docker +# Context: https://github.com/git/git/commit/8959555cee7ec045958f9b6dd62e541affb7e7d9 +RUN git config --system --add safe.directory "*" + +# Automatic platform ARGs in the global scope +# https://docs.docker.com/engine/reference/builder/#automatic-platform-args-in-the-global-scope +ARG TARGETARCH + +COPY --from=build /opt/tabby /opt/tabby + +ENV PATH="$PATH:/opt/tabby/bin" +ENV TABBY_ROOT=/data + +ENTRYPOINT ["/opt/tabby/bin/tabby"]