diff --git a/.github/workflows/docker-amd64.yml b/.github/workflows/docker-amd64.yml deleted file mode 100644 index 5c3eae0fe..000000000 --- a/.github/workflows/docker-amd64.yml +++ /dev/null @@ -1,34 +0,0 @@ -# Build Docker image and push it to docker hub - -name: Dockerize amd64 - -on: - workflow_dispatch: - inputs: - docker_tag: - description: "Enter KM version (for docker tag)" - required: true - default: "0.000.000000.0" - -jobs: - build-and-push-image: - runs-on: ubuntu-latest - env: - DOCKER_TARGET_PLATFORM: linux/amd64 - steps: - - - name: Checkout code - uses: actions/checkout@v4 - - - name: Login to Docker Hub - uses: docker/login-action@v3 - with: - username: ${{ vars.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Build Docker image - run: | - docker build --push --platform linux/amd64 \ - --build-arg BUILD_IMAGE_TAG=9.0-noble-amd64 \ - --build-arg RUN_IMAGE_TAG=9.0-alpine-amd64 \ - --tag "${{ vars.DOCKERHUB_USERNAME }}/service:${{ github.event.inputs.docker_tag }}-amd64" . diff --git a/.github/workflows/docker-arm64.yml b/.github/workflows/docker-arm64.yml deleted file mode 100644 index 2b63a9ea2..000000000 --- a/.github/workflows/docker-arm64.yml +++ /dev/null @@ -1,52 +0,0 @@ -# Build Docker image and push it to docker hub - -name: Dockerize arm64 - -on: - workflow_dispatch: - inputs: - docker_tag: - description: "Enter KM version (for docker tag)" - required: true - default: "0.000.000000.0" - -jobs: - build-and-push-image: - runs-on: ubuntu-24.04-arm - env: - DOCKER_TARGET_PLATFORM: linux/arm64 - steps: - - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Login to Docker Hub - uses: docker/login-action@v3 - with: - username: ${{ vars.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Docker meta - id: meta - uses: docker/metadata-action@v5 - with: - images: | - ${{ vars.DOCKERHUB_USERNAME }}/service - tags: | - type=raw,priority=800,value=${{ github.event.inputs.docker_tag }}-arm64 - - - name: Build and push - uses: docker/build-push-action@v6 - with: - context: . - push: true - platforms: linux/arm64 - # See https://github.com/dotnet/dotnet-docker/blob/main/README.sdk.md#full-tag-listing - build-args: | - BUILD_IMAGE_TAG=9.0-noble-arm64v8 - RUN_IMAGE_TAG=9.0-alpine-arm64v8 - labels: ${{ steps.meta.outputs.labels }} - tags: ${{ steps.meta.outputs.tags }} diff --git a/.github/workflows/docker-multiarch.yml b/.github/workflows/docker-multiarch.yml index 0bd7c148c..edc860090 100644 --- a/.github/workflows/docker-multiarch.yml +++ b/.github/workflows/docker-multiarch.yml @@ -55,3 +55,30 @@ jobs: --build-arg BUILD_IMAGE_TAG=9.0-noble-amd64 \ --build-arg RUN_IMAGE_TAG=9.0-alpine-amd64 \ --tag "${{ vars.DOCKERHUB_USERNAME }}/service:${{ github.event.inputs.docker_tag }}-amd64" . + + latest: + runs-on: ubuntu-latest + needs: + - arm64 + - amd64 + steps: + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ vars.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Create multi-arch manifest for "latest" tag + run: | + docker pull --platform linux/amd64 "kernelmemory/service:${{ github.event.inputs.docker_tag }}-amd64" + docker pull --platform linux/arm64 "kernelmemory/service:${{ github.event.inputs.docker_tag }}-arm64" + + docker manifest create kernelmemory/service:latest \ + "kernelmemory/service:${{ github.event.inputs.docker_tag }}-amd64" \ + "kernelmemory/service:${{ github.event.inputs.docker_tag }}-arm64" + + docker manifest annotate kernelmemory/service:latest "kernelmemory/service:${{ github.event.inputs.docker_tag }}-amd64" --os linux --arch amd64 + docker manifest annotate kernelmemory/service:latest "kernelmemory/service:${{ github.event.inputs.docker_tag }}-arm64" --os linux --arch arm64 + + docker manifest push kernelmemory/service:latest diff --git a/Dockerfile b/Dockerfile index 9c50b5ca2..7acdca585 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,9 +1,12 @@ -# Usage: docker buildx build --platform linux/amd64 . -# Usage: docker buildx build --platform linux/arm64 . +# Usage: docker build --platform linux/amd64 --build-arg BUILD_IMAGE_TAG=9.0-noble-amd64 \ +# --build-arg RUN_IMAGE_TAG=9.0-alpine-amd64 . +# +# Usage: docker build --platform linux/arm64 --build-arg BUILD_IMAGE_TAG=9.0-noble-arm64v8 \ +# --build-arg RUN_IMAGE_TAG=9.0-alpine-arm64v8 . # See https://github.com/dotnet/dotnet-docker/blob/main/README.sdk.md#full-tag-listing -ARG BUILD_IMAGE_TAG="8.0-jammy" -ARG RUN_IMAGE_TAG="8.0-alpine" +ARG BUILD_IMAGE_TAG="9.0-noble" +ARG RUN_IMAGE_TAG="9.0-alpine" ######################################################################### # .NET build diff --git a/KernelMemory.sln b/KernelMemory.sln index cb069aec6..84b93f45c 100644 --- a/KernelMemory.sln +++ b/KernelMemory.sln @@ -98,8 +98,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\dotnet-unit-tests.yml = .github\workflows\dotnet-unit-tests.yml .github\workflows\github-pages-jekyll.yml = .github\workflows\github-pages-jekyll.yml .github\workflows\spell-check-with-typos.yml = .github\workflows\spell-check-with-typos.yml - .github\workflows\docker-amd64.yml = .github\workflows\docker-amd64.yml - .github\workflows\docker-arm64.yml = .github\workflows\docker-arm64.yml .github\workflows\fortify.yml = .github\workflows\fortify.yml .github\workflows\securitycodescan.yml = .github\workflows\securitycodescan.yml .github\workflows\docker-multiarch.yml = .github\workflows\docker-multiarch.yml diff --git a/README.md b/README.md index ae70004dc..c5e52e8c0 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,7 @@ Kernel Memory [![License: MIT](https://img.shields.io/github/license/microsoft/kernel-memory)](https://github.com/microsoft/kernel-memory/blob/main/LICENSE) [![Discord](https://img.shields.io/discord/1063152441819942922?label=Discord&color=d82679&logo=discord&logoColor=white)](https://aka.ms/KMdiscord) -[![Docker Image Version](https://img.shields.io/docker/v/kernelmemory/service/latest?arch=amd64&label=Docker&color=%230db7ed&logo=docker&logoColor=white)](https://hub.docker.com/r/kernelmemory/service) -[![Docker Image Version](https://img.shields.io/docker/v/kernelmemory/service/latest-arm64?arch=arm64&label=Docker+ARM&color=%230db7ed&logo=docker&logoColor=white)](https://hub.docker.com/r/kernelmemory/service) +[![Docker Image](https://img.shields.io/docker/pulls/kernelmemory/service?label=Docker&color=%230db7ed&logo=docker&logoColor=white)](https://hub.docker.com/r/kernelmemory/service) [![NuGet Version](https://img.shields.io/nuget/v/Microsoft.KernelMemory?label=nuget&color=%23512BD4&logo=.net&logoColor=white)](https://www.nuget.org/packages/Microsoft.KernelMemory) [![GitHub Release](https://img.shields.io/github/v/release/microsoft/kernel-memory?color=%23dddddd&label=tag&logo=github&logoColor=white)](https://github.com/microsoft/kernel-memory/releases) @@ -276,12 +275,6 @@ to **start the Kernel Memory Service** using OpenAI: docker run -e OPENAI_API_KEY="..." -it --rm -p 9001:9001 kernelmemory/service ``` -on Linux ARM/MacOS use a different tag: - -```shell -docker run -e OPENAI_API_KEY="..." -it --rm -p 9001:9001 kernelmemory/service:latest-arm64 -``` - If you prefer using custom settings and services such as Azure OpenAI, Azure Document Intelligence, etc., you should create an `appsettings.Development.json` file overriding the default values set in `appsettings.json`, or using the @@ -297,14 +290,10 @@ on Windows: docker run --volume .\appsettings.Development.json:/app/appsettings.Production.json -it --rm -p 9001:9001 kernelmemory/service -on Linux (AMD64): +on Linux / macOS: docker run --volume ./appsettings.Development.json:/app/appsettings.Production.json -it --rm -p 9001:9001 kernelmemory/service -on ARM64 / macOS: - - docker run --volume ./appsettings.Development.json:/app/appsettings.Production.json -it --rm -p 9001:9001 kernelmemory/service:latest-arm64 - 🔗 See also: * [How to configure KM service](https://github.com/microsoft/kernel-memory/blob/main/service/Service/README.md#%EF%B8%8F-configuration) * [Deploy Kernel Memory to Azure](#kernel-memory-service-on-azure). diff --git a/examples/303-dotnet-aspire/Program.cs b/examples/303-dotnet-aspire/Program.cs index 6dc968ce5..ef4a9b8ed 100644 --- a/examples/303-dotnet-aspire/Program.cs +++ b/examples/303-dotnet-aspire/Program.cs @@ -31,8 +31,6 @@ internal static void Main() // RunFromDockerWithOpenAI(s_openAIConfig.APIKey); // RunFromDockerImage("latest"); - - // RunFromDockerImage("latest-arm64"); } private static void RunFromCode() diff --git a/tools/dev/dockerize-amd64.sh b/tools/dev/dockerize-amd64.sh index 27ed28fdb..958ca392b 100755 --- a/tools/dev/dockerize-amd64.sh +++ b/tools/dev/dockerize-amd64.sh @@ -7,13 +7,27 @@ cd "$HERE/../.." USR=kernelmemory IMG=${USR}/service +ARCH=amd64 # Prompt user for VERSION -read -p "Enter VERSION (e.g. '0.99.260214.1'): " VERSION +if [ -z "$1" ]; then + # Get the latest git tag and remove any prefix + LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "") + SUGGESTED_VERSION=${LATEST_TAG#*-} + read -p "Enter VERSION (default: '${SUGGESTED_VERSION}'): " VERSION + VERSION=${VERSION:-$SUGGESTED_VERSION} +else + VERSION=$1 + read -p "VERSION is set to '${VERSION}'. Press Enter to keep or provide a new value: " NEW_VERSION + VERSION=${NEW_VERSION:-$VERSION} +fi + +# Trim VERSION value +VERSION=$(echo "$VERSION" | xargs) # Ensure VERSION ends with arch name -if [[ "${VERSION:(-6)}" != "-amd64" ]]; then - VERSION="${VERSION}-amd64" +if [[ "${VERSION:(-6)}" != "-${ARCH}" ]]; then + VERSION="${VERSION}-${ARCH}" fi # Remove images if they exist @@ -37,11 +51,10 @@ for TAG in "${VERSION}" "latest"; do done # See https://github.com/dotnet/dotnet-docker/blob/main/README.sdk.md#full-tag-listing -docker buildx build --no-cache --load \ - --platform=linux/amd64 \ +docker build --platform linux/amd64 \ --build-arg BUILD_IMAGE_TAG=9.0-noble-amd64 \ --build-arg RUN_IMAGE_TAG=9.0-alpine-amd64 \ - -t "${IMG}:${VERSION}" \ + --push -t "${IMG}:${VERSION}" \ . # Push images to Docker registry diff --git a/tools/dev/dockerize-arm64.sh b/tools/dev/dockerize-arm64.sh index 3f978930e..7faad81d4 100755 --- a/tools/dev/dockerize-arm64.sh +++ b/tools/dev/dockerize-arm64.sh @@ -7,13 +7,27 @@ cd "$HERE/../.." USR=kernelmemory IMG=${USR}/service +ARCH=arm64 # Prompt user for VERSION -read -p "Enter VERSION (e.g. '0.99.260214.1'): " VERSION +if [ -z "$1" ]; then + # Get the latest git tag and remove any prefix + LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "") + SUGGESTED_VERSION=${LATEST_TAG#*-} + read -p "Enter VERSION (default: '${SUGGESTED_VERSION}'): " VERSION + VERSION=${VERSION:-$SUGGESTED_VERSION} +else + VERSION=$1 + read -p "VERSION is set to '${VERSION}'. Press Enter to keep or provide a new value: " NEW_VERSION + VERSION=${NEW_VERSION:-$VERSION} +fi + +# Trim VERSION value +VERSION=$(echo "$VERSION" | xargs) # Ensure VERSION ends with arch name -if [[ "${VERSION:(-6)}" != "-arm64" ]]; then - VERSION="${VERSION}-arm64" +if [[ "${VERSION:(-6)}" != "-${ARCH}" ]]; then + VERSION="${VERSION}-${ARCH}" fi # Remove images if they exist @@ -37,11 +51,10 @@ for TAG in "${VERSION}" "latest"; do done # See https://github.com/dotnet/dotnet-docker/blob/main/README.sdk.md#full-tag-listing -docker buildx build --no-cache --load \ - --platform=linux/arm64 \ +docker build --platform linux/arm64 \ --build-arg BUILD_IMAGE_TAG=9.0-noble-arm64v8 \ --build-arg RUN_IMAGE_TAG=9.0-alpine-arm64v8 \ - -t "${IMG}:${VERSION}" \ + --push -t "${IMG}:${VERSION}" \ . # Push images to Docker registry diff --git a/tools/dev/dockerize-multiarch.sh b/tools/dev/dockerize-multiarch.sh index ddfca1b0e..679cd02ce 100755 --- a/tools/dev/dockerize-multiarch.sh +++ b/tools/dev/dockerize-multiarch.sh @@ -9,7 +9,20 @@ USR=kernelmemory IMG=${USR}/service # Prompt user for VERSION -read -p "Enter VERSION (e.g. '0.99.260214.1'): " VERSION +if [ -z "$1" ]; then + # Get the latest git tag and remove any prefix + LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "") + SUGGESTED_VERSION=${LATEST_TAG#*-} + read -p "Enter VERSION (default: '${SUGGESTED_VERSION}'): " VERSION + VERSION=${VERSION:-$SUGGESTED_VERSION} +else + VERSION=$1 + read -p "VERSION is set to '${VERSION}'. Press Enter to keep or provide a new value: " NEW_VERSION + VERSION=${NEW_VERSION:-$VERSION} +fi + +# Trim VERSION value +VERSION=$(echo "$VERSION" | xargs) # Remove local images if they exist for TAG in "latest" "${VERSION}-amd64" "${VERSION}-arm64"; do @@ -32,21 +45,29 @@ for TAG in "latest" "${VERSION}-amd64" "${VERSION}-arm64"; do done # Pull images +echo "# Pulling images..." docker pull --platform linux/amd64 "kernelmemory/service:${VERSION}-amd64" docker pull --platform linux/arm64 "kernelmemory/service:${VERSION}-arm64" +# Delete manifest +echo "# Deleting manifest..." +docker manifest rm kernelmemory/service:latest || true + # Create manifest +echo "# Creating new manifest..." docker manifest create kernelmemory/service:latest \ "kernelmemory/service:${VERSION}-amd64" \ "kernelmemory/service:${VERSION}-arm64" # Add images to manifest +echo "# Adding images to new manifest..." docker manifest annotate kernelmemory/service:latest \ "kernelmemory/service:${VERSION}-amd64" --os linux --arch amd64 docker manifest annotate kernelmemory/service:latest \ "kernelmemory/service:${VERSION}-arm64" --os linux --arch arm64 # Publish manifest +echo "# Publishing manifest..." docker manifest push kernelmemory/service:latest