diff --git a/.github/workflows/build-sim-image.yml b/.github/workflows/build-sim-image.yml new file mode 100644 index 00000000..990ec7ef --- /dev/null +++ b/.github/workflows/build-sim-image.yml @@ -0,0 +1,107 @@ +name: Build simulator image + +# Builds an Ubuntu-based image with the simulator side fully installed +# (ASTRA-Sim analytical backend, chakra, python deps — exactly what +# scripts/install-sim.sh produces on a bare host) and pushes it to +# GitHub Container Registry. PRs run the build to validate the install +# path; only pushes to main (and manual dispatch) publish the image. + +on: + push: + branches: [main] + paths: + - 'scripts/install-sim.sh' + - 'scripts/compile.sh' + - 'scripts/sim.Dockerfile' + - 'astra-sim' + - '.gitmodules' + - '.github/workflows/build-sim-image.yml' + pull_request: + paths: + - 'scripts/install-sim.sh' + - 'scripts/compile.sh' + - 'scripts/sim.Dockerfile' + - 'astra-sim' + - '.gitmodules' + - '.github/workflows/build-sim-image.yml' + workflow_dispatch: + +permissions: + contents: read + packages: write + +env: + REGISTRY: ghcr.io + +# One in-flight build per ref; queued PR builds get cancelled in favour +# of the newest commit. Main pushes finish. +concurrency: + group: build-sim-image-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout (with submodules) + uses: actions/checkout@v4 + with: + submodules: recursive + + # GHCR rejects uppercase characters in image names, but + # ${{ github.repository }} preserves the original case + # (PSAL-POSTECH/LLMServingSimSpec). Lowercase it once here so + # every downstream step sees a clean reference. + - name: Resolve image name (lowercase) + id: img + run: | + name="${GITHUB_REPOSITORY,,}/sim" + echo "ref=${REGISTRY}/${name}" >> "$GITHUB_OUTPUT" + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to GHCR + if: github.event_name != 'pull_request' + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + # latest → main only; sha- → every build; branch tag for + # non-main branches so feature-branch images are addressable. + - name: Image tags + labels + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ steps.img.outputs.ref }} + tags: | + type=raw,value=latest,enable={{is_default_branch}} + type=sha,prefix=sha-,format=short + type=ref,event=branch + + - name: Build (and push if not PR) + uses: docker/build-push-action@v5 + with: + context: . + file: scripts/sim.Dockerfile + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Summary + if: always() + run: | + { + echo "### Simulator image" + echo + echo "- **image:** \`${{ steps.img.outputs.ref }}\`" + echo "- **tags:**" + echo '```' + echo "${{ steps.meta.outputs.tags }}" + echo '```' + echo "- **pushed:** ${{ github.event_name != 'pull_request' }}" + } >> "$GITHUB_STEP_SUMMARY" diff --git a/scripts/README.md b/scripts/README.md index 2e66688e..12a7bcdf 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -14,6 +14,7 @@ live with their module — only setup and build helpers are here. | `install-vllm-cpu.sh` | Bare-metal vLLM **CPU** install. Builds vLLM 0.19.0 from source with `VLLM_TARGET_DEVICE=cpu` into `.venv-cpu` (separate from the GPU venv). Works on x86_64 and aarch64 (NVIDIA Grace). Used by `profiler/profile-cpu.sh`. | | `install-sim.sh` | Bare-metal simulator install for fresh Docker containers / minimal Linux hosts (root or non-root). Installs apt build deps, inits submodules, pip-installs sim Python deps, builds ASTRA-Sim's analytical backend, and installs the Chakra converter (`--no-deps`). Skips vLLM — profiler/bench need `install-vllm.sh` and a GPU. Idempotent. | | `compile.sh` | Build ASTRA-Sim's analytical backend and install the Chakra trace converter. | +| `sim.Dockerfile` | Ubuntu 24.04 base + `install-sim.sh`. Built and published to GHCR by `.github/workflows/build-sim-image.yml` on every push to `main` touching the install / build paths. Pull with `docker pull ghcr.io/psal-postech/llmservingsimspec/sim:latest`. | ## Typical first-time setup diff --git a/scripts/sim.Dockerfile b/scripts/sim.Dockerfile new file mode 100644 index 00000000..975abd05 --- /dev/null +++ b/scripts/sim.Dockerfile @@ -0,0 +1,45 @@ +# LLMServingSim simulator image. +# +# Built by .github/workflows/build-sim-image.yml on every push to main +# that touches scripts/install-sim.sh, the astra-sim submodule, or this +# file. Published to ghcr.io///sim. +# +# Local build: +# docker build -f scripts/sim.Dockerfile -t llmservingsim-sim . +# +# Local run (mount your working copy over /workspace if you want live +# edits — the image carries the repo state at build time): +# docker run -it --rm -v "$(pwd)":/workspace llmservingsim-sim bash + +FROM ubuntu:24.04 + +ENV DEBIAN_FRONTEND=noninteractive \ + PIP_BREAK_SYSTEM_PACKAGES=1 + +# Pre-install the apt packages install-sim.sh expects. Doing this in a +# dedicated layer lets Docker cache them independently of the script's +# pip / submodule / build steps further down, which is what dominates +# rebuild time when the source changes. +RUN apt-get update -qq \ + && apt-get install -y -qq --no-install-recommends \ + git build-essential cmake \ + protobuf-compiler libprotobuf-dev \ + python3 python3-pip python-is-python3 \ + ca-certificates curl \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /workspace + +# Copy the repo (including submodules — the workflow's checkout step +# fetches them on the runner so they're in the build context). +COPY . /workspace + +# install-sim.sh is idempotent and detects pre-installed apt packages, +# so its apt phase is a no-op here; the work it actually does in this +# layer is: python deps, ASTRA-Sim analytical-backend build, chakra +# install. See the script for the full sequence. +RUN bash scripts/install-sim.sh + +# Default entry: interactive shell at the repo root. Match docker-sim.sh +# behaviour so the two surfaces (CI image / dev script) feel the same. +CMD ["/bin/bash"]