Skip to content
104 changes: 104 additions & 0 deletions o/ollama/Dockerfiles/v0.24.0_ubi_9/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
###############################################################################
# Stage 1: Build Ollama (Power10 optimized)
###############################################################################
FROM registry.access.redhat.com/ubi9/ubi:9.6 AS build

ARG PACKAGE_NAME=ollama
ARG PACKAGE_VERSION=v0.24.0
ARG PACKAGE_URL=https://github.com/ollama/ollama
ENV CMAKE_VERSION=3.30.5
ENV GO_VERSION=1.26.1
ENV PATH="/usr/local/go/bin:/usr/local/cmake/bin:${PATH}"

# Install dependencies
RUN yum update -y && \
yum install -y \
python3 python3-pip python3-devel \
gcc-toolset-13 gcc-toolset-13-binutils gcc-toolset-13-gcc-c++ \
git make cmake binutils wget patch tar gzip openssl-devel \
&& yum clean all

# Enable GCC toolset 13
ENV PATH="/opt/rh/gcc-toolset-13/root/usr/bin:${PATH}"
ENV LD_LIBRARY_PATH="/opt/rh/gcc-toolset-13/root/usr/lib64:${LD_LIBRARY_PATH}"
ENV CC=/opt/rh/gcc-toolset-13/root/usr/bin/gcc
ENV CXX=/opt/rh/gcc-toolset-13/root/usr/bin/g++

# Install CMake
WORKDIR /tmp
RUN wget https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/cmake-${CMAKE_VERSION}.tar.gz && \
tar -xzf cmake-${CMAKE_VERSION}.tar.gz && \
cd cmake-${CMAKE_VERSION} && \
./bootstrap --prefix=/usr/local/cmake --parallel=2 -- \
-DBUILD_TESTING:BOOL=OFF \
-DCMAKE_BUILD_TYPE:STRING=Release \
-DCMAKE_USE_OPENSSL:BOOL=ON && \
make -j$(nproc) && \
make install && \
cmake --version

# Install Go
RUN wget https://go.dev/dl/go${GO_VERSION}.linux-ppc64le.tar.gz && \
rm -rf /usr/local/go && \
tar -C /usr/local -xzf go${GO_VERSION}.linux-ppc64le.tar.gz && \
rm -rf go${GO_VERSION}.linux-ppc64le.tar.gz && \
go version

###############################################################################
# Clone and patch Ollama
###############################################################################
WORKDIR /src

# Clone Ollama source and apply patches
RUN git clone ${PACKAGE_URL} && \
cd ${PACKAGE_NAME} && \
git checkout ${PACKAGE_VERSION}

WORKDIR /src/${PACKAGE_NAME}
# Download patches
RUN wget -q -O ppc_sync1.patch \
https://github.com/ollama/ollama/commit/035aee3b98e666b42fbab724aa9aaa176360844f.patch && \
wget -q -O ppc_sync2.patch \
https://github.com/ollama/ollama/commit/b765e03d192fe99e96a8008daeb76a0a843e997d.patch && \
wget -q -O build_fix_ppc.patch \
https://github.com/ollama/ollama/commit/4115e4f58f8c3fb86cdce2d58aae811c2d26cc52.patch && \
wget -q -O set_threads_env.patch \
https://github.com/ollama/ollama/commit/93e98dcc345e34cebd18ac7a83cf08a9b646fd52.patch

# Apply patches
RUN patch -Np1 < ppc_sync1.patch && \
patch -Np1 < ppc_sync2.patch && \
patch -Np1 < build_fix_ppc.patch && \
patch -Np1 < set_threads_env.patch


###############################################################################
# Build Ollama (CMake + Go)
###############################################################################
RUN cmake -B build -DCMAKE_BUILD_TYPE=Release && \
cmake --build build -j$(nproc)

# Link GGML Power10 libs
ENV CGO_LDFLAGS="-L/src/ollama/build/lib/ollama -lggml-cpu-power10"

RUN go build --tags ppc64le.power10 -o /src/ollama/ollama .

###############################################################################
# Stage 2: Small runtime image
###############################################################################
FROM registry.access.redhat.com/ubi9/ubi:9.6

RUN yum update -y && \
yum install -y libatomic openblas-devel && \
yum clean all

COPY --from=build /src/ollama/ollama /usr/bin/ollama
COPY --from=build /src/ollama/build/lib/ollama /usr/lib/ollama

