[ROCm][CI] Build and publish TheRock nightly docker images (#55014)

Signed-off-by: Rohan Potdar <rohan.potdar@amd.com> Signed-off-by: Andreas Karatzas <Andreas.Karatzas@amd.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Co-authored-by: Andreas Karatzas <Andreas.Karatzas@amd.com> Co-authored-by: OpenAI Codex <noreply@openai.com>

Rohan Potdar committed Sep 3, 2026 at 21:34 UTC 7dc30f5a663d1d3fcadf73ffd297682b56a69197
2 files changed +219 -34
.buildkite/release-pipeline.yaml
+138
@@ -959,6 +959,144 @@ steps:
959 DOCKER_BUILDKIT: "1"
960 DOCKERHUB_USERNAME: "vllmbot"
961
962 + # =============================================================================
963 + # ROCk Release Pipeline (x86_64 only)
964 + # =============================================================================
965 + #
966 + # Same shape as the ROCm pipeline above (Jobs 1 and 6 only), but built from
967 + # docker/Dockerfile.rock_base and docker/Dockerfile.rock, which install the
968 + # ROCm SDK from TheRock wheels instead of the ROCm apt repos.
969 + #
970 + # Note: ROCm SDK version is determined by ROCM_SDK_VERSION in
971 + # docker/Dockerfile.rock_base
972 + #
973 + # =============================================================================
974 +
975 + - group: "Build ROCk Image"
976 + key: "build-rock-image"
977 + depends_on: ~
978 + steps:
979 + # ROCk Job 1: Build ROCk Base Image (with ECR caching)
980 + - label: ":rocm: Build ROCk Base Image"
981 + id: build-rock-base-image
982 + depends_on: ~
983 + agents:
984 + queue: cpu_queue_release
985 + timeout_in_minutes: 360
986 + commands:
987 + - |
988 + set -euo pipefail
989 +
990 + # The SDK version, torch wheels and component branches all live in
991 + # the Dockerfile, so its hash is the cache key.
992 + CACHE_KEY=$$(sha256sum docker/Dockerfile.rock_base | cut -c1-16)
993 + ECR_CACHE_TAG="public.ecr.aws/q9t5s3a7/vllm-release-repo:$${CACHE_KEY}-rock-base"
994 +
995 + echo "========================================"
996 + echo "ROCk Base Build Configuration"
997 + echo "========================================"
998 + echo " CACHE_KEY: $${CACHE_KEY}"
999 + echo " ECR_CACHE_TAG: $${ECR_CACHE_TAG}"
1000 + echo "========================================"
1001 +
1002 + # Login to ECR
1003 + aws ecr-public get-login-password --region us-east-1 | \
1004 + docker login --username AWS --password-stdin public.ecr.aws/q9t5s3a7
1005 +
1006 + if docker manifest inspect "$${ECR_CACHE_TAG}" > /dev/null 2>&1; then
1007 + echo "ECR image cache HIT"
1008 + else
1009 + echo "CACHE MISS - Building from scratch..."
1010 +
1011 + DOCKER_BUILDKIT=1 docker buildx build \
1012 + --file docker/Dockerfile.rock_base \
1013 + --tag "$${ECR_CACHE_TAG}" \
1014 + --build-arg USE_SCCACHE=1 \
1015 + --build-arg SCCACHE_BUCKET_NAME=vllm-build-sccache \
1016 + --build-arg SCCACHE_REGION_NAME=us-west-2 \
1017 + --build-arg SCCACHE_S3_NO_CREDENTIALS=0 \
1018 + --push \
1019 + .
1020 + fi
1021 +
1022 + # Save ECR tag for downstream jobs
1023 + buildkite-agent meta-data set "rock-base-image-tag" "$${ECR_CACHE_TAG}"
1024 + env:
1025 + DOCKER_BUILDKIT: "1"
1026 +
1027 + # ROCk Job 2: Build ROCk Release Docker Image
1028 + - label: ":docker: Build release image - x86_64 - ROCk"
1029 + id: build-rock-release-image
1030 + depends_on:
1031 + - step: block-build-release-images
1032 + allow_failure: true
1033 + - step: build-rock-base-image
1034 + allow_failure: false
1035 + agents:
1036 + queue: cpu_queue_release
1037 + timeout_in_minutes: 60
1038 + commands:
1039 + - |
1040 + set -euo pipefail
1041 +
1042 + # Login to ECR
1043 + aws ecr-public get-login-password --region us-east-1 | \
1044 + docker login --username AWS --password-stdin public.ecr.aws/q9t5s3a7
1045 +
1046 + ECR_IMAGE_TAG="$$(buildkite-agent meta-data get rock-base-image-tag 2>/dev/null || echo '')"
1047 + if [ -z "$${ECR_IMAGE_TAG}" ]; then
1048 + echo "ERROR: rock-base-image-tag metadata not found"
1049 + echo "This should have been set by the build-rock-base-image job"
1050 + exit 1
1051 + fi
1052 +
1053 + docker pull "$${ECR_IMAGE_TAG}"
1054 +
1055 + # Pass the base image ECR tag to downstream steps (nightly publish)
1056 + buildkite-agent meta-data set "rock-base-ecr-tag" "$${ECR_IMAGE_TAG}"
1057 +
1058 + echo "========================================"
1059 + echo "Building vLLM ROCk release image with:"
1060 + echo " BASE_IMAGE: $${ECR_IMAGE_TAG}"
1061 + echo " BUILDKITE_COMMIT: $${BUILDKITE_COMMIT}"
1062 + echo "========================================"
1063 +
1064 + DOCKER_BUILDKIT=1 docker build \
1065 + --build-arg max_jobs=16 \
1066 + --build-arg BASE_IMAGE="$${ECR_IMAGE_TAG}" \
1067 + --build-arg USE_SCCACHE=1 \
1068 + --build-arg SCCACHE_BUCKET_NAME=vllm-build-sccache \
1069 + --build-arg SCCACHE_REGION_NAME=us-west-2 \
1070 + --build-arg SCCACHE_S3_NO_CREDENTIALS=0 \
1071 + --build-arg INSTALL_LMCACHE=true \
1072 + --tag public.ecr.aws/q9t5s3a7/vllm-release-repo:$${BUILDKITE_COMMIT}-rock \
1073 + --target vllm-openai \
1074 + --progress plain \
1075 + -f docker/Dockerfile.rock .
1076 +
1077 + docker push public.ecr.aws/q9t5s3a7/vllm-release-repo:$${BUILDKITE_COMMIT}-rock
1078 + env:
1079 + DOCKER_BUILDKIT: "1"
1080 +
1081 + - label: "Publish nightly ROCk image to DockerHub"
1082 + depends_on:
1083 + - build-rock-release-image
1084 + if: build.env("NIGHTLY") == "1"
1085 + agents:
1086 + queue: small_cpu_queue_release
1087 + commands:
1088 + - "bash .buildkite/scripts/push-nightly-builds-rocm.sh rock rocm714"
1089 + # Clean up old nightly builds (keep only last 14)
1090 + - "bash .buildkite/scripts/cleanup-nightly-builds.sh nightly-rocm714- vllm/vllm-openai-rocm"
1091 + - "bash .buildkite/scripts/cleanup-nightly-builds.sh base-nightly-rocm714- vllm/vllm-openai-rocm"
1092 + plugins:
1093 + - docker-login#v3.0.0:
1094 + username: vllmbot
1095 + password-env: DOCKERHUB_TOKEN
1096 + env:
1097 + DOCKER_BUILDKIT: "1"
1098 + DOCKERHUB_USERNAME: "vllmbot"
1099 +
1100 # =============================================================================
1101 # Publish to DockerHub and PyPI (at the end so all builds complete first)
1102 # =============================================================================
.buildkite/scripts/push-nightly-builds-rocm.sh
+81 -34
@@ -2,61 +2,108 @@
2 # SPDX-License-Identifier: Apache-2.0
3 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
4 #
5 -# Push ROCm nightly base image and nightly image from ECR
6 -# to Docker Hub as vllm/vllm-openai-rocm:base-nightly and vllm/vllm-openai-rocm:nightly
7 -# and vllm/vllm-openai-rocm:base-nightly-<commit> and vllm/vllm-openai-rocm:nightly-<commit>.
8 -# Run when NIGHTLY=1 after build-rocm-release-image has pushed to ECR.
5 +# Push a ROCm-family nightly base image and nightly image from ECR to Docker Hub
6 +# under vllm/vllm-openai-rocm, as base-nightly[-<variant>], nightly[-<variant>]
7 +# and their -<commit> forms.
8 +# Run when NIGHTLY=1 after the matching build-*-release-image step has pushed to ECR.
9 +#
10 +# Usage: push-nightly-builds-rocm.sh [ECR_TAG_SUFFIX TAG_VARIANT]
11 +# Pass both arguments or neither. With none, the default ROCm apt build is
12 +# published as :nightly. The TheRock build passes "rock" (the source ECR tag
13 +# suffix) and "rocm714" (the Docker Hub tag flavor), giving :nightly-rocm714.
14 #
15 # Local testing (no push to Docker Hub):
11 -# BUILDKITE_COMMIT=<commit-with-rocm-image-in-ecr> DRY_RUN=1 bash .buildkite/scripts/push-nightly-builds-rocm.sh
16 +# BASE_ECR_IMAGE=<full-base-image-reference> \
17 +# BUILDKITE_COMMIT=<commit-with-image-in-ecr> DRY_RUN=1 \
18 +# bash .buildkite/scripts/push-nightly-builds-rocm.sh
19 # Requires: AWS CLI configured (for ECR public login), Docker. For full run: Docker Hub login.
20
14 -set -ex
21 +set -euxo pipefail
22 +
23 +usage() {
24 + echo "Usage: $0 [ECR_TAG_SUFFIX TAG_VARIANT]" >&2
25 +}
26 +
27 +DOCKERHUB_REPO="vllm/vllm-openai-rocm"
28
16 -# Use BUILDKITE_COMMIT from env (required; set to a commit that has ROCm image in ECR for local test)
17 -BUILDKITE_COMMIT="${BUILDKITE_COMMIT:?Set BUILDKITE_COMMIT to the commit SHA that has the ROCm image in ECR (e.g. from a previous release pipeline run)}"
29 +case "$#" in
30 + 0)
31 + ECR_TAG_SUFFIX="rocm"
32 + TAG_VARIANT=""
33 + ;;
34 + 2)
35 + if [[ -z "$1" || -z "$2" ]]; then
36 + usage
37 + exit 2
38 + fi
39 + ECR_TAG_SUFFIX="$1"
40 + TAG_VARIANT="$2"
41 + ;;
42 + *)
43 + usage
44 + exit 2
45 + ;;
46 +esac
47 +
48 +# Use BUILDKITE_COMMIT from env (required; set to a commit that has the image in ECR for local test)
49 +BUILDKITE_COMMIT="${BUILDKITE_COMMIT:?Set BUILDKITE_COMMIT to the commit SHA that has the image in ECR (e.g. from a previous release pipeline run)}"
50 DRY_RUN="${DRY_RUN:-0}"
51
20 -# Get the base image ECR tag (set by build-rocm-release-image pipeline step)
21 -BASE_ORIG_TAG="$(buildkite-agent meta-data get rocm-base-ecr-tag 2>/dev/null || echo "")"
22 -if [ -z "$BASE_ORIG_TAG" ]; then
23 - echo "WARNING: rocm-base-ecr-tag metadata not found, falling back to commit-based tag"
24 - BASE_ORIG_TAG="public.ecr.aws/q9t5s3a7/vllm-release-repo:${BUILDKITE_COMMIT}-rocm-base"
52 +ECR_REPO="public.ecr.aws/q9t5s3a7/vllm-release-repo"
53 +
54 +# Get the base image ECR tag (set by the build-*-release-image pipeline step)
55 +BASE_METADATA_KEY="${ECR_TAG_SUFFIX}-base-ecr-tag"
56 +if [[ -n "${BASE_ECR_IMAGE:-}" ]]; then
57 + if [[ "$DRY_RUN" != "1" ]]; then
58 + echo "ERROR: BASE_ECR_IMAGE may only be used with DRY_RUN=1" >&2
59 + exit 1
60 + fi
61 + BASE_ORIG_TAG="$BASE_ECR_IMAGE"
62 +elif ! BASE_ORIG_TAG="$(buildkite-agent meta-data get "$BASE_METADATA_KEY")"; then
63 + echo "ERROR: Failed to read required Buildkite metadata '$BASE_METADATA_KEY'" >&2
64 + exit 1
65 +fi
66 +if [[ -z "$BASE_ORIG_TAG" ]]; then
67 + echo "ERROR: Required Buildkite metadata '$BASE_METADATA_KEY' is empty" >&2
68 + echo "Set BASE_ECR_IMAGE to the full ECR base image reference for local testing" >&2
69 + exit 1
70 fi
71
27 -ORIG_TAG="${BUILDKITE_COMMIT}-rocm"
28 -BASE_TAG_NAME="base-nightly"
29 -TAG_NAME="nightly"
30 -BASE_TAG_NAME_COMMIT="base-nightly-${BUILDKITE_COMMIT}"
31 -TAG_NAME_COMMIT="nightly-${BUILDKITE_COMMIT}"
72 +ORIG_TAG="${BUILDKITE_COMMIT}-${ECR_TAG_SUFFIX}"
73 +VARIANT_SUFFIX=""
74 +[[ -n "$TAG_VARIANT" ]] && VARIANT_SUFFIX="-$TAG_VARIANT"
75 +BASE_TAG_NAME="base-nightly${VARIANT_SUFFIX}"
76 +TAG_NAME="nightly${VARIANT_SUFFIX}"
77 +BASE_TAG_NAME_COMMIT="base-nightly${VARIANT_SUFFIX}-${BUILDKITE_COMMIT}"
78 +TAG_NAME_COMMIT="nightly${VARIANT_SUFFIX}-${BUILDKITE_COMMIT}"
79
33 -echo "Pushing ROCm base image from ECR: $BASE_ORIG_TAG"
34 -echo "Pushing ROCm release image from ECR tag: $ORIG_TAG to Docker Hub as $TAG_NAME and $TAG_NAME_COMMIT"
80 +echo "Pushing base image from ECR: $BASE_ORIG_TAG"
81 +echo "Pushing release image from ECR tag: $ORIG_TAG to Docker Hub as $DOCKERHUB_REPO:$TAG_NAME and $DOCKERHUB_REPO:$TAG_NAME_COMMIT"
82 [[ "$DRY_RUN" == "1" ]] && echo "[DRY_RUN] Skipping push to Docker Hub"
83
37 -# Login to ECR and pull the image built by build-rocm-release-image
84 +# Login to ECR and pull the images built by build-*-release-image
85 aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws/q9t5s3a7
86 docker pull "$BASE_ORIG_TAG"
40 -docker pull public.ecr.aws/q9t5s3a7/vllm-release-repo:"$ORIG_TAG"
87 +docker pull "${ECR_REPO}:${ORIG_TAG}"
88
89 # Tag for Docker Hub (base-nightly and base-nightly-<commit>, nightly and nightly-<commit>)
43 -docker tag "$BASE_ORIG_TAG" vllm/vllm-openai-rocm:"$BASE_TAG_NAME"
44 -docker tag "$BASE_ORIG_TAG" vllm/vllm-openai-rocm:"$BASE_TAG_NAME_COMMIT"
45 -docker tag public.ecr.aws/q9t5s3a7/vllm-release-repo:"$ORIG_TAG" vllm/vllm-openai-rocm:"$TAG_NAME"
46 -docker tag public.ecr.aws/q9t5s3a7/vllm-release-repo:"$ORIG_TAG" vllm/vllm-openai-rocm:"$TAG_NAME_COMMIT"
90 +docker tag "$BASE_ORIG_TAG" "$DOCKERHUB_REPO":"$BASE_TAG_NAME"
91 +docker tag "$BASE_ORIG_TAG" "$DOCKERHUB_REPO":"$BASE_TAG_NAME_COMMIT"
92 +docker tag "${ECR_REPO}:${ORIG_TAG}" "$DOCKERHUB_REPO":"$TAG_NAME"
93 +docker tag "${ECR_REPO}:${ORIG_TAG}" "$DOCKERHUB_REPO":"$TAG_NAME_COMMIT"
94
95 if [[ "$DRY_RUN" == "1" ]]; then
49 - echo "[DRY_RUN] Would push vllm/vllm-openai-rocm:$BASE_TAG_NAME and vllm/vllm-openai-rocm:$BASE_TAG_NAME_COMMIT"
50 - echo "[DRY_RUN] Would push vllm/vllm-openai-rocm:$TAG_NAME and vllm/vllm-openai-rocm:$TAG_NAME_COMMIT"
96 + echo "[DRY_RUN] Would push $DOCKERHUB_REPO:$BASE_TAG_NAME and $DOCKERHUB_REPO:$BASE_TAG_NAME_COMMIT"
97 + echo "[DRY_RUN] Would push $DOCKERHUB_REPO:$TAG_NAME and $DOCKERHUB_REPO:$TAG_NAME_COMMIT"
98 echo "[DRY_RUN] Local tags created. Exiting without push."
99 exit 0
100 fi
101
102 # Push to Docker Hub (docker-login plugin runs before this step in CI)
56 -docker push vllm/vllm-openai-rocm:"$BASE_TAG_NAME"
57 -docker push vllm/vllm-openai-rocm:"$BASE_TAG_NAME_COMMIT"
58 -docker push vllm/vllm-openai-rocm:"$TAG_NAME"
59 -docker push vllm/vllm-openai-rocm:"$TAG_NAME_COMMIT"
103 +docker push "$DOCKERHUB_REPO":"$BASE_TAG_NAME"
104 +docker push "$DOCKERHUB_REPO":"$BASE_TAG_NAME_COMMIT"
105 +docker push "$DOCKERHUB_REPO":"$TAG_NAME"
106 +docker push "$DOCKERHUB_REPO":"$TAG_NAME_COMMIT"
107
61 -echo "Pushed vllm/vllm-openai-rocm:$BASE_TAG_NAME and vllm/vllm-openai-rocm:$BASE_TAG_NAME_COMMIT"
62 -echo "Pushed vllm/vllm-openai-rocm:$TAG_NAME and vllm/vllm-openai-rocm:$TAG_NAME_COMMIT"
108 +echo "Pushed $DOCKERHUB_REPO:$BASE_TAG_NAME and $DOCKERHUB_REPO:$BASE_TAG_NAME_COMMIT"
109 +echo "Pushed $DOCKERHUB_REPO:$TAG_NAME and $DOCKERHUB_REPO:$TAG_NAME_COMMIT"