Block-level snapshots
Save and restore entire folders with block-level snapshots. Helps to speed-up docker builds in your GitHub Actions workflows.
Since v2.8.3, RunsOn supports block-level snapshots. This is a new feature that allows you to save and restore entire folders with block-level snapshots. This is particularly useful for speeding up docker builds in your GitHub Actions workflows.
Usage
Flex
Use runs-on/snapshot@v1 on a Flex runner to restore a path at the start of the job and save it again at the end:
jobs: docker: runs-on: runs-on=${{ github.run_id }}/runner=2cpu-linux-x64 steps: - uses: actions/checkout@v6 - uses: runs-on/snapshot@v1 with: path: /var/lib/docker - uses: docker/setup-buildx-action@v3 with: name: runs-on keep-state: true - uses: docker/build-push-action@v4 with: context: .Fleet
Block-level snapshots are not exposed by the Fleet module yet. Use Flex for runs-on/snapshot workflows; see Fleet current limitations.
How it works
The snapshotting feature is performed by a dedicated action: runs-on/snapshot@v1 ↗. This action is used to create a snapshot of an entire folder at the end of a job, and restore it at the beginning of the next.
name: Docker build with snapshotsjobs: long-docker-build: runs-on: runs-on=${{ github.run_id }}/runner=2cpu-linux-x64 steps: - uses: actions/checkout@v6
- uses: runs-on/snapshot@v1 with: path: /var/lib/docker
- uses: docker/setup-buildx-action@v3 with: name: runs-on keep-state: true
- uses: docker/build-push-action@v4 with: context: .Action inputs
| Input | Description | Required | Default |
|---|---|---|---|
| path | Path to the directory to snapshot. Must be an absolute path. | Yes | - |
| version | Version of the snapshot to use. Can be bumped to force a new initial snapshot | No | v1 |
| volume_type | Type of volume to use for the snapshot | No | gp3 |
| volume_iops | IOPS to use for the volume | No | 3000 |
| volume_throughput | Throughput to use for the volume | No | 750 |
| volume_size | Size (in GiB) of the volume to use for the snapshot | No | 40 |
| volume_initialization_rate | Initialization rate to use for the volume. Useful for very large volumes. 100 MB/s - 200 MB/s: $0.00240/GB, 201 MB/s - 300 MB/s $0.00360/GB | No | 0 |
| wait_for_completion | Wait for snapshot completion before exiting. Note that the first snapshot will always be waited for | No | false |
Snapshot selection
When restoring a snapshot, the most recent snapshot for the current branch is fetched. If none is found, the most recent snapshot for the repository default branch will be taken. If none found, a new empty volume is used instead.
Snapshot cleanup
Volume and snapshot cleanup is performed by the RunsOn service that lives in your AWS account.
Only the latest snapshot from a branch is kept. After a snapshot is taken, the source volume is tagged for deletion ~10 minutes later; freshly created volumes that are never snapshotted are reclaimed after 20 minutes. Volume deletion is performed by the RunsOn service housekeeping loop, so actual removal may lag slightly behind the TTL.
Snapshots older than 10 days are always removed (in case the branch no longer see any activity).
Additional notes
- On the first run, there will be an additional delay because the action will forcibly wait for the completion of the first snapshot, which takes the most time (further snapshots are incremental). This is technically not required, but will be less confusing if a second job comes up right after and you start from an empty volume again, because the first snapshot is still being created.
- Snapshot and restore speed is highly dependent on the volume type, iops, throughput, and used size. Feel free to experiment with those. Default values are a balance between good speed, and very low price.
- The snapshot is only saved if the job succeeds (the action’s post step uses
post-if: success()). A failed or cancelled job will not update the snapshot, avoiding persisting corrupted state.