ENV LD_LIBRARY_PATH=/usr/lib/ollama:$LD_LIBRARY_PATH
ENV PATH="/usr/bin:${PATH}"
ENV OLLAMA_HOST=0.0.0.0:11434

EXPOSE 11434
ENTRYPOINT ["/usr/bin/ollama"]
CMD ["serve"]
8 changes: 7 additions & 1 deletion o/ollama/build_info.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"maintainer": "shalinib-ibm",
"package_name": "ollama",
"github_url": "https://github.com/ollama/ollama",
"version": "v0.23.1",
"version": "v0.24.0",
"wheel_build": true,
"package_dir": "o/ollama",
"default_branch": "main",
Expand All @@ -11,6 +11,12 @@
"validate_build_script": true,
"docker_cmd": "docker build -t ${package_name}-ppc64le:$PACKAGE_VERSION ${dir}",
"use_non_root_user": false,
"v0.24.0": {
"dir": "v0.24.0_ubi_9",
"build_script": "ollama_v0.24.0_ubi_9.6.sh",
"base_docker_image": "registry.access.redhat.com/ubi9/ubi:9.6",
"base_docker_variant": "redhat"
},
"v0.23.1": {
"dir": "v0.23.1_ubi_9",
"build_script": "ollama_v0.20.3_ubi_9.6.sh",
Expand Down
194 changes: 194 additions & 0 deletions o/ollama/ollama_v0.24.0_ubi_9.6.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
#!/bin/bash
# -----------------------------------------------------------------------------
#
# Package : Ollama (Power10 optimized)
# Version : v0.24.0
# Source repo : https://github.com/ollama/ollama
# Tested on : UBI:9.6
# Language : Go, C, Python
# Ci-Check : True
# Script License : Apache License, Version 2 or later
# Maintainer : Shalini Salomi Bodapati <Shalini.Salomi.Bodapati@ibm.com>
#
# Disclaimer: This script has been tested in root mode on given
# ========== platform using the mentioned version of the package.
# It may not work as expected with newer versions of the
# package and/or distribution. In such case, please
# contact "Maintainer" of this script.
#
# -----------------------------------------------------------------------------

set -e

# Variables
PACKAGE_NAME=ollama
PACKAGE_VERSION=${1:-v0.24.0}
PACKAGE_URL=https://github.com/ollama/ollama
OLLAMA_VERSION=${PACKAGE_VERSION}
CURRENT_DIR=$(pwd)
PACKAGE_DIR=ollama
SCRIPT_PATH=$(dirname $(realpath $0))

echo "------------------------Installing dependencies-------------------"

# install core dependencies
yum install -y python python-pip python-devel gcc-toolset-13 gcc-toolset-13-binutils gcc-toolset-13-binutils-devel gcc-toolset-13-gcc-c++ git make cmake binutils wget patch

python -m pip install --upgrade pip setuptools wheel build

export PATH=/opt/rh/gcc-toolset-13/root/usr/bin:$PATH
export LD_LIBRARY_PATH=/opt/rh/gcc-toolset-13/root/usr/lib64:$LD_LIBRARY_PATH
gcc --version

echo "**** Checking GCC version..."
gcc -v || true

# -----------------------------------------------------------------------------
# Download Go
# -----------------------------------------------------------------------------
GO_VERSION="1.26.1"
GO_TAR="go${GO_VERSION}.linux-ppc64le.tar.gz"
GO_DIR="go"

if [ ! -d "${GO_DIR}" ]; then
echo "**** Downloading Go ${GO_VERSION}..."
wget -q https://go.dev/dl/${GO_TAR}
echo "**** Extracting Go binary..."
tar xzf ${GO_TAR}
else
echo "**** Go already extracted, skipping..."
fi

export PATH="$(pwd)/go/bin:$PATH"

# -----------------------------------------------------------------------------
# Clone and patch Ollama
# -----------------------------------------------------------------------------

echo "**** Cloning Ollama repository..."
git clone $PACKAGE_URL
cd $PACKAGE_NAME
git checkout $PACKAGE_VERSION

echo "** Downloading power specific patches **"
wget -q -O ppc_sync1.patch https://github.com/ollama/ollama/commit/035aee3b98e666b42fbab724aa9aaa176360844f.patch
wget -q -O ppc_sync2.patch https://github.com/ollama/ollama/commit/b765e03d192fe99e96a8008daeb76a0a843e997d.patch
wget -q -O ppc_build_fix.patch https://github.com/ollama/ollama/commit/4115e4f58f8c3fb86cdce2d58aae811c2d26cc52.patch
wget -q -O set_threads_env.patch https://github.com/ollama/ollama/commit/93e98dcc345e34cebd18ac7a83cf08a9b646fd52.patch

echo "** Applying power specific patches**"
patch -p1 < ppc_sync1.patch
patch -p1 < ppc_sync2.patch
patch -p1 < ppc_build_fix.patch
patch -p1 < set_threads_env.patch

# -----------------------------------------------------------------------------
# Build Ollama
# -----------------------------------------------------------------------------
echo "**** Building Ollama with CMake..."
cmake -B build
cmake --build build -j$(nproc)


export CGO_LDFLAGS="-L$(pwd)/build/lib/ollama -lggml-cpu-power10 -Wl,-rpath,\$ORIGIN/../lib"

echo "**** Building Ollama binary with Go..."
../go/bin/go build --tags ppc64le.power10 -o ollama .

if ls ollama 1>/dev/null 2>&1; then
echo "Ollama Binary built successfully:"
ls ollama
else
echo "Ollama Build failed"
EXIT_CODE=1
fi

# -----------------------------------------------------------------------------
# Auto-generate setup.py and minimal package structure for wheel build
# -----------------------------------------------------------------------------
echo "**** Creating setup.py and package files ****"

PKG_NAME="ollama_python_package"
mkdir -p ${PKG_NAME} ${PKG_NAME}/bin ${PKG_NAME}/lib

# Generate setup.py
cat <<EOF > setup.py
from setuptools import setup, find_packages
from setuptools.command.build_py import build_py
import os, shutil, stat

PYTHON_PACKAGE_NAME = "ollama_python_package"
VERSION = "${PACKAGE_VERSION#v}"

BIN_SRC = os.path.join(os.getcwd(), "ollama")
LIB_SRC = os.path.join(os.getcwd(), "build", "lib", "ollama")
PKG_BIN_DIR = os.path.join(PYTHON_PACKAGE_NAME, "bin")
PKG_LIB_DIR = os.path.join(PYTHON_PACKAGE_NAME, "lib")

def make_executable(path):
st = os.stat(path)
os.chmod(path, st.st_mode | stat.S_IEXEC)

class CustomBuild(build_py):
def run(self):
os.makedirs(PKG_BIN_DIR, exist_ok=True)
os.makedirs(PKG_LIB_DIR, exist_ok=True)

# Copy ollama binary
if os.path.exists(BIN_SRC):
print(f"Copying binary to {PKG_BIN_DIR}")
shutil.copy2(BIN_SRC, PKG_BIN_DIR)
make_executable(os.path.join(PKG_BIN_DIR, "ollama"))
else:
print("Warning: ollama binary not found")

# Copy .so libraries
if os.path.exists(LIB_SRC):
for f in os.listdir(LIB_SRC):
if f.endswith(".so"):
src = os.path.join(LIB_SRC, f)
dst = os.path.join(PKG_LIB_DIR, f)
print(f"Copying shared lib: {src}")
shutil.copy2(src, dst)
else:
print(f"Warning: {LIB_SRC} not found")

super().run()

setup(
name=PYTHON_PACKAGE_NAME,
version=VERSION,
author="Shalini Salomi Bodapati",
author_email="Shalini.Salomi.Bodapati@ibm.com",
description="Power10 optimized Ollama binary + shared libs as Python package",
license="MIT",
packages=find_packages(include=["ollama_python_package"]),
include_package_data=False,
cmdclass={'build_py': CustomBuild},
package_data={PYTHON_PACKAGE_NAME: ["bin/*", "lib/*.so"]},
python_requires=">=3.8",
)
EOF

# Create __init__.py (wrapper)
cat <<'EOF' > ${PKG_NAME}/__init__.py
import subprocess
from pathlib import Path

def run(args=None):
"""Run embedded Ollama binary packaged with this wheel."""
bin_path = Path(__file__).parent / "bin" / "ollama"
if not bin_path.exists():
raise FileNotFoundError("Embedded ollama binary not found.")
subprocess.run([str(bin_path)] + (args or []))
EOF

echo "=============== Building wheel =================="
python -m pip install --upgrade pip setuptools wheel build

if ! python setup.py bdist_wheel --plat-name linux_ppc64le --dist-dir "$CURRENT_DIR/"; then
echo "============ Wheel Creation Failed ================="
EXIT_CODE=1
else
echo "============ Wheel successfully built ================="
fi