From 51041db4d50bd381fc8a80845f50280644a3870e Mon Sep 17 00:00:00 2001 From: Luke Roy Date: Thu, 16 Apr 2026 15:29:31 +0200 Subject: [PATCH 1/6] Add hook examples Signed-off-by: Luke Roy --- serverless-fleets/README.md | 37 ++++++++++++++++ serverless-fleets/run_hook_ollama | 49 +++++++++++++++++++++ serverless-fleets/run_hook_podman_in_podman | 49 +++++++++++++++++++++ 3 files changed, 135 insertions(+) create mode 100755 serverless-fleets/run_hook_ollama create mode 100755 serverless-fleets/run_hook_podman_in_podman diff --git a/serverless-fleets/README.md b/serverless-fleets/README.md index 703e1952..8cd2e5ee 100644 --- a/serverless-fleets/README.md +++ b/serverless-fleets/README.md @@ -558,6 +558,43 @@ An IBM Cloud Logs instance is being setup and enabled by default during the auto ![](./images/prototype_logs.png) +### How to customize fleet workers + +> **Note:** This is an experimental feature to unlock specific use cases and might change or will be deprecated. + +Fleet workers can be customized using startup hooks to prepare the environment before tasks are executed. This allows you to install additional software, pull container images, or configure services that your tasks will use. + +#### Example 1: Running Ollama on Fleet Workers + +See `run_hook_ollama` for a complete example that demonstrates: +- Running Ollama (local LLM runtime) on fleet workers +- Automatic GPU detection and configuration +- Preloading AI models during worker startup +- Using `__CE_INTERNAL_HOOK_AFTER_STARTUP` to execute setup scripts + +Key environment variables used: +- `__CE_INTERNAL_HOOK_AFTER_STARTUP`: Script to run after worker startup +- `__CE_INTERNAL_HOOK_AFTER_STARTUP_RETRY_LIMIT=3`: Retry attempts if hook fails +- `__CE_INTERNAL_HOOK_AFTER_STARTUP_MAX_EXECUTION_TIME=30m`: Maximum hook execution time + +#### Example 2: Running Podman-in-Podman + +See `run_hook_podman_in_podman` for a complete example that demonstrates: +- Running Podman inside fleet workers for nested containerization +- Preloading container images during startup +- Using privileged containers and host path mounts + +Additional environment variables used: +- `__CE_INTERNAL_PRIVILEGED_CONTAINER=true`: Enable privileged mode (required for nested containers) +- `__CE_INTERNAL_HOSTPATH_MOUNTS=/var/lib/containers:/var/lib/containers`: Mount host paths + +**Available Hook Environment Variables:** +- `__CE_INTERNAL_HOOK_AFTER_STARTUP`: The script to execute after worker startup +- `__CE_INTERNAL_HOOK_AFTER_STARTUP_RETRY_LIMIT`: Number of retry attempts if the hook fails +- `__CE_INTERNAL_HOOK_AFTER_STARTUP_MAX_EXECUTION_TIME`: Maximum time allowed for hook execution +- `__CE_INTERNAL_PRIVILEGED_CONTAINER`: Enable privileged mode +- `__CE_INTERNAL_HOSTPATH_MOUNTS`: Mount host paths into the container + ### Cleanup the Environment To clean up all IBM Cloud resources, that have been created as part of the provided script, run: diff --git a/serverless-fleets/run_hook_ollama b/serverless-fleets/run_hook_ollama new file mode 100755 index 00000000..c13f6e80 --- /dev/null +++ b/serverless-fleets/run_hook_ollama @@ -0,0 +1,49 @@ +#!/bin/bash + +set -e + +uuid=$(uuidgen | tr '[:upper:]' '[:lower:]' | awk -F- '{print $1}') + +PREHOOK=$(cat <<'EOF' +#!/bin/bash + +if nvidia-smi >/dev/null 2>&1; then + echo "NVIDIA GPU detected" + podman run -d --device nvidia.com/gpu=all -v ollama:/root/.ollama -p 11434:11434 --name ollama docker.io/ollama/ollama +else + echo "No NVIDIA GPU detected" + podman run -d -v ollama:/root/.ollama -p 11434:11434 --name ollama docker.io/ollama/ollama:latest +fi + +# pull the model into ollama +podman exec -it ollama ollama pull granite4:350m +EOF +) + +echo code-engine fleet create --name "fleet-${uuid}-1" +echo " "--tasks-state-store fleet-task-store +echo " "--subnetpool-name fleet-subnetpool +echo " "--image registry.access.redhat.com/ubi10/ubi-minimal +echo " "--max-scale 1 +echo " "--command="curl" +echo " "--arg "http://host.containers.internal:8080" +echo " "--tasks 1 +echo " "--env __CE_INTERNAL_HOOK_AFTER_STARTUP="${PREHOOK}" +echo " "__CE_INTERNAL_HOOK_AFTER_STARTUP_RETRY_LIMIT=3 +echo " "__CE_INTERNAL_HOOK_AFTER_STARTUP_MAX_EXECUTION_TIME=10m +echo " "--cpu 2 +echo " "--memory 4G + +ibmcloud code-engine fleet create --name "fleet-${uuid}-1" \ + --tasks-state-store fleet-task-store \ + --subnetpool-name fleet-subnetpool \ + --image registry.access.redhat.com/ubi10/ubi-minimal \ + --max-scale 1 \ + --command="curl" \ + --arg "http://host.containers.internal:11434/api/tags" \ + --tasks 1 \ + --env __CE_INTERNAL_HOOK_AFTER_STARTUP="${PREHOOK}" \ + --env __CE_INTERNAL_HOOK_AFTER_STARTUP_RETRY_LIMIT=3 \ + --env __CE_INTERNAL_HOOK_AFTER_STARTUP_MAX_EXECUTION_TIME=30m \ + --cpu 2 \ + --memory 4G \ No newline at end of file diff --git a/serverless-fleets/run_hook_podman_in_podman b/serverless-fleets/run_hook_podman_in_podman new file mode 100755 index 00000000..d3325b72 --- /dev/null +++ b/serverless-fleets/run_hook_podman_in_podman @@ -0,0 +1,49 @@ +#!/bin/bash + +set -e + +ibmcloud login --sso -a cloud.ibm.com -r eu-de -c 1260a3541bb44fefb9c58d5cc92aaddb -g luke-new-ce-fleet-sandbox--rg +ibmcloud ce project select -n luke-new-ce-fleet-sandbox--ce-project + +uuid=$(uuidgen | tr '[:upper:]' '[:lower:]' | awk -F- '{print $1}') + +PREHOOK=$(cat <<'EOF' +#!/bin/bash +podman pull docker.io/library/hello-world:latest +EOF +) + + +echo ibmcloud code-engine fleet create --name "fleet-${uuid}-1" +echo " "--tasks-state-store fleet-task-store +echo " "--subnetpool-name fleet-subnetpool +echo " "--image quay.io/podman/stable:latest +echo " "--max-scale 1 +echo " "--command="podman" +echo " "--arg "run" +echo " "--arg "hello-world" +echo " "--tasks 1 +echo " "--env __CE_INTERNAL_HOOK_AFTER_STARTUP="${PREHOOK}" +echo " "__CE_INTERNAL_HOOK_AFTER_STARTUP_RETRY_LIMIT=3 +echo " "__CE_INTERNAL_HOOK_AFTER_STARTUP_MAX_EXECUTION_TIME=10m +echo " "--env __CE_INTERNAL_PRIVILEGED_CONTAINER=true +echo " "--env __CE_INTERNAL_HOSTPATH_MOUNTS=/var/lib/containers:/var/lib/containers +echo " "--cpu 2 +echo " "--memory 4G + +ibmcloud code-engine fleet create --name "fleet-${uuid}-1" \ + --tasks-state-store fleet-task-store \ + --subnetpool-name fleet-subnetpool \ + --image quay.io/podman/stable:latest \ + --max-scale 1 \ + --command="podman" \ + --arg "run" \ + --arg "hello-world" \ + --tasks 1 \ + --env __CE_INTERNAL_HOOK_AFTER_STARTUP="${PREHOOK}" \ + --env __CE_INTERNAL_HOOK_AFTER_STARTUP_RETRY_LIMIT=3 \ + --env __CE_INTERNAL_HOOK_AFTER_STARTUP_MAX_EXECUTION_TIME=10m \ + --env __CE_INTERNAL_PRIVILEGED_CONTAINER=true \ + --env __CE_INTERNAL_HOSTPATH_MOUNTS=/var/lib/containers:/var/lib/containers \ + --cpu 2 \ + --memory 4G \ No newline at end of file From 974d30d00aa8ca6a0e78359c4a0a6fd766c70d3c Mon Sep 17 00:00:00 2001 From: Luke Roy <83647952+Luke-Roy-IBM@users.noreply.github.com> Date: Thu, 16 Apr 2026 17:19:59 +0200 Subject: [PATCH 2/6] Update serverless-fleets/README.md Co-authored-by: Enrico Regge <36001299+reggeenr@users.noreply.github.com> --- serverless-fleets/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/serverless-fleets/README.md b/serverless-fleets/README.md index 8cd2e5ee..cfbcf0bc 100644 --- a/serverless-fleets/README.md +++ b/serverless-fleets/README.md @@ -570,7 +570,7 @@ See `run_hook_ollama` for a complete example that demonstrates: - Running Ollama (local LLM runtime) on fleet workers - Automatic GPU detection and configuration - Preloading AI models during worker startup -- Using `__CE_INTERNAL_HOOK_AFTER_STARTUP` to execute setup scripts +- Using the environment variable `__CE_INTERNAL_HOOK_AFTER_STARTUP` to execute setup scripts Key environment variables used: - `__CE_INTERNAL_HOOK_AFTER_STARTUP`: Script to run after worker startup From e6f6b8b3d3b2f96c9c0a56843a8393681460d82f Mon Sep 17 00:00:00 2001 From: Luke Roy <83647952+Luke-Roy-IBM@users.noreply.github.com> Date: Thu, 16 Apr 2026 17:20:12 +0200 Subject: [PATCH 3/6] Update serverless-fleets/run_hook_ollama Co-authored-by: Enrico Regge <36001299+reggeenr@users.noreply.github.com> --- serverless-fleets/run_hook_ollama | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/serverless-fleets/run_hook_ollama b/serverless-fleets/run_hook_ollama index c13f6e80..89cd0c96 100755 --- a/serverless-fleets/run_hook_ollama +++ b/serverless-fleets/run_hook_ollama @@ -26,7 +26,7 @@ echo " "--subnetpool-name fleet-subnetpool echo " "--image registry.access.redhat.com/ubi10/ubi-minimal echo " "--max-scale 1 echo " "--command="curl" -echo " "--arg "http://host.containers.internal:8080" +echo " "--arg "http://host.containers.internal:11434/api/tags" echo " "--tasks 1 echo " "--env __CE_INTERNAL_HOOK_AFTER_STARTUP="${PREHOOK}" echo " "__CE_INTERNAL_HOOK_AFTER_STARTUP_RETRY_LIMIT=3 From 24b4357a73483ed8af6385384afc078825af08ca Mon Sep 17 00:00:00 2001 From: Luke Roy Date: Thu, 16 Apr 2026 17:24:19 +0200 Subject: [PATCH 4/6] update readme Signed-off-by: Luke Roy --- serverless-fleets/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/serverless-fleets/README.md b/serverless-fleets/README.md index cfbcf0bc..7f3fbc68 100644 --- a/serverless-fleets/README.md +++ b/serverless-fleets/README.md @@ -562,7 +562,7 @@ An IBM Cloud Logs instance is being setup and enabled by default during the auto > **Note:** This is an experimental feature to unlock specific use cases and might change or will be deprecated. -Fleet workers can be customized using startup hooks to prepare the environment before tasks are executed. This allows you to install additional software, pull container images, or configure services that your tasks will use. +Fleet workers can be customized using startup hooks to prepare the environment before tasks are executed. These hooks are configured through special environment variables that you set when creating the fleet. This customization capability allows you to install additional software, pull container images, or configure services that your tasks will use—all automatically before your workload begins processing. #### Example 1: Running Ollama on Fleet Workers From c96b71a443c7fca6fae7d8ccbaf330e27edde602 Mon Sep 17 00:00:00 2001 From: Luke Roy <83647952+Luke-Roy-IBM@users.noreply.github.com> Date: Thu, 16 Apr 2026 19:33:36 +0200 Subject: [PATCH 5/6] Apply suggestion from @Luke-Roy-IBM --- serverless-fleets/run_hook_podman_in_podman | 1 - 1 file changed, 1 deletion(-) diff --git a/serverless-fleets/run_hook_podman_in_podman b/serverless-fleets/run_hook_podman_in_podman index d3325b72..e347b829 100755 --- a/serverless-fleets/run_hook_podman_in_podman +++ b/serverless-fleets/run_hook_podman_in_podman @@ -3,7 +3,6 @@ set -e ibmcloud login --sso -a cloud.ibm.com -r eu-de -c 1260a3541bb44fefb9c58d5cc92aaddb -g luke-new-ce-fleet-sandbox--rg -ibmcloud ce project select -n luke-new-ce-fleet-sandbox--ce-project uuid=$(uuidgen | tr '[:upper:]' '[:lower:]' | awk -F- '{print $1}') From b828805b9cadaed025141a23a4384990c7da5634 Mon Sep 17 00:00:00 2001 From: Luke Roy <83647952+Luke-Roy-IBM@users.noreply.github.com> Date: Thu, 16 Apr 2026 19:33:49 +0200 Subject: [PATCH 6/6] Apply suggestion from @Luke-Roy-IBM --- serverless-fleets/run_hook_podman_in_podman | 1 - 1 file changed, 1 deletion(-) diff --git a/serverless-fleets/run_hook_podman_in_podman b/serverless-fleets/run_hook_podman_in_podman index e347b829..e6692594 100755 --- a/serverless-fleets/run_hook_podman_in_podman +++ b/serverless-fleets/run_hook_podman_in_podman @@ -2,7 +2,6 @@ set -e -ibmcloud login --sso -a cloud.ibm.com -r eu-de -c 1260a3541bb44fefb9c58d5cc92aaddb -g luke-new-ce-fleet-sandbox--rg uuid=$(uuidgen | tr '[:upper:]' '[:lower:]' | awk -F- '{print $1}')