Skip to content
/ gh-rmrf Public

Runner Maintenance: Reclaim Filesystem - reclaim disk space on GitHub runners.

Notifications You must be signed in to change notification settings

fenio/gh-rmrf

Use this GitHub action with your project
Add this Action to an existing workflow or create a new one
View on Marketplace

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

47 Commits
 
 
 
 
 
 

Repository files navigation

gh-rmrf

GitHub - Runner Maintenance: Reclaim Filesystem - reclaim disk space on GitHub runners.

GitHub-hosted runners come with a lot of pre-installed software you probably don't need. This action removes the bloat and optionally merges multiple disks into a single large volume.

Features

  • Fast deletion using rmz (parallel, Rust-based rm)
  • Configurable cleanup - choose what to remove
  • Disk merging - combine root and /mnt into a single LVM volume (~100GB)
  • Custom mount path - mount merged volume at $GITHUB_WORKSPACE or /var/lib/docker/ for Docker builds
  • Btrfs support - optional zstd compression for even more space

Usage

Basic (cleanup only)

- uses: fenio/gh-rmrf@v1

This removes ~20GB of bloat (Android SDK, .NET, Haskell, Boost, Swift, CodeQL).

With disk merging

Important: When using merge-disks: true, the action mounts a fresh filesystem at $GITHUB_WORKSPACE. This means it must run before actions/checkout, so the code gets checked out onto the merged volume.

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      # gh-rmrf must run FIRST when using merge-disks
      - uses: fenio/gh-rmrf@v1
        with:
          merge-disks: 'true'
      
      # Now checkout into the merged workspace
      - uses: actions/checkout@v6
      
      # Your build steps...

Creates a ~100GB unified workspace by combining freed space with the /mnt disk.

With Btrfs compression

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      # gh-rmrf must run FIRST when using merge-disks
      - uses: fenio/gh-rmrf@v1
        with:
          merge-disks: 'true'
          use-btrfs: 'true'
      
      # Now checkout into the merged workspace
      - uses: actions/checkout@v6

Uses Btrfs with zstd compression for the merged volume.

For Docker builds

When building large Docker images that exceed the default disk space, you can mount the merged volume directly at Docker's data directory. This requires backing up and restoring Docker data around the merge operation.

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      # 1. Backup Docker data BEFORE merge
      - name: Backup Docker data
        run: |
          sudo mkdir -p /tmp/docker-backup
          sudo rsync -aPq /var/lib/docker/ /tmp/docker-backup/

      # 2. Run gh-rmrf with custom mount path
      - uses: fenio/gh-rmrf@v1
        with:
          merge-disks: 'true'
          mount-path: '/var/lib/docker/'

      # 3. Restore Docker data AFTER merge
      - name: Restore Docker data
        run: |
          sudo rsync -aPq /tmp/docker-backup/ /var/lib/docker/
          sudo rm -rf /tmp/docker-backup

      # 4. Now checkout and build
      - uses: actions/checkout@v4

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: your-image:latest

This gives Docker access to the full ~100GB merged volume for building large images.

Custom configuration

- uses: fenio/gh-rmrf@v1
  with:
    remove-android: 'true'          # ~12GB
    remove-dotnet: 'true'           # ~2GB
    remove-haskell: 'true'          # ~2GB
    remove-boost: 'true'            # ~1GB
    remove-swift: 'true'            # ~1.5GB
    remove-codeql: 'true'           # ~1GB
    remove-hostedtoolcache: 'false' # ~8GB - Go, Node.js, Python, Ruby, etc.
    remove-docker-images: 'false'   # ~4GB
    nuke: 'false'                   # Experimental: nuke browsers, databases, cloud CLIs
    merge-disks: 'false'
    use-btrfs: 'false'

Inputs

Input Description Default
remove-android Remove Android SDK (~12GB) true
remove-dotnet Remove .NET SDK (~2GB) true
remove-haskell Remove GHC/Haskell (~2GB) true
remove-boost Remove Boost (~1GB) true
remove-swift Remove Swift (~1.5GB) true
remove-codeql Remove CodeQL (~1GB) true
remove-hostedtoolcache Remove cached tool versions - Go, Node.js, Python, Ruby, etc. (~8GB) false
remove-docker-images Remove Docker images (~4GB) false
nuke Experimental: Remove browsers, databases, cloud CLIs, build tools false
merge-disks Merge root and /mnt into single LVM volume false
mount-path Path where merged volume will be mounted (defaults to $GITHUB_WORKSPACE) ''
use-btrfs Use Btrfs with zstd compression (requires merge-disks) false

How it works

Cleanup mode (default)

  1. Reports initial disk usage
  2. Downloads rmz for fast parallel deletion
  3. Removes selected bloat directories
  4. Reports final disk usage

Merge mode

Note: The disk merging feature is somewhat hackish - it relies on undocumented details of GitHub runner disk layout that could change without notice. It works today, but use at your own risk.

  1. Removes bloat (as above)
  2. Disables swap and unmounts /mnt
  3. Creates a loopback file from freed space on root (~80% of available)
  4. Creates LVM volume group combining the former /mnt disk and loopback
  5. Formats as ext4 or Btrfs (with zstd compression)
  6. Mounts at $GITHUB_WORKSPACE (default) or custom mount-path

Space gains

Mode Before After Free space
Cleanup only 55GB used, 18GB free 35GB used, 38GB free ~38GB on root
Cleanup + nuke 55GB used, 18GB free 14GB used, 58GB free ~58GB on root
Merge (ext4) - - ~100GB unified
Merge (Btrfs+zstd) - - ~100GB+ unified
Maximum (all + nuke + merge) 55GB used, 18GB free 25GB used, 47GB free ~113GB unified

Bloat locations on GitHub runners

Path Size Removed by
/usr/local/lib/android ~12GB remove-android
/opt/hostedtoolcache ~8GB remove-hostedtoolcache
/usr/share/dotnet ~2GB remove-dotnet
/opt/ghc ~2GB remove-haskell
/usr/local/.ghcup ~1GB remove-haskell
/usr/local/share/boost ~1GB remove-boost
/usr/share/swift ~1.5GB remove-swift
/opt/hostedtoolcache/CodeQL ~1GB remove-codeql
Docker images ~4GB remove-docker-images

Nuke option

The nuke option aggressively removes additional bloat, freeing ~40GB total when combined with default cleanup:

Category Paths Size
Browsers Chrome, Firefox, Edge, Chromium ~1.5GB
Cloud CLIs Azure, GCloud, AWS CLI, AWS SAM ~2GB
Databases PostgreSQL, MySQL ~0.5GB
Languages Julia, Miniconda, Rust toolchains ~2.5GB
Build tools Gradle, Kotlin, Maven, LLVM versions ~2GB
Other PowerShell, Linuxbrew, Java VMs, Minikube, Runner cache ~2.5GB

Warning: The nuke option removes tools you might need. Java VMs, LLVM, and build tools are removed. Only use this if you're sure your workflow doesn't depend on these.

License

MIT

About

Runner Maintenance: Reclaim Filesystem - reclaim disk space on GitHub runners.

Topics

Resources

Stars

Watchers

Forks

Packages

No packages published