Use GitHub-hosted aarch64 runners (#2202)

* Use GitHub-hosted aarch64 runners

* More updates

* Fix

* Pin build environment's Python version to 3.12 for consistency

* Update date

* Sleep to allow Docker daemon to start

* Sleep to allow Docker daemon to start on aarch64 and before checkout

* Fix typo

* Fix

* Unify runner.arch usage

* Do not sleep as it doesn't help

* Try to use ubuntu-22.04-arm

* Update changelog date

---------

Co-authored-by: Erik Sundell <erik.i.sundell@gmail.com>
This commit is contained in:
Ayaz Salikhov
2025-02-11 15:04:53 +00:00
committed by GitHub
parent 83600cfa50
commit 8c38e0f00f
14 changed files with 38 additions and 119 deletions

View File

@@ -4,14 +4,10 @@ description: Create a build environment
runs: runs:
using: composite using: composite
steps: steps:
# actions/setup-python doesn't support Linux aarch64 runners
# See: https://github.com/actions/setup-python/issues/108
# python3 is manually preinstalled in the aarch64 VM self-hosted runner
- name: Set Up Python 🐍 - name: Set Up Python 🐍
uses: actions/setup-python@v5 uses: actions/setup-python@v5
with: with:
python-version: 3.x python-version: "3.12"
if: runner.arch == 'X64'
- name: Install Dev Dependencies 📦 - name: Install Dev Dependencies 📦
run: | run: |

View File

@@ -1,31 +0,0 @@
name: Test aarch64-runner setup script
on:
schedule:
# Weekly, at 03:00 on Monday UTC
- cron: "0 3 * * 1"
pull_request:
paths:
- ".github/workflows/aarch64-setup.yml"
- "aarch64-runner/setup.sh"
push:
branches:
- main
paths:
- ".github/workflows/aarch64-setup.yml"
- "aarch64-runner/setup.sh"
workflow_dispatch:
jobs:
test-script:
# The script itself is not aarch64-specific
# It is easier to test on x86_64
# Using `ubuntu-22.04` as this is what our aarch64 runners currently use
runs-on: ubuntu-22.04
steps:
- name: Checkout Repo ⚡️
uses: actions/checkout@v4
- name: Run setup script ✅
run: sudo ./aarch64-runner/setup.sh

View File

@@ -44,7 +44,6 @@ jobs:
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Build recipe 🛠 - name: Build recipe 🛠
# We're pulling here to avoid accidentally using an image that might be present on aarch64 self-hosted runner
run: docker build --pull --rm --force-rm --tag my-custom-image -f ./${{ matrix.dockerfile }} ./ run: docker build --pull --rm --force-rm --tag my-custom-image -f ./${{ matrix.dockerfile }} ./
env: env:
DOCKER_BUILDKIT: 1 DOCKER_BUILDKIT: 1

View File

@@ -41,7 +41,7 @@ jobs:
steps: steps:
# Image with CUDA needs extra disk space # Image with CUDA needs extra disk space
- name: Free disk space 🧹 - name: Free disk space 🧹
if: contains(inputs.variant, 'cuda') && inputs.platform == 'x86_64' if: contains(inputs.variant, 'cuda') && runner.arch == 'X64'
uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be
with: with:
tool-cache: false tool-cache: false
@@ -57,18 +57,6 @@ jobs:
- name: Create dev environment 📦 - name: Create dev environment 📦
uses: ./.github/actions/create-dev-env uses: ./.github/actions/create-dev-env
# Self-hosted runners share a state (whole VM) between runs
# Also, they might have running or stopped containers,
# which are not cleaned up by `docker system prune`
- name: Reset docker state and cleanup artifacts 🗑️
if: inputs.platform != 'x86_64'
run: |
docker kill $(docker ps --quiet) || true
docker rm $(docker ps --all --quiet) || true
docker system prune --all --force
rm -rf /tmp/jupyter/
shell: bash
- name: Load parent built image to Docker 📥 - name: Load parent built image to Docker 📥
if: inputs.parent-image != '' if: inputs.parent-image != ''
uses: ./.github/actions/load-image uses: ./.github/actions/load-image

View File

@@ -41,7 +41,7 @@ jobs:
with: with:
name: ${{ inputs.image }}-aarch64-${{ inputs.variant }}-tags name: ${{ inputs.image }}-aarch64-${{ inputs.variant }}-tags
path: /tmp/jupyter/tags/ path: /tmp/jupyter/tags/
if: github.repository_owner == 'jupyter' && !contains(inputs.variant, 'cuda') if: ${{ !contains(inputs.variant, 'cuda') }}
# Docker might be stuck when pulling images # Docker might be stuck when pulling images
# https://github.com/docker/for-mac/issues/2083 # https://github.com/docker/for-mac/issues/2083

View File

@@ -33,7 +33,7 @@ jobs:
steps: steps:
# Image with CUDA needs extra disk space # Image with CUDA needs extra disk space
- name: Free disk space 🧹 - name: Free disk space 🧹
if: contains(inputs.variant, 'cuda') && inputs.platform == 'x86_64' if: contains(inputs.variant, 'cuda') && runner.arch == 'X64'
uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be
with: with:
tool-cache: false tool-cache: false

View File

@@ -66,8 +66,7 @@ jobs:
parent-image: "" parent-image: ""
image: docker-stacks-foundation image: docker-stacks-foundation
platform: aarch64 platform: aarch64
runs-on: ARM64_FAST runs-on: ubuntu-22.04-arm
if: github.repository_owner == 'jupyter'
x86_64-foundation: x86_64-foundation:
uses: ./.github/workflows/docker-build-test-upload.yml uses: ./.github/workflows/docker-build-test-upload.yml
@@ -83,9 +82,8 @@ jobs:
parent-image: docker-stacks-foundation parent-image: docker-stacks-foundation
image: base-notebook image: base-notebook
platform: aarch64 platform: aarch64
runs-on: ARM64_FAST runs-on: ubuntu-22.04-arm
needs: [aarch64-foundation] needs: [aarch64-foundation]
if: github.repository_owner == 'jupyter'
x86_64-base: x86_64-base:
uses: ./.github/workflows/docker-build-test-upload.yml uses: ./.github/workflows/docker-build-test-upload.yml
@@ -102,9 +100,9 @@ jobs:
parent-image: base-notebook parent-image: base-notebook
image: minimal-notebook image: minimal-notebook
platform: aarch64 platform: aarch64
runs-on: ARM64_FAST runs-on: ubuntu-22.04-arm
needs: [aarch64-base] needs: [aarch64-base]
if: github.repository_owner == 'jupyter' && !contains(github.event.pull_request.title, '[FAST_BUILD]') if: ${{ !contains(github.event.pull_request.title, '[FAST_BUILD]') }}
x86_64-minimal: x86_64-minimal:
uses: ./.github/workflows/docker-build-test-upload.yml uses: ./.github/workflows/docker-build-test-upload.yml
@@ -122,9 +120,9 @@ jobs:
parent-image: minimal-notebook parent-image: minimal-notebook
image: scipy-notebook image: scipy-notebook
platform: aarch64 platform: aarch64
runs-on: ARM64_FAST runs-on: ubuntu-22.04-arm
needs: [aarch64-minimal] needs: [aarch64-minimal]
if: github.repository_owner == 'jupyter' && !contains(github.event.pull_request.title, '[FAST_BUILD]') if: ${{ !contains(github.event.pull_request.title, '[FAST_BUILD]') }}
x86_64-scipy: x86_64-scipy:
uses: ./.github/workflows/docker-build-test-upload.yml uses: ./.github/workflows/docker-build-test-upload.yml
@@ -142,9 +140,9 @@ jobs:
parent-image: minimal-notebook parent-image: minimal-notebook
image: r-notebook image: r-notebook
platform: aarch64 platform: aarch64
runs-on: ARM64_SLOW runs-on: ubuntu-22.04-arm
needs: [aarch64-minimal] needs: [aarch64-minimal]
if: github.repository_owner == 'jupyter' && !contains(github.event.pull_request.title, '[FAST_BUILD]') if: ${{ !contains(github.event.pull_request.title, '[FAST_BUILD]') }}
x86_64-r: x86_64-r:
uses: ./.github/workflows/docker-build-test-upload.yml uses: ./.github/workflows/docker-build-test-upload.yml
@@ -162,9 +160,9 @@ jobs:
parent-image: minimal-notebook parent-image: minimal-notebook
image: julia-notebook image: julia-notebook
platform: aarch64 platform: aarch64
runs-on: ARM64_SLOW runs-on: ubuntu-22.04-arm
needs: [aarch64-minimal] needs: [aarch64-minimal]
if: github.repository_owner == 'jupyter' && !contains(github.event.pull_request.title, '[FAST_BUILD]') if: ${{ !contains(github.event.pull_request.title, '[FAST_BUILD]') }}
x86_64-julia: x86_64-julia:
uses: ./.github/workflows/docker-build-test-upload.yml uses: ./.github/workflows/docker-build-test-upload.yml
@@ -182,9 +180,9 @@ jobs:
parent-image: scipy-notebook parent-image: scipy-notebook
image: tensorflow-notebook image: tensorflow-notebook
platform: aarch64 platform: aarch64
runs-on: ARM64_SLOW runs-on: ubuntu-22.04-arm
needs: [aarch64-scipy] needs: [aarch64-scipy]
if: github.repository_owner == 'jupyter' && !contains(github.event.pull_request.title, '[FAST_BUILD]') if: ${{ !contains(github.event.pull_request.title, '[FAST_BUILD]') }}
x86_64-tensorflow: x86_64-tensorflow:
uses: ./.github/workflows/docker-build-test-upload.yml uses: ./.github/workflows/docker-build-test-upload.yml
@@ -213,9 +211,9 @@ jobs:
parent-image: scipy-notebook parent-image: scipy-notebook
image: pytorch-notebook image: pytorch-notebook
platform: aarch64 platform: aarch64
runs-on: ARM64_SLOW runs-on: ubuntu-22.04-arm
needs: [aarch64-scipy] needs: [aarch64-scipy]
if: github.repository_owner == 'jupyter' && !contains(github.event.pull_request.title, '[FAST_BUILD]') if: ${{ !contains(github.event.pull_request.title, '[FAST_BUILD]') }}
x86_64-pytorch: x86_64-pytorch:
uses: ./.github/workflows/docker-build-test-upload.yml uses: ./.github/workflows/docker-build-test-upload.yml
@@ -255,9 +253,9 @@ jobs:
parent-image: scipy-notebook parent-image: scipy-notebook
image: datascience-notebook image: datascience-notebook
platform: aarch64 platform: aarch64
runs-on: ARM64_SLOW runs-on: ubuntu-22.04-arm
needs: [aarch64-scipy] needs: [aarch64-scipy]
if: github.repository_owner == 'jupyter' && !contains(github.event.pull_request.title, '[FAST_BUILD]') if: ${{ !contains(github.event.pull_request.title, '[FAST_BUILD]') }}
x86_64-datascience: x86_64-datascience:
uses: ./.github/workflows/docker-build-test-upload.yml uses: ./.github/workflows/docker-build-test-upload.yml
@@ -275,9 +273,9 @@ jobs:
parent-image: scipy-notebook parent-image: scipy-notebook
image: pyspark-notebook image: pyspark-notebook
platform: aarch64 platform: aarch64
runs-on: ARM64_FAST runs-on: ubuntu-22.04-arm
needs: [aarch64-scipy] needs: [aarch64-scipy]
if: github.repository_owner == 'jupyter' && !contains(github.event.pull_request.title, '[FAST_BUILD]') if: ${{ !contains(github.event.pull_request.title, '[FAST_BUILD]') }}
x86_64-pyspark: x86_64-pyspark:
uses: ./.github/workflows/docker-build-test-upload.yml uses: ./.github/workflows/docker-build-test-upload.yml
@@ -295,9 +293,9 @@ jobs:
parent-image: pyspark-notebook parent-image: pyspark-notebook
image: all-spark-notebook image: all-spark-notebook
platform: aarch64 platform: aarch64
runs-on: ARM64_FAST runs-on: ubuntu-22.04-arm
needs: [aarch64-pyspark] needs: [aarch64-pyspark]
if: github.repository_owner == 'jupyter' && !contains(github.event.pull_request.title, '[FAST_BUILD]') if: ${{ !contains(github.event.pull_request.title, '[FAST_BUILD]') }}
x86_64-all-spark: x86_64-all-spark:
uses: ./.github/workflows/docker-build-test-upload.yml uses: ./.github/workflows/docker-build-test-upload.yml
@@ -348,7 +346,7 @@ jobs:
aarch64-pyspark, aarch64-pyspark,
aarch64-all-spark, aarch64-all-spark,
] ]
if: github.repository_owner == 'jupyter' && !contains(github.event.pull_request.title, '[FAST_BUILD]') if: ${{ !contains(github.event.pull_request.title, '[FAST_BUILD]') }}
aarch64-images-tag-push-fast: aarch64-images-tag-push-fast:
uses: ./.github/workflows/docker-tag-push.yml uses: ./.github/workflows/docker-tag-push.yml
@@ -367,7 +365,7 @@ jobs:
{ image: base-notebook, variant: default }, { image: base-notebook, variant: default },
] ]
needs: [aarch64-foundation, aarch64-base] needs: [aarch64-foundation, aarch64-base]
if: github.repository_owner == 'jupyter' && contains(github.event.pull_request.title, '[FAST_BUILD]') if: contains(github.event.pull_request.title, '[FAST_BUILD]')
x86_64-images-tag-push: x86_64-images-tag-push:
uses: ./.github/workflows/docker-tag-push.yml uses: ./.github/workflows/docker-tag-push.yml
@@ -505,4 +503,4 @@ jobs:
contributed-recipes: contributed-recipes:
uses: ./.github/workflows/contributed-recipes.yml uses: ./.github/workflows/contributed-recipes.yml
needs: [merge-tags] needs: [merge-tags]
if: github.repository_owner == 'jupyter' && (github.ref == 'refs/heads/main' || github.event_name == 'schedule') if: github.ref == 'refs/heads/main' || github.event_name == 'schedule'

