name: Create and publish Docker images with specific build args on: workflow_dispatch: push: branches: - main - dev tags: - v* env: REGISTRY: ghcr.io jobs: build-main-image: runs-on: ubuntu-latest permissions: contents: read packages: write strategy: fail-fast: false matrix: platform: - linux/amd64 - linux/arm64 steps: # GitHub Packages requires the entire repository name to be in lowercase # although the repository owner has a lowercase username, this prevents some people from running actions after forking - name: Set repository and image name to lowercase run: | echo "IMAGE_NAME=${IMAGE_NAME,,}" >>${GITHUB_ENV} echo "FULL_IMAGE_NAME=ghcr.io/${IMAGE_NAME,,}" >>${GITHUB_ENV} env: IMAGE_NAME: '${{ github.repository }}' - name: Prepare run: | platform=${{ matrix.platform }} echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV - name: Checkout repository uses: actions/checkout@v4 - name: Set up QEMU uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Log in to the Container registry uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Get version number from package.json id: get_version run: | VERSION=$(jq -r '.version' package.json) echo "version=$VERSION" >> $GITHUB_OUTPUT - name: Extract metadata for Docker images id: meta uses: docker/metadata-action@v5 with: images: ${{ env.FULL_IMAGE_NAME }} tags: | type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }} type=raw,value=${{ steps.get_version.outputs.version }},enable=${{ github.ref == 'refs/heads/main' }} type=ref,event=branch type=ref,event=tag type=sha,prefix=git- type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} - name: Extract metadata for Docker cache id: cache-meta uses: docker/metadata-action@v5 with: images: ${{ env.FULL_IMAGE_NAME }} tags: | type=ref,event=branch ${{ github.ref_type == 'tag' && 'type=raw,value=main' || '' }} flavor: | prefix=cache-${{ matrix.platform }}- latest=false - name: Build Docker image uses: docker/build-push-action@v5 id: build with: context: . push: true platforms: ${{ matrix.platform }} labels: ${{ steps.meta.outputs.labels }} tags: ${{ steps.meta.outputs.tags }} outputs: type=image,name=${{ env.FULL_IMAGE_NAME }},push=true cache-from: type=registry,ref=${{ steps.cache-meta.outputs.tags }} cache-to: type=registry,ref=${{ steps.cache-meta.outputs.tags }},mode=max build-args: | BUILD_HASH=${{ github.sha }} - name: Export digest run: | mkdir -p /tmp/digests digest="${{ steps.build.outputs.digest }}" touch "/tmp/digests/${digest#sha256:}" - name: Upload digest uses: actions/upload-artifact@v4 with: name: digests-main-${{ env.PLATFORM_PAIR }} path: /tmp/digests/* if-no-files-found: error retention-days: 1 build-cuda-image: runs-on: ubuntu-latest permissions: contents: read packages: write strategy: fail-fast: false matrix: platform: - linux/amd64 - linux/arm64 steps: # GitHub Packages requires the entire repository name to be in lowercase # although the repository owner has a lowercase username, this prevents some people from running actions after forking - name: Set repository and image name to lowercase run: | echo "IMAGE_NAME=${IMAGE_NAME,,}" >>${GITHUB_ENV} echo "FULL_IMAGE_NAME=ghcr.io/${IMAGE_NAME,,}" >>${GITHUB_ENV} env: IMAGE_NAME: '${{ github.repository }}' - name: Prepare run: | platform=${{ matrix.platform }} echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV - name: Checkout repository uses: actions/checkout@v4 - name: Set up QEMU uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Log in to the Container registry uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Get version number from package.json id: get_version run: | VERSION=$(jq -r '.version' package.json) echo "version=$VERSION" >> $GITHUB_OUTPUT - name: Extract metadata for Docker images id: meta uses: docker/metadata-action@v5 with: images: ${{ env.FULL_IMAGE_NAME }} tags: | type=raw,value=latest-cuda,enable=${{ github.ref == 'refs/heads/main' }} type=raw,value=${{ steps.get_version.outputs.version }}-cuda,enable=${{ github.ref == 'refs/heads/main' }} type=ref,event=branch,suffix=-cuda type=ref,event=tag,suffix=-cuda type=sha,prefix=git-,suffix=-cuda type=semver,pattern={{version}},suffix=-cuda type=semver,pattern={{major}}.{{minor}},suffix=-cuda - name: Extract metadata for Docker cache id: cache-meta uses: docker/metadata-action@v5 with: images: ${{ env.FULL_IMAGE_NAME }} tags: | type=ref,event=branch ${{ github.ref_type == 'tag' && 'type=raw,value=main' || '' }} flavor: | prefix=cache-cuda-${{ matrix.platform }}- latest=false - name: Build Docker image (cuda) uses: docker/build-push-action@v5 id: build with: context: . push: true platforms: ${{ matrix.platform }} labels: ${{ steps.meta.outputs.labels }} tags: ${{ steps.meta.outputs.tags }} outputs: type=image,name=${{ env.FULL_IMAGE_NAME }},push=true cache-from: type=registry,ref=${{ steps.cache-meta.outputs.tags }} cache-to: type=registry,ref=${{ steps.cache-meta.outputs.tags }},mode=max build-args: | BUILD_HASH=${{ github.sha }} USE_CUDA=true - name: Export digest run: | mkdir -p /tmp/digests digest="${{ steps.build.outputs.digest }}" touch "/tmp/digests/${digest#sha256:}" - name: Upload digest uses: actions/upload-artifact@v4 with: name: digests-cuda-${{ env.PLATFORM_PAIR }} path: /tmp/digests/* if-no-files-found: error retention-days: 1 build-ollama-image: runs-on: ubuntu-latest permissions: contents: read packages: write strategy: fail-fast: false matrix: platform: - linux/amd64 - linux/arm64 steps: # GitHub Packages requires the entire repository name to be in lowercase # although the repository owner has a lowercase username, this prevents some people from running actions after forking - name: Set repository and image name to lowercase run: | echo "IMAGE_NAME=${IMAGE_NAME,,}" >>${GITHUB_ENV} echo "FULL_IMAGE_NAME=ghcr.io/${IMAGE_NAME,,}" >>${GITHUB_ENV} env: IMAGE_NAME: '${{ github.repository }}' - name: Prepare run: | platform=${{ matrix.platform }} echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV - name: Checkout repository uses: actions/checkout@v4 - name: Set up QEMU uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Log in to the Container registry uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Get version number from package.json id: get_version run: | VERSION=$(jq -r '.version' package.json) echo "version=$VERSION" >> $GITHUB_OUTPUT - name: Extract metadata for Docker images id: meta uses: docker/metadata-action@v5 with: images: ${{ env.FULL_IMAGE_NAME }} tags: | type=raw,value=latest-ollama,enable=${{ github.ref == 'refs/heads/main' }} type=raw,value=${{ steps.get_version.outputs.version }}-ollama,enable=${{ github.ref == 'refs/heads/main' }} type=ref,event=branch,suffix=-ollama type=ref,event=tag,suffix=-ollama type=sha,prefix=git-,suffix=-ollama type=semver,pattern={{version}},suffix=-ollama type=semver,pattern={{major}}.{{minor}},suffix=-ollama - name: Extract metadata for Docker cache id: cache-meta uses: docker/metadata-action@v5 with: images: ${{ env.FULL_IMAGE_NAME }} tags: | type=ref,event=branch ${{ github.ref_type == 'tag' && 'type=raw,value=main' || '' }} flavor: | prefix=cache-ollama-${{ matrix.platform }}- latest=false - name: Build Docker image (ollama) uses: docker/build-push-action@v5 id: build with: context: . push: true platforms: ${{ matrix.platform }} labels: ${{ steps.meta.outputs.labels }} tags: ${{ steps.meta.outputs.tags }} outputs: type=image,name=${{ env.FULL_IMAGE_NAME }},push=true cache-from: type=registry,ref=${{ steps.cache-meta.outputs.tags }} cache-to: type=registry,ref=${{ steps.cache-meta.outputs.tags }},mode=max build-args: | BUILD_HASH=${{ github.sha }} USE_OLLAMA=true - name: Export digest run: | mkdir -p /tmp/digests digest="${{ steps.build.outputs.digest }}" touch "/tmp/digests/${digest#sha256:}" - name: Upload digest uses: actions/upload-artifact@v4 with: name: digests-ollama-${{ env.PLATFORM_PAIR }} path: /tmp/digests/* if-no-files-found: error retention-days: 1 merge-main-images: runs-on: ubuntu-latest needs: [ build-main-image ] steps: # GitHub Packages requires the entire repository name to be in lowercase # although the repository owner has a lowercase username, this prevents some people from running actions after forking - name: Set repository and image name to lowercase run: | echo "IMAGE_NAME=${IMAGE_NAME,,}" >>${GITHUB_ENV} echo "FULL_IMAGE_NAME=ghcr.io/${IMAGE_NAME,,}" >>${GITHUB_ENV} env: IMAGE_NAME: '${{ github.repository }}' - name: Download digests uses: actions/download-artifact@v4 with: pattern: digests-main-* path: /tmp/digests merge-multiple: true - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Log in to the Container registry uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Extract metadata for Docker images (default latest tag) id: meta uses: docker/metadata-action@v5 with: images: ${{ env.FULL_IMAGE_NAME }} tags: | type=ref,event=branch type=ref,event=tag type=sha,prefix=git- type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} flavor: | latest=${{ github.ref == 'refs/heads/main' }} - name: Create manifest list and push working-directory: /tmp/digests run: | docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ $(printf '${{ env.FULL_IMAGE_NAME }}@sha256:%s ' *) - name: Inspect image run: | docker buildx imagetools inspect ${{ env.FULL_IMAGE_NAME }}:${{ steps.meta.outputs.version }} merge-cuda-images: runs-on: ubuntu-latest needs: [ build-cuda-image ] steps: # GitHub Packages requires the entire repository name to be in lowercase # although the repository owner has a lowercase username, this prevents some people from running actions after forking - name: Set repository and image name to lowercase run: | echo "IMAGE_NAME=${IMAGE_NAME,,}" >>${GITHUB_ENV} echo "FULL_IMAGE_NAME=ghcr.io/${IMAGE_NAME,,}" >>${GITHUB_ENV} env: IMAGE_NAME: '${{ github.repository }}' - name: Download digests uses: actions/download-artifact@v4 with: pattern: digests-cuda-* path: /tmp/digests merge-multiple: true - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Log in to the Container registry uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Extract metadata for Docker images (default latest tag) id: meta uses: docker/metadata-action@v5 with: images: ${{ env.FULL_IMAGE_NAME }} tags: | type=ref,event=branch type=ref,event=tag type=sha,prefix=git- type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} type=raw,enable=${{ github.ref == 'refs/heads/main' }},prefix=,suffix=,value=cuda flavor: | latest=${{ github.ref == 'refs/heads/main' }} suffix=-cuda,onlatest=true - name: Create manifest list and push working-directory: /tmp/digests run: | docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ $(printf '${{ env.FULL_IMAGE_NAME }}@sha256:%s ' *) - name: Inspect image run: | docker buildx imagetools inspect ${{ env.FULL_IMAGE_NAME }}:${{ steps.meta.outputs.version }} merge-ollama-images: runs-on: ubuntu-latest needs: [ build-ollama-image ] steps: # GitHub Packages requires the entire repository name to be in lowercase # although the repository owner has a lowercase username, this prevents some people from running actions after forking - name: Set repository and image name to lowercase run: | echo "IMAGE_NAME=${IMAGE_NAME,,}" >>${GITHUB_ENV} echo "FULL_IMAGE_NAME=ghcr.io/${IMAGE_NAME,,}" >>${GITHUB_ENV} env: IMAGE_NAME: '${{ github.repository }}' - name: Download digests uses: actions/download-artifact@v4 with: pattern: digests-ollama-* path: /tmp/digests merge-multiple: true - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Log in to the Container registry uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Extract metadata for Docker images (default ollama tag) id: meta uses: docker/metadata-action@v5 with: images: ${{ env.FULL_IMAGE_NAME }} tags: | type=ref,event=branch type=ref,event=tag type=sha,prefix=git- type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} type=raw,enable=${{ github.ref == 'refs/heads/main' }},prefix=,suffix=,value=ollama flavor: | latest=${{ github.ref == 'refs/heads/main' }} suffix=-ollama,onlatest=true - name: Create manifest list and push working-directory: /tmp/digests run: | docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ $(printf '${{ env.FULL_IMAGE_NAME }}@sha256:%s ' *) - name: Inspect image run: | docker buildx imagetools inspect ${{ env.FULL_IMAGE_NAME }}:${{ steps.meta.outputs.version }}