View File

@@ -3,6 +3,12 @@
This changelog only contains breaking and/or significant changes manually introduced to this repository (using Pull Requests). This changelog only contains breaking and/or significant changes manually introduced to this repository (using Pull Requests).
All image manifests can be found in [the wiki](https://github.com/jupyter/docker-stacks/wiki). All image manifests can be found in [the wiki](https://github.com/jupyter/docker-stacks/wiki).
## 2025-02-11
Affected: all images.
- **Non-breaking:**: start using GitHub-hosted `aarch64` runners.
## 2024-12-03 ## 2024-12-03
Affected: all images. Affected: all images.

View File

@@ -93,6 +93,7 @@ more information is available in the [documentation](https://jupyter-docker-stac
- Starting from `2022-07-05`, `aarch64` self-hosted runners were sponsored by [`@mathbunnyru`](https://github.com/mathbunnyru/). - Starting from `2022-07-05`, `aarch64` self-hosted runners were sponsored by [`@mathbunnyru`](https://github.com/mathbunnyru/).
Please, consider [sponsoring his work](https://github.com/sponsors/mathbunnyru) on GitHub Please, consider [sponsoring his work](https://github.com/sponsors/mathbunnyru) on GitHub
- Starting from `2023-10-31`, `aarch64` self-hosted runners are sponsored by an amazing [`2i2c non-profit organization`](https://2i2c.org) - Starting from `2023-10-31`, `aarch64` self-hosted runners are sponsored by an amazing [`2i2c non-profit organization`](https://2i2c.org)
- Starting from `2025-02-11`, we use GitHub-hosted `aarch64` runners
## CPU Architectures ## CPU Architectures

View File

@@ -63,7 +63,6 @@ myst_heading_anchors = 3
linkcheck_ignore = [ linkcheck_ignore = [
r".*github\.com.*#", # javascript based anchors r".*github\.com.*#", # javascript based anchors
r"https://github\.com/jupyter/docker-stacks/settings/actions/runners/new\?arch=arm64\&amp;os=linux", # only works for users with permissions to change runners
r"http://127\.0\.0\.1:.*", # various examples r"http://127\.0\.0\.1:.*", # various examples
r"https://mybinder\.org/v2/gh/.*", # lots of 500 errors r"https://mybinder\.org/v2/gh/.*", # lots of 500 errors
r"https://packages\.ubuntu\.com/search\?keywords=openjdk", # frequent read timeouts r"https://packages\.ubuntu\.com/search\?keywords=openjdk", # frequent read timeouts

View File

@@ -36,7 +36,6 @@ Table of Contents
maintaining/new-images-and-packages-policy maintaining/new-images-and-packages-policy
maintaining/tasks maintaining/tasks
maintaining/aarch64-runner
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 2

View File

@@ -1,30 +0,0 @@
# Self-hosted runners
For building `aarch64` images, we use self-hosted GitHub runners.
It is recommended to have at least two runners to allow better parallelism.
Each runner is recommended to have at least _2 cores_ and _30 GB_ of disk space.
Add a new runner:
- To use [Oracle OCI](https://www.oracle.com/cloud/), create a compute instance `VM.Standard.A1.Flex`.
- To use [Google Cloud](https://cloud.google.com), use [this instruction](https://cloud.google.com/compute/docs/instances/create-start-instance).
Configure your runner:
1. Run under `root`:
```bash
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/jupyter/docker-stacks/HEAD/aarch64-runner/setup.sh)"
```
This will perform the initial runner setup and create a user `runner-user` without `sudo` capabilities.
2. Set up a new GitHub Runner under `runner-user` using [GitHub Instructions](https://github.com/jupyter/docker-stacks/settings/actions/runners/new?arch=arm64&os=linux).
**Do not `./run.sh` yet**.
3. Run under `root`:
```bash
cd /home/runner-user/actions-runner/ && ./svc.sh install runner-user
```
4. Reboot the VM to apply all updates and run GitHub runner.

View File

@@ -12,13 +12,13 @@ REPOSITORY_OWNER = os.environ["REPOSITORY_OWNER"]
def generate_matrix() -> dict[str, Any]: def generate_matrix() -> dict[str, Any]:
dockerfiles = sorted(file.name for file in THIS_DIR.glob("*.dockerfile")) dockerfiles = sorted(file.name for file in THIS_DIR.glob("*.dockerfile"))
runs_on = ["ubuntu-latest"] runs_on = ["ubuntu-latest", "ubuntu-22.04-arm"]
if REPOSITORY_OWNER == "jupyter":
runs_on.append("ARM64")
return { return {
"dockerfile": dockerfiles, "dockerfile": dockerfiles,
"runs-on": runs_on, "runs-on": runs_on,
"exclude": [{"dockerfile": "oracledb.dockerfile", "runs-on": "ARM64"}], "exclude": [
{"dockerfile": "oracledb.dockerfile", "runs-on": "ubuntu-22.04-arm"}
],
} }

View File

@@ -43,12 +43,6 @@ def get_latest_julia_url() -> tuple[str, str]:
triplet = unify_aarch64(platform.machine()) + "-linux-gnu" triplet = unify_aarch64(platform.machine()) + "-linux-gnu"
file_info = [vf for vf in latest_version_files if vf["triplet"] == triplet][0] file_info = [vf for vf in latest_version_files if vf["triplet"] == triplet][0]
LOGGER.info(f"Latest version: {file_info['version']} url: {file_info['url']}") LOGGER.info(f"Latest version: {file_info['version']} url: {file_info['url']}")
BROKEN_VERSION = "1.11.3"
if file_info["version"] == BROKEN_VERSION:
LOGGER.warning(
f"Not using Julia {BROKEN_VERSION}, because it hangs in GitHub self-hosted runners"
)
return file_info["url"].replace(BROKEN_VERSION, "1.11.1"), "1.11.1"
return file_info["url"], file_info["version"] return file_info["url"], file_info["version"]