Repository: lima-vm/lima

Issue:
Simplify syntax for selecting images, with locations and digests
### Description

Make the usage of Lima more similar to a `Vagrantfile` or a `Dockerfile`.

1)
```ruby
Vagrant.configure("2") do |config|
  config.vm.box = "cloud-image/ubuntu-24.04"
end
```
https://app.vagrantup.com/cloud-image

2)
```Dockerfile
FROM ubuntu:24.04
# or, with a fully qualified registry
FROM docker.io/library/ubuntu:24.04
```
https://hub.docker.com/_/ubuntu

This by separating the usage of the images with the definition of the images.

templates/[ubuntu.yaml](https://github.com/lima-vm/lima/blob/master/examples/ubuntu.yaml)

```yaml
images:
- ubuntu-24.04
```

images/ubuntu-24.04.yaml
```yaml
images:
# Try to use release-yyyyMMdd image if available. Note that release-yyyyMMdd will be removed after several months.
- location: "https://cloud-images.ubuntu.com/releases/24.04/release-20240423/ubuntu-24.04-server-cloudimg-amd64.img"
  arch: "x86_64"
  digest: "sha256:32a9d30d18803da72f5936cf2b7b9efcb4d0bb63c67933f17e3bdfd1751de3f3"
- location: "https://cloud-images.ubuntu.com/releases/24.04/release-20240423/ubuntu-24.04-server-cloudimg-arm64.img"
  arch: "aarch64"
  digest: "sha256:c841bac00925d3e6892d979798103a867931f255f28fefd9d5e07e3e22d0ef22"
# Fallback to the latest release image.
# Hint: run `limactl prune` to invalidate the cache
- location: "https://cloud-images.ubuntu.com/releases/24.04/release/ubuntu-24.04-server-cloudimg-amd64.img"
  arch: "x86_64"
- location: "https://cloud-images.ubuntu.com/releases/24.04/release/ubuntu-24.04-server-cloudimg-arm64.img"
  arch: "aarch64"
```

The image can be shared with multiple templates, reducing the need for copy/paste of details.

Discussion:
@afbjorklund: The new `limactl validate --fill` will show a preview of the actual values.@afbjorklund: Alternatively one could use something longer like `image://ubuntu-24.04` @afbjorklund: Added `default` for the default image, for when you don't care about the OS@afbjorklund: Also good when adding more optional fields to images - like `size` and `cid`*

\* see https://docs.ipfs.tech/concepts/content-addressing/ for CID information

Example entry:

```yaml
- location: "https://cloud-images.ubuntu.com/releases/24.04/release-20240423/ubuntu-24.04-server-cloudimg-amd64.img"
  size: 475004928
  arch: "x86_64"
  digest: "sha256:32a9d30d18803da72f5936cf2b7b9efcb4d0bb63c67933f17e3bdfd1751de3f3"
  cid: "bafybeig5sch22ecfox7gq724rz7uivydwvnnpuqdcnjz72iwelgtrakzui"
```

* #1586
* #2407@afbjorklund: More architectures now in the default template, making "images" twice as long...@jandubois: This is now possible with the `base` feature:

```
base: template://images/ubuntu-24.04
```

This is something we could implement right away with Lima 1.1.0, if we wanted to.

I've also written a little bit about how we could eventually have a single template per distro, and select the release via a `--param` setting in https://github.com/lima-vm/lima/discussions/2520#discussioncomment-10193298.

But that is still some way off and will need further discussion and refinement before we can figure out if that is a good idea or not.

Solution patch:
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index f4758eff..971bfc1d 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -196,7 +196,8 @@ jobs:
     - name: Validate jsonschema
       run: make schema-limayaml.json
     - name: Validate templates
-      run: find -L templates -name '*.yaml' | xargs limactl validate
+      # Can't validate base templates in `_default` because they have no images
+      run: find -L templates -name '*.yaml' ! -path '*/_default/*' | xargs limactl validate
     - name: Install test dependencies
       # QEMU:      required by Lima itself
       # bash:      required by test-templates.sh (OS version of bash is too old)
@@ -208,7 +209,7 @@ jobs:
       run: echo "LIMACTL_CREATE_ARGS=${LIMACTL_CREATE_ARGS} --vm-type=qemu" >>$GITHUB_ENV
     - name: "Inject `no_timer_check` to kernel cmdline"
       # workaround to https://github.com/lima-vm/lima/issues/84
-      run: ./hack/inject-cmdline-to-template.sh templates/default.yaml no_timer_check
+      run: ./hack/inject-cmdline-to-template.sh templates/_images/ubuntu.yaml no_timer_check
     - name: Cache image used by default.yaml
       uses: ./.github/actions/setup_cache_for_template
       with:
@@ -353,7 +354,7 @@ jobs:
     steps:
     - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683  # v4.2.2
       with:
-        fetch-depth: 1
+        fetch-depth: 0
     - uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b  # v5.4.0
       with:
         go-version: 1.24.x
@@ -365,7 +366,7 @@ jobs:
       run: echo "LIMACTL_CREATE_ARGS=${LIMACTL_CREATE_ARGS} --vm-type=qemu --network=lima:shared" >>$GITHUB_ENV
     - name: "Inject `no_timer_check` to kernel cmdline"
       # workaround to https://github.com/lima-vm/lima/issues/84
-      run: ./hack/inject-cmdline-to-template.sh templates/default.yaml no_timer_check
+      run: ./hack/inject-cmdline-to-template.sh templates/_images/ubuntu.yaml no_timer_check
     - name: Cache image used by default .yaml
       uses: ./.github/actions/setup_cache_for_template
       with:
@@ -408,6 +409,7 @@ jobs:
     steps:
     - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683  # v4.2.2
       with:
+        # To avoid "failed to load YAML file \"templates/experimental/riscv64.yaml\": can't parse builtin Lima version \"3f3a6f6\": 3f3a6f6 is not in dotted-tri format"
         fetch-depth: 0
     - name: Fetch homebrew-core commit messages
       uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683  # v4.2.2
@@ -452,7 +454,7 @@ jobs:
     steps:
     - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683  # v4.2.2
       with:
-        fetch-depth: 1
+        fetch-depth: 0
     - uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b  # v5.4.0
       with:
         go-version: 1.24.x
@@ -487,7 +489,7 @@ jobs:
     steps:
     - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683  # v4.2.2
       with:
-        fetch-depth: 1
+        fetch-depth: 0
     - uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b  # v5.4.0
       with:
         go-version: 1.24.x
diff --git a/.gitignore b/.gitignore
index 086c11c8..9afbe9fa 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
 _output/
 _artifacts/
 lima.REJECTED.yaml
+default-template.yaml
 schema-limayaml.json
 .config
diff --git a/.ls-lint.yml b/.ls-lint.yml
index 6f9a0898..972dbf2b 100644
--- a/.ls-lint.yml
+++ b/.ls-lint.yml
@@ -19,6 +19,10 @@ ls:
   docs:
     .md: kebab-case
 
+  templates:
+    # _default and _images have leading underscores
+    .dir: lowercase
+
   website/content:
     .dir: lowercase
 
diff --git a/Makefile b/Makefile
index 3f46ed93..9ddaa84d 100644
--- a/Makefile
+++ b/Makefile
@@ -419,14 +419,19 @@ ifeq ($(native_compiling),true)
 endif
 
 ################################################################################
-schema-limayaml.json: _output/bin/limactl$(exe)
+default-template.yaml: _output/bin/limactl$(exe)
 ifeq ($(native_compiling),true)
-	$< generate-jsonschema --schemafile $@ templates/default.yaml
+	$< tmpl copy --embed-all templates/default.yaml $@
+endif
+
+schema-limayaml.json: _output/bin/limactl$(exe) default-template.yaml
+ifeq ($(native_compiling),true)
+	$< generate-jsonschema --schemafile $@ default-template.yaml
 endif
 
 .PHONY: check-jsonschema
-check-jsonschema: schema-limayaml.json
-	check-jsonschema --schemafile $< templates/default.yaml
+check-jsonschema: schema-limayaml.json default-template.yaml
+	check-jsonschema --schemafile schema-limayaml.json default-template.yaml
 
 ################################################################################
 .PHONY: diagrams
diff --git a/cmd/limactl/start.go b/cmd/limactl/start.go
index d567f195..8fbeb7c5 100644
--- a/cmd/limactl/start.go
+++ b/cmd/limactl/start.go
@@ -374,7 +374,10 @@ func createStartActionCommon(cmd *cobra.Command, _ []string) (exit bool, err err
 		if templates, err := templatestore.Templates(); err == nil {
 			w := cmd.OutOrStdout()
 			for _, f := range templates {
-				_, _ = fmt.Fprintln(w, f.Name)
+				// Don't show internal base templates like `_default/*` and `_images/*`.
+				if !strings.HasPrefix(f.Name, "_") {
+					_, _ = fmt.Fprintln(w, f.Name)
+				}
 			}
 			return true, nil
 		}
diff --git a/hack/common.inc.sh b/hack/common.inc.sh
index 95e429fc..8e6f94fe 100644
--- a/hack/common.inc.sh
+++ b/hack/common.inc.sh
@@ -29,3 +29,9 @@ _IPERF3=iperf3
 # https://github.com/lima-vm/socket_vmnet/issues/85
 [ "$(uname -s)" = "Darwin" ] && _IPERF3="iperf3-darwin"
 : "${IPERF3:=$_IPERF3}"
+
+# Setup LIMA_TEMPLATES_PATH because the templates are not installed, but reference base templates
+# via template://_images/* and template://_default/*.
+templates_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/../templates" && pwd)"
+: "${LIMA_TEMPLATES_PATH:-$templates_dir}"
+export LIMA_TEMPLATES_PATH
diff --git a/hack/test-templates.sh b/hack/test-templates.sh
index bb502ca6..cd228a26 100755
--- a/hack/test-templates.sh
+++ b/hack/test-templates.sh
@@ -22,8 +22,8 @@ FILE="$(cd "$(dirname "$1")" && pwd)/$(basename "$1")"
 NAME="$(basename -s .yaml "$FILE")"
 OS_HOST="$(uname -o)"
 
-# On Windows $HOME of the bash runner, %USERPROFILE% of the host machine and mpunting point in the guest machine
-# are all different folders. This will handle path differences, when values are expilictly set.
+# On Windows $HOME of the bash runner, %USERPROFILE% of the host machine and mounting point in the guest machine
+# are all different folders. This will handle path differences, when values are explicitly set.
 HOME_HOST=${HOME_HOST:-$HOME}
 HOME_GUEST=${HOME_GUEST:-$HOME}
 FILE_HOST=$FILE
diff --git a/templates/_default/mounts.yaml b/templates/_default/mounts.yaml
new file mode 100644
index 00000000..a695c293
--- /dev/null
+++ b/templates/_default/mounts.yaml
@@ -0,0 +1,4 @@
+mounts:
+- location: "~"
+- location: "/tmp/lima"
+  writable: true
diff --git a/templates/_images/almalinux-8.yaml b/templates/_images/almalinux-8.yaml
new file mode 100644
index 00000000..31f5f476
--- /dev/null
+++ b/templates/_images/almalinux-8.yaml
@@ -0,0 +1,33 @@
+# NOTE: EL8-based distros are known not to work on M1 chips: https://github.com/lima-vm/lima/issues/841
+# EL9-based distros are known to work.
+images:
+- location: https://repo.almalinux.org/almalinux/8.10/cloud/x86_64/images/AlmaLinux-8-GenericCloud-8.10-20240819.x86_64.qcow2
+  arch: x86_64
+  digest: sha256:669bd580dcef5491d4dfd5724d252cce7cde1b2b33a3ca951e688d71386875e3
+
+- location: https://repo.almalinux.org/almalinux/8.10/cloud/aarch64/images/AlmaLinux-8-GenericCloud-8.10-20240819.aarch64.qcow2
+  arch: aarch64
+  digest: sha256:cec6736cbc562d06895e218b6f022621343c553bfa79192ca491381b4636c7b8
+
+- location: https://repo.almalinux.org/almalinux/8.10/cloud/s390x/images/AlmaLinux-8-GenericCloud-8.10-20240819.s390x.qcow2
+  arch: s390x
+  digest: sha256:7f8866a4247ad57c81f5d2c5a0fa64940691f9df1e858a1510d34a0de008eb16
+
+# Fallback to the latest release image.
+# Hint: run `limactl prune` to invalidate the cache
+
+- location: https://repo.almalinux.org/almalinux/8/cloud/x86_64/images/AlmaLinux-8-GenericCloud-latest.x86_64.qcow2
+  arch: x86_64
+
+- location: https://repo.almalinux.org/almalinux/8/cloud/aarch64/images/AlmaLinux-8-GenericCloud-latest.aarch64.qcow2
+  arch: aarch64
+
+- location: https://repo.almalinux.org/almalinux/8/cloud/s390x/images/AlmaLinux-8-GenericCloud-latest.s390x.qcow2
+  arch: s390x
+
+mountTypesUnsupported: [9p]
+
+cpuType:
+  # Workaround for "vmx_write_mem: mmu_gva_to_gpa XXXXXXXXXXXXXXXX failed" on Intel Mac
+  # https://bugs.launchpad.net/qemu/+bug/1838390
+  x86_64: Haswell-v4
diff --git a/templates/_images/almalinux-9.yaml b/templates/_images/almalinux-9.yaml
new file mode 100644
index 00000000..b13fa427
--- /dev/null
+++ b/templates/_images/almalinux-9.yaml
@@ -0,0 +1,26 @@
+images:
+- location: https://repo.almalinux.org/almalinux/9.5/cloud/x86_64/images/AlmaLinux-9-GenericCloud-9.5-20241120.x86_64.qcow2
+  arch: x86_64
+  digest: sha256:abddf01589d46c841f718cec239392924a03b34c4fe84929af5d543c50e37e37
+
+- location: https://repo.almalinux.org/almalinux/9.5/cloud/aarch64/images/AlmaLinux-9-GenericCloud-9.5-20241120.aarch64.qcow2
+  arch: aarch64
+  digest: sha256:5ede4affaad0a997a2b642f1628b6268bd8eba775f281346b75be3ed20ec369e
+
+- location: https://repo.almalinux.org/almalinux/9.5/cloud/s390x/images/AlmaLinux-9-GenericCloud-9.5-20241120.s390x.qcow2
+  arch: s390x
+  digest: sha256:9948ea1c5ee1c6497bde5cec18c71c5f9e50861af4c0f1400c1af504eee2b995
+
+# Fallback to the latest release image.
+# Hint: run `limactl prune` to invalidate the cache
+
+- location: https://repo.almalinux.org/almalinux/9/cloud/x86_64/images/AlmaLinux-9-GenericCloud-latest.x86_64.qcow2
+  arch: x86_64
+
+- location: https://repo.almalinux.org/almalinux/9/cloud/aarch64/images/AlmaLinux-9-GenericCloud-latest.aarch64.qcow2
+  arch: aarch64
+
+- location: https://repo.almalinux.org/almalinux/9/cloud/s390x/images/AlmaLinux-9-GenericCloud-latest.s390x.qcow2
+  arch: s390x
+
+mountTypesUnsupported: [9p]
diff --git a/templates/_images/alpine-iso.yaml b/templates/_images/alpine-iso.yaml
new file mode 100644
index 00000000..dd79496a
--- /dev/null
+++ b/templates/_images/alpine-iso.yaml
@@ -0,0 +1,9 @@
+# Using the Alpine 3.20 aarch64 image with vmType=vz requires macOS Ventura 13.3 or later.
+images:
+- location: https://github.com/lima-vm/alpine-lima/releases/download/v0.2.41/alpine-lima-std-3.20.3-x86_64.iso
+  arch: x86_64
+  digest: sha512:949a353c1676bb406561d22c1b7f9db72fb0cc899c6c50166df3b38e392280a7e7b83f58643a309816d51a48317507c46c3e7e24e52fbc9f20fe817039306db1
+
+- location: https://github.com/lima-vm/alpine-lima/releases/download/v0.2.41/alpine-lima-std-3.20.3-aarch64.iso
+  arch: aarch64
+  digest: sha512:91ea119fea2bb638519792de2047303b26eaebcdace8df57b76373dc7b1cddcad77aaa9fed2d438fb02351b261783af3264d6bb2716519f8ba211a4b25d6f114
diff --git a/templates/_images/alpine.yaml b/templates/_images/alpine.yaml
new file mode 100644
index 00000000..4c140333
--- /dev/null
+++ b/templates/_images/alpine.yaml
@@ -0,0 +1,8 @@
+images:
+- location: https://dl-cdn.alpinelinux.org/alpine/v3.21/releases/cloud/nocloud_alpine-3.21.2-x86_64-uefi-cloudinit-r0.qcow2
+  arch: x86_64
+  digest: sha512:1aaf22b4a584e69e228e6aa38a295159c0143d9ccebe7ad4928e92b414714066af3bfe5f9e0ca4d4d64a70ca9fea09033af90258a6f2344130d70b660151127a
+
+- location: https://dl-cdn.alpinelinux.org/alpine/v3.21/releases/cloud/nocloud_alpine-3.21.2-aarch64-uefi-cloudinit-r0.qcow2
+  arch: aarch64
+  digest: sha512:08d340126b222abae651a20aa63c3ee3dc601d703de7879d2a6bc1fe82a3664d058a2c55ad0cf8a874327f7535e3af8a9384ce438217d6f32200cad1462a5b32
diff --git a/templates/_images/archlinux.yaml b/templates/_images/archlinux.yaml
new file mode 100644
index 00000000..116754e1
--- /dev/null
+++ b/templates/_images/archlinux.yaml
@@ -0,0 +1,16 @@
+images:
+# Try to use yyyyMMdd.REV image if available. Note that yyyyMMdd.REV will be removed after several months.
+
+- location: https://geo.mirror.pkgbuild.com/images/v20250315.322357/Arch-Linux-x86_64-cloudimg-20250315.322357.qcow2
+  arch: x86_64
+  digest: sha256:b162746f6e64064500901ecb61b76f3d2873fcd25bdab4aaa784758719a701c5
+
+- location: https://github.com/mcginty/arch-boxes-arm/releases/download/v20220323/Arch-Linux-aarch64-cloudimg-20220323.0.qcow2
+  arch: aarch64
+  digest: sha512:27524910bf41cb9b3223c8749c6e67fd2f2fdb8b70d40648708e64d6b03c0b4a01b3c5e72d51fefd3e0c3f58487dbb400a79ca378cde2da341a3a19873612be8
+
+# Fallback to the latest release image.
+# Hint: run `limactl prune` to invalidate the cache
+
+- location: https://geo.mirror.pkgbuild.com/images/latest/Arch-Linux-x86_64-cloudimg.qcow2
+  arch: x86_64
diff --git a/templates/_images/centos-stream-10.yaml b/templates/_images/centos-stream-10.yaml
new file mode 100644
index 00000000..7cb4137a
--- /dev/null
+++ b/templates/_images/centos-stream-10.yaml
@@ -0,0 +1,39 @@
+images:
+# Try to use release-yyyyMMdd image if available. Note that release-yyyyMMdd will be removed after several months.
+
+- location: https://cloud.centos.org/centos/10-stream/x86_64/images/CentOS-Stream-GenericCloud-10-20250317.0.x86_64.qcow2
+  arch: x86_64
+  digest: sha256:24578ef181b03ab577acaa885cbc24b1c91fbae613d50152796cbe6c2e004aab
+
+- location: https://cloud.centos.org/centos/10-stream/aarch64/images/CentOS-Stream-GenericCloud-10-20250317.0.aarch64.qcow2
+  arch: aarch64
+  digest: sha256:5cfd6199d9f9ada1e4e44113938981b2dce96ba3e9e670549e6e1c1a8e74f167
+
+- location: https://cloud.centos.org/centos/10-stream/s390x/images/CentOS-Stream-GenericCloud-10-20250317.0.s390x.qcow2
+  arch: s390x
+  digest: sha256:903b47d726fa9a892853cfb805d52a0bf75a7fc710169619bdaae7c3e3a00296
+
+# Fallback to the latest release image.
+# Hint: run `limactl prune` to invalidate the cache
+
+- location: https://cloud.centos.org/centos/10-stream/x86_64/images/CentOS-Stream-GenericCloud-10-latest.x86_64.qcow2
+  arch: x86_64
+
+- location: https://cloud.centos.org/centos/10-stream/aarch64/images/CentOS-Stream-GenericCloud-10-latest.aarch64.qcow2
+  arch: aarch64
+
+- location: https://cloud.centos.org/centos/10-stream/s390x/images/CentOS-Stream-GenericCloud-10-latest.s390x.qcow2
+  arch: s390x
+
+mountTypesUnsupported: [9p]
+
+firmware:
+  # CentOS Stream 10 still requires legacyBIOS
+  # https://issues.redhat.com/browse/CS-2672
+  legacyBIOS: true
+
+cpuType:
+  # When emulating Intel on ARM hosts, Lima uses the "qemu64" CPU by default (https://github.com/lima-vm/lima/pull/494).
+  # However, CentOS Stream 10 kernel reboots indefinitely due to lack of the support for x86_64-v3 instructions.
+  # This issue is tracked in <https://github.com/lima-vm/lima/issues/3063>.
+  x86_64: "Haswell-v4"
diff --git a/templates/_images/centos-stream-9.yaml b/templates/_images/centos-stream-9.yaml
new file mode 100644
index 00000000..bee6789f
--- /dev/null
+++ b/templates/_images/centos-stream-9.yaml
@@ -0,0 +1,32 @@
+images:
+# Try to use release-yyyyMMdd image if available. Note that release-yyyyMMdd will be removed after several months.
+
+- location: https://cloud.centos.org/centos/9-stream/x86_64/images/CentOS-Stream-GenericCloud-9-20250317.0.x86_64.qcow2
+  arch: x86_64
+  digest: sha256:d126417bee8428880ec9070f1833adcf75f048be839b7c121fda4f5ef242eea2
+
+- location: https://cloud.centos.org/centos/9-stream/aarch64/images/CentOS-Stream-GenericCloud-9-20250317.0.aarch64.qcow2
+  arch: aarch64
+  digest: sha256:e292c1dcd2a58c9e7e47b66f8eb565f647743bcce088e2434ccb746b12fe694a
+
+- location: https://cloud.centos.org/centos/9-stream/s390x/images/CentOS-Stream-GenericCloud-9-20250317.0.s390x.qcow2
+  arch: s390x
+  digest: sha256:b3147474d2332a9d0d47fc0e43ff0c9d37cacf485925396beee0a057a3b7ec6f
+
+# Fallback to the latest release image.
+# Hint: run `limactl prune` to invalidate the cache
+
+- location: https://cloud.centos.org/centos/9-stream/x86_64/images/CentOS-Stream-GenericCloud-9-latest.x86_64.qcow2
+  arch: x86_64
+
+- location: https://cloud.centos.org/centos/9-stream/aarch64/images/CentOS-Stream-GenericCloud-9-latest.aarch64.qcow2
+  arch: aarch64
+
+- location: https://cloud.centos.org/centos/9-stream/s390x/images/CentOS-Stream-GenericCloud-9-latest.s390x.qcow2
+  arch: s390x
+
+mountTypesUnsupported: [9p]
+
+firmware:
+  # CentOS Stream 9 still requires legacyBIOS, while AlmaLinux 9 and Rocky Linux 9 do not.
+  legacyBIOS: true
diff --git a/templates/_images/debian-11.yaml b/templates/_images/debian-11.yaml
new file mode 100644
index 00000000..802b7072
--- /dev/null
+++ b/templates/_images/debian-11.yaml
@@ -0,0 +1,25 @@
+images:
+# Try to use release-yyyyMMdd image if available. Note that release-yyyyMMdd will be removed after several months.
+
+- location: https://cloud.debian.org/images/cloud/bullseye/20250303-2040/debian-11-genericcloud-amd64-20250303-2040.qcow2
+  arch: x86_64
+  digest: sha512:3c08356d6860f987089c14b45953fb1f266d1b1b50dd086744925e2ed4113b804e848a8b1b46614febc48cde759f18e824b76bfb02618ed6b3d06ed15ea99283
+
+- location: https://cloud.debian.org/images/cloud/bullseye/20250303-2040/debian-11-genericcloud-arm64-20250303-2040.qcow2
+  arch: aarch64
+  digest: sha512:c1a1645cf37ce628a8734bb25dce09fcd0858865302635ce0ae88b2da23bb615da43d483984709d743cd6b6b45d56d88e9f6800f0b3110ba1b09c01b990342f3
+
+# Fallback to the latest release image.
+# Hint: run `limactl prune` to invalidate the cache
+
+- location: https://cloud.debian.org/images/cloud/bullseye/latest/debian-11-genericcloud-amd64.qcow2
+  arch: x86_64
+
+- location: https://cloud.debian.org/images/cloud/bullseye/latest/debian-11-genericcloud-arm64.qcow2
+  arch: aarch64
+
+mountTypesUnsupported: [9p]
+
+# debian-11 seems incompatible with vz
+# https://github.com/lima-vm/lima/issues/2855
+vmType: qemu
diff --git a/templates/_images/debian-12.yaml b/templates/_images/debian-12.yaml
new file mode 100644
index 00000000..04edb634
--- /dev/null
+++ b/templates/_images/debian-12.yaml
@@ -0,0 +1,21 @@
+images:
+# Try to use release-yyyyMMdd image if available. Note that release-yyyyMMdd will be removed after several months.
+
+- location: https://cloud.debian.org/images/cloud/bookworm/20250316-2053/debian-12-genericcloud-amd64-20250316-2053.qcow2
+  arch: x86_64
+  digest: sha512:0ea74c246c5eb8c6eb5b8e3b8b5268b16a791dfbc8f0bca27d9d787a3f4c50a7830bfc690e6902dfe78031fb2b2c3892349990d6b26b13112252a81d6f20f792
+
+- location: https://cloud.debian.org/images/cloud/bookworm/20250316-2053/debian-12-genericcloud-arm64-20250316-2053.qcow2
+  arch: aarch64
+  digest: sha512:a6733f7f76ef62706e9e04dbad15d7ca251a2875d31025d9e8893391985b7e0610c96b6133ec5b2fa5fc4426bb3e6dcc91da77d0b3dc59bf4352e30625fc180d
+
+# Fallback to the latest release image.
+# Hint: run `limactl prune` to invalidate the cache
+
+- location: https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-genericcloud-amd64.qcow2
+  arch: x86_64
+
+- location: https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-genericcloud-arm64.qcow2
+  arch: aarch64
+
+mountTypesUnsupported: [9p]
diff --git a/templates/_images/fedora-41.yaml b/templates/_images/fedora-41.yaml
new file mode 100644
index 00000000..db86d777
--- /dev/null
+++ b/templates/_images/fedora-41.yaml
@@ -0,0 +1,12 @@
+images:
+- location: https://download.fedoraproject.org/pub/fedora/linux/releases/41/Cloud/x86_64/images/Fedora-Cloud-Base-Generic-41-1.4.x86_64.qcow2
+  arch: x86_64
+  digest: sha256:6205ae0c524b4d1816dbd3573ce29b5c44ed26c9fbc874fbe48c41c89dd0bac2
+
+- location: https://download.fedoraproject.org/pub/fedora/linux/releases/41/Cloud/aarch64/images/Fedora-Cloud-Base-Generic-41-1.4.aarch64.qcow2
+  arch: aarch64
+  digest: sha256:085883b42c7e3b980e366a1fe006cd0ff15877f7e6e984426f3c6c67c7cc2faa
+
+# 9p is broken in Linux v6.9, v6.10, and v6.11 (used by Fedora 41).
+# The issue was fixed in Linux v6.12-rc5 (https://github.com/torvalds/linux/commit/be2ca38).
+mountTypesUnsupported: [9p]
diff --git a/templates/_images/fedora-42.yaml b/templates/_images/fedora-42.yaml
new file mode 100644
index 00000000..62dfb836
--- /dev/null
+++ b/templates/_images/fedora-42.yaml
@@ -0,0 +1,13 @@
+images:
+- location: https://download.fedoraproject.org/pub/fedora/linux/releases/42/Cloud/x86_64/images/Fedora-Cloud-Base-Generic-42-1.1.x86_64.qcow2
+  arch: x86_64
+  digest: sha256:e401a4db2e5e04d1967b6729774faa96da629bcf3ba90b67d8d9cce9906bec0f
+
+- location: https://download.fedoraproject.org/pub/fedora/linux/releases/42/Cloud/aarch64/images/Fedora-Cloud-Base-Generic-42-1.1.aarch64.qcow2
+  arch: aarch64
+  digest: sha256:e10658419a8d50231037dc781c3155aa94180a8c7a74e5cac2a6b09eaa9342b7
+
+
+# # NOTE: Intel Mac requires setting vmType to qemu
+# # https://github.com/lima-vm/lima/issues/3334
+# vmType: qemu
diff --git a/templates/_images/fedora.yaml b/templates/_images/fedora.yaml
new file mode 120000
index 00000000..98dcf55f
--- /dev/null
+++ b/templates/_images/fedora.yaml
@@ -0,0 +1 @@
+fedora-41.yaml
\ No newline at end of file
diff --git a/templates/_images/opensuse-leap.yaml b/templates/_images/opensuse-leap.yaml
new file mode 100644
index 00000000..885b4014
--- /dev/null
+++ b/templates/_images/opensuse-leap.yaml
@@ -0,0 +1,14 @@
+images:
+# Hint: run `limactl prune` to invalidate the Current cache
+
+- location: https://download.opensuse.org/distribution/leap/15.6/appliances/openSUSE-Leap-15.6-Minimal-VM.x86_64-Cloud.qcow2
+  arch: x86_64
+
+- location: https://download.opensuse.org/distribution/leap/15.6/appliances/openSUSE-Leap-15.6-Minimal-VM.aarch64-Cloud.qcow2
+  arch: aarch64
+
+# Hint: to allow 9p and virtiofs, replace the `kernel-default-base` package with `kernel-default` and reboot the VM.
+# https://github.com/lima-vm/lima/issues/3055
+mountType: reverse-sshfs
+
+mountTypesUnsupported: [9p, virtiofs]
diff --git a/templates/_images/oraclelinux-8.yaml b/templates/_images/oraclelinux-8.yaml
new file mode 100644
index 00000000..5ca5df18
--- /dev/null
+++ b/templates/_images/oraclelinux-8.yaml
@@ -0,0 +1,25 @@
+# Oracle image license: https://www.oracle.com/downloads/licenses/oracle-linux-license.html
+# Image source: https://yum.oracle.com/oracle-linux-templates.html
+
+# NOTE: EL8-based distros are known not to work on M1 chips: https://github.com/lima-vm/lima/issues/841
+# EL9-based distros are known to work.
+
+images:
+- location: https://yum.oracle.com/templates/OracleLinux/OL8/u10/x86_64/OL8U10_x86_64-kvm-b237.qcow2
+  arch: x86_64
+  digest: sha256:53a5eee27c59f335ba1bdb0afc2c3273895f128dd238b51a78f46ad515cbc662
+
+- location: https://yum.oracle.com/templates/OracleLinux/OL8/u10/aarch64/OL8U10_aarch64-kvm-cloud-b100.qcow2
+  arch: aarch64
+  digest: sha256:def7b8055e275507a593f07dc6076a2adc5967af046c003072b479e69f25f407
+
+mountTypesUnsupported: [9p]
+
+firmware:
+  # Oracle Linux 8 still requires legacyBIOS, while AlmaLinux 8 and Rocky Linux 8 do not.
+  legacyBIOS: true
+
+cpuType:
+  # Workaround for vmx_write_mem: mmu_gva_to_gpa XXXXXXXXXXXXXXXX failed on Intel Mac
+  # https://bugs.launchpad.net/qemu/+bug/1838390
+  x86_64: Haswell-v4
diff --git a/templates/_images/oraclelinux-9.yaml b/templates/_images/oraclelinux-9.yaml
new file mode 100644
index 00000000..224fc3d1
--- /dev/null
+++ b/templates/_images/oraclelinux-9.yaml
@@ -0,0 +1,17 @@
+# Oracle image license: https://www.oracle.com/downloads/licenses/oracle-linux-license.html
+# Image source: https://yum.oracle.com/oracle-linux-templates.html
+
+images:
+- location: https://yum.oracle.com/templates/OracleLinux/OL9/u5/x86_64/OL9U5_x86_64-kvm-b253.qcow2
+  arch: x86_64
+  digest: sha256:3b00bbbefc8e78dd28d9f538834fb9e2a03d5ccdc2cadf2ffd0036c0a8f02021
+
+- location: https://yum.oracle.com/templates/OracleLinux/OL9/u5/aarch64/OL9U5_aarch64-kvm-cloud-b117.qcow2
+  arch: aarch64
+  digest: sha256:6b62b633eb66cd1769015c25699d4d5f15c41c8fe5ef6ec3e81f0f2d5ed9e4d4
+
+mountTypesUnsupported: [9p]
+
+firmware:
+  # Oracle Linux 9 still requires legacyBIOS, while AlmaLinux 9 and Rocky Linux 9 do not.
+  legacyBIOS: true
diff --git a/templates/_images/rocky-8.yaml b/templates/_images/rocky-8.yaml
new file mode 100644
index 00000000..bbc4efd5
--- /dev/null
+++ b/templates/_images/rocky-8.yaml
@@ -0,0 +1,27 @@
+# NOTE: EL8-based distros are known not to work on M1 chips: https://github.com/lima-vm/lima/issues/841
+# EL9-based distros are known to work.
+
+images:
+- location: https://dl.rockylinux.org/pub/rocky/8.10/images/x86_64/Rocky-8-GenericCloud-Base-8.10-20240528.0.x86_64.qcow2
+  arch: x86_64
+  digest: sha256:e56066c58606191e96184de9a9183a3af33c59bcbd8740d8b10ca054a7a89c14
+
+- location: https://dl.rockylinux.org/pub/rocky/8.10/images/aarch64/Rocky-8-GenericCloud-Base-8.10-20240528.0.aarch64.qcow2
+  arch: aarch64
+  digest: sha256:946b5b9845aa5e3ed98f1bc6ee9873201712a2aef01b87731aed16857e0ca13f
+
+# Fallback to the latest release image.
+# Hint: run `limactl prune` to invalidate the cache
+
+- location: https://dl.rockylinux.org/pub/rocky/8/images/x86_64/Rocky-8-GenericCloud.latest.x86_64.qcow2
+  arch: x86_64
+
+- location: https://dl.rockylinux.org/pub/rocky/8/images/aarch64/Rocky-8-GenericCloud.latest.aarch64.qcow2
+  arch: aarch64
+
+mountTypesUnsupported: [9p]
+
+cpuType:
+  # Workaround for vmx_write_mem: mmu_gva_to_gpa XXXXXXXXXXXXXXXX failed on Intel Mac
+  # https://bugs.launchpad.net/qemu/+bug/1838390
+  x86_64: Haswell-v4
diff --git a/templates/_images/rocky-9.yaml b/templates/_images/rocky-9.yaml
new file mode 100644
index 00000000..9377d554
--- /dev/null
+++ b/templates/_images/rocky-9.yaml
@@ -0,0 +1,19 @@
+images:
+- location: https://dl.rockylinux.org/pub/rocky/9.5/images/x86_64/Rocky-9-GenericCloud-Base-9.5-20241118.0.x86_64.qcow2
+  arch: x86_64
+  digest: sha256:069493fdc807300a22176540e9171fcff2227a92b40a7985a0c1c9e21aeebf57
+
+- location: https://dl.rockylinux.org/pub/rocky/9.5/images/aarch64/Rocky-9-GenericCloud-Base-9.5-20241118.0.aarch64.qcow2
+  arch: aarch64
+  digest: sha256:5443bcc0507fadc3d7bd3e8d266135ab8db6966c703216933f824164fd3252f1
+
+# Fallback to the latest release image.
+# Hint: run `limactl prune` to invalidate the cache
+
+- location: https://dl.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud.latest.x86_64.qcow2
+  arch: x86_64
+
+- location: https://dl.rockylinux.org/pub/rocky/9/images/aarch64/Rocky-9-GenericCloud.latest.aarch64.qcow2
+  arch: aarch64
+
+mountTypesUnsupported: [9p]
diff --git a/templates/_images/ubuntu-20.04.yaml b/templates/_images/ubuntu-20.04.yaml
new file mode 100644
index 00000000..0c4e2540
--- /dev/null
+++ b/templates/_images/ubuntu-20.04.yaml
@@ -0,0 +1,33 @@
+images:
+# Try to use release-yyyyMMdd image if available. Note that release-yyyyMMdd will be removed after several months.
+
+- location: https://cloud-images.ubuntu.com/releases/focal/release-20250303/ubuntu-20.04-server-cloudimg-amd64.img
+  arch: x86_64
+  digest: sha256:77a68bd67a78754bafb4a709d1af27e9a6ccf5dc9753302c6e6407c27d4f7fa0
+
+- location: https://cloud-images.ubuntu.com/releases/focal/release-20250303/ubuntu-20.04-server-cloudimg-arm64.img
+  arch: aarch64
+  digest: sha256:7ca528c6d6a28fb631760a06e5b2462f5d2a64fdf136c810d6083bf0b0bf4a1f
+
+- location: https://cloud-images.ubuntu.com/releases/focal/release-20250303/ubuntu-20.04-server-cloudimg-armhf.img
+  arch: armv7l
+  digest: sha256:b3eea15775504e94d145ba31a9171dae213c8b253cc5e99d8d4a9994d9902a24
+
+- location: https://cloud-images.ubuntu.com/releases/focal/release-20250303/ubuntu-20.04-server-cloudimg-s390x.img
+  arch: s390x
+  digest: sha256:de1c7370d59563caf29d0b6a9af43d5ab44e57e23fbda54d4b12b26bcbf6c7cf
+
+# Fallback to the latest release image.
+# Hint: run `limactl prune` to invalidate the cache
+
+- location: https://cloud-images.ubuntu.com/releases/focal/release/ubuntu-20.04-server-cloudimg-amd64.img
+  arch: x86_64
+
+- location: https://cloud-images.ubuntu.com/releases/focal/release/ubuntu-20.04-server-cloudimg-arm64.img
+  arch: aarch64
+
+- location: https://cloud-images.ubuntu.com/releases/focal/release/ubuntu-20.04-server-cloudimg-armhf.img
+  arch: armv7l
+
+- location: https://cloud-images.ubuntu.com/releases/focal/release/ubuntu-20.04-server-cloudimg-s390x.img
+  arch: s390x
diff --git a/templates/_images/ubuntu-22.04.yaml b/templates/_images/ubuntu-22.04.yaml
new file mode 100644
index 00000000..34217e3d
--- /dev/null
+++ b/templates/_images/ubuntu-22.04.yaml
@@ -0,0 +1,40 @@
+images:
+# Try to use release-yyyyMMdd image if available. Note that release-yyyyMMdd will be removed after several months.
+
+- location: https://cloud-images.ubuntu.com/releases/jammy/release-20250305/ubuntu-22.04-server-cloudimg-amd64.img
+  arch: x86_64
+  digest: sha256:eb4707ac0dec191347bb5123ad2fd2b372077a66e5300ddb4c0d16444f619fa6
+
+- location: https://cloud-images.ubuntu.com/releases/jammy/release-20250305/ubuntu-22.04-server-cloudimg-arm64.img
+  arch: aarch64
+  digest: sha256:46113bedf45e3429bc7e0a74e9bca0a75768c595f61ee45d9cd0141838bda2ca
+
+- location: https://cloud-images.ubuntu.com/releases/jammy/release-20250305/ubuntu-22.04-server-cloudimg-riscv64.img
+  arch: riscv64
+  digest: sha256:0cede637b61ff3575a7648414573d1ee31e36b0d014d3755fb84c7a32bff0bf1
+
+- location: https://cloud-images.ubuntu.com/releases/jammy/release-20250305/ubuntu-22.04-server-cloudimg-armhf.img
+  arch: armv7l
+  digest: sha256:852da1f71a43c7e4a782fb2ae93379eb5810cdd445570f807ede118926a11d06
+
+- location: https://cloud-images.ubuntu.com/releases/jammy/release-20250305/ubuntu-22.04-server-cloudimg-s390x.img
+  arch: s390x
+  digest: sha256:5caf61c680e6aa0b82265d93e953a6b49a5f7961ee2f5cedf8070b6efc9a2339
+
+# Fallback to the latest release image.
+# Hint: run `limactl prune` to invalidate the cache
+
+- location: https://cloud-images.ubuntu.com/releases/jammy/release/ubuntu-22.04-server-cloudimg-amd64.img
+  arch: x86_64
+
+- location: https://cloud-images.ubuntu.com/releases/jammy/release/ubuntu-22.04-server-cloudimg-arm64.img
+  arch: aarch64
+
+- location: https://cloud-images.ubuntu.com/releases/jammy/release/ubuntu-22.04-server-cloudimg-riscv64.img
+  arch: riscv64
+
+- location: https://cloud-images.ubuntu.com/releases/jammy/release/ubuntu-22.04-server-cloudimg-armhf.img
+  arch: armv7l
+
+- location: https://cloud-images.ubuntu.com/releases/jammy/release/ubuntu-22.04-server-cloudimg-s390x.img
+  arch: s390x
diff --git a/templates/_images/ubuntu-24.04.yaml b/templates/_images/ubuntu-24.04.yaml
new file mode 100644
index 00000000..75432a2f
--- /dev/null
+++ b/templates/_images/ubuntu-24.04.yaml
@@ -0,0 +1,40 @@
+images:
+# Try to use release-yyyyMMdd image if available. Note that release-yyyyMMdd will be removed after several months.
+
+- location: https://cloud-images.ubuntu.com/releases/noble/release-20250313/ubuntu-24.04-server-cloudimg-amd64.img
+  arch: x86_64
+  digest: sha256:eacac65efe9e9bae0cbcb3f9d5c2b5e8c5313fa78a3bc401c3fb28b2d48cefc0
+
+- location: https://cloud-images.ubuntu.com/releases/noble/release-20250313/ubuntu-24.04-server-cloudimg-arm64.img
+  arch: aarch64
+  digest: sha256:103f31c5a5b7f031a60ce3555c8fbd56317fd8ffbaaa7e17002879e6157d546d
+
+- location: https://cloud-images.ubuntu.com/releases/noble/release-20250313/ubuntu-24.04-server-cloudimg-riscv64.img
+  arch: riscv64
+  digest: sha256:bfd6a91a7ee84e26f33ce6b2df2e415b038214db67f009206b40cf2e9158fc3f
+
+- location: https://cloud-images.ubuntu.com/releases/noble/release-20250313/ubuntu-24.04-server-cloudimg-armhf.img
+  arch: armv7l
+  digest: sha256:0b862b6a4811f23c76e292ffe5a7cd90a4f03db9f48f664a2a943b02f83621c3
+
+- location: https://cloud-images.ubuntu.com/releases/noble/release-20250313/ubuntu-24.04-server-cloudimg-s390x.img
+  arch: s390x
+  digest: sha256:7e7080ed67f148373ac9645f48fc3f4206fc1e8b517c316f3fc03fca9c04713c
+
+# Fallback to the latest release image.
+# Hint: run `limactl prune` to invalidate the cache
+
+- location: https://cloud-images.ubuntu.com/releases/noble/release/ubuntu-24.04-server-cloudimg-amd64.img
+  arch: x86_64
+
+- location: https://cloud-images.ubuntu.com/releases/noble/release/ubuntu-24.04-server-cloudimg-arm64.img
+  arch: aarch64
+
+- location: https://cloud-images.ubuntu.com/releases/noble/release/ubuntu-24.04-server-cloudimg-riscv64.img
+  arch: riscv64
+
+- location: https://cloud-images.ubuntu.com/releases/noble/release/ubuntu-24.04-server-cloudimg-armhf.img
+  arch: armv7l
+
+- location: https://cloud-images.ubuntu.com/releases/noble/release/ubuntu-24.04-server-cloudimg-s390x.img
+  arch: s390x
diff --git a/templates/_images/ubuntu-24.10.yaml b/templates/_images/ubuntu-24.10.yaml
new file mode 100644
index 00000000..b913fd46
--- /dev/null
+++ b/templates/_images/ubuntu-24.10.yaml
@@ -0,0 +1,44 @@
+images:
+# Try to use release-yyyyMMdd image if available. Note that release-yyyyMMdd will be removed after several months.
+
+- location: https://cloud-images.ubuntu.com/releases/oracular/release-20250305/ubuntu-24.10-server-cloudimg-amd64.img
+  arch: x86_64
+  digest: sha256:c2c3ed89097c5f5c90ebbe45216d1569e3ea2d3c8d0993eeae74f859f6467cdb
+
+- location: https://cloud-images.ubuntu.com/releases/oracular/release-20250305/ubuntu-24.10-server-cloudimg-arm64.img
+  arch: aarch64
+  digest: sha256:9d8e0c98858d53866117d5c701a554a9d2434bedffec1c0ab7253691bfd2c70e
+
+- location: https://cloud-images.ubuntu.com/releases/oracular/release-20250305/ubuntu-24.10-server-cloudimg-riscv64.img
+  arch: riscv64
+  digest: sha256:be6109cfed964a2b745330681f7ec5b9ddc45bb180f41837b6e3969b4be9e8b5
+
+- location: https://cloud-images.ubuntu.com/releases/oracular/release-20250305/ubuntu-24.10-server-cloudimg-armhf.img
+  arch: armv7l
+  digest: sha256:8f3a22d7392512b56ffbcbf30d4f5df0805b7d515f08fb86c5a8f87405ca7f02
+
+- location: https://cloud-images.ubuntu.com/releases/oracular/release-20250305/ubuntu-24.10-server-cloudimg-s390x.img
+  arch: s390x
+  digest: sha256:98b19fee0742b4cfccbfcc72fa82f274355f01dd0e5216263a9988e79e6d03ab
+
+# Fallback to the latest release image.
+# Hint: run `limactl prune` to invalidate the cache
+
+- location: https://cloud-images.ubuntu.com/releases/oracular/release/ubuntu-24.10-server-cloudimg-amd64.img
+  arch: x86_64
+
+- location: https://cloud-images.ubuntu.com/releases/oracular/release/ubuntu-24.10-server-cloudimg-arm64.img
+  arch: aarch64
+
+- location: https://cloud-images.ubuntu.com/releases/oracular/release/ubuntu-24.10-server-cloudimg-riscv64.img
+  arch: riscv64
+
+- location: https://cloud-images.ubuntu.com/releases/oracular/release/ubuntu-24.10-server-cloudimg-armhf.img
+  arch: armv7l
+
+- location: https://cloud-images.ubuntu.com/releases/oracular/release/ubuntu-24.10-server-cloudimg-s390x.img
+  arch: s390x
+
+# 9p is broken in Linux v6.9, v6.10, and v6.11 (used by Ubuntu 24.10).
+# The issue was fixed in Linux v6.12-rc5 (https://github.com/torvalds/linux/commit/be2ca38).
+mountTypesUnsupported: [9p]
diff --git a/templates/_images/ubuntu-25.04.yaml b/templates/_images/ubuntu-25.04.yaml
new file mode 100644
index 00000000..20f54beb
--- /dev/null
+++ b/templates/_images/ubuntu-25.04.yaml
@@ -0,0 +1,44 @@
+images:
+# Try to use release-yyyyMMdd image if available. Note that release-yyyyMMdd will be removed after several months.
+
+- location: https://cloud-images.ubuntu.com/releases/plucky/release-20250415/ubuntu-25.04-server-cloudimg-amd64.img
+  arch: x86_64
+  digest: sha256:6fb0299c53b8872c51b96c54947ee25383378ed5045f2ef18c751be0cab42ecd
+
+- location: https://cloud-images.ubuntu.com/releases/plucky/release-20250415/ubuntu-25.04-server-cloudimg-arm64.img
+  arch: aarch64
+  digest: sha256:d599b0769b6df1a2c9c6a04108beaa265a354f93db15f219c820567a42231486
+
+- location: https://cloud-images.ubuntu.com/releases/plucky/release-20250415/ubuntu-25.04-server-cloudimg-riscv64.img
+  arch: riscv64
+  digest: sha256:accc86a8fea04dff4599fe776fddcaa5ae7d498cbac69a0c25d4dd0292b79b38
+
+- location: https://cloud-images.ubuntu.com/releases/plucky/release-20250415/ubuntu-25.04-server-cloudimg-armhf.img
+  arch: armv7l
+  digest: sha256:28f9959f528f3c7e172b367fdae4032a09e75b4a8499283c6c4c611d91bf9699
+
+- location: https://cloud-images.ubuntu.com/releases/plucky/release-20250415/ubuntu-25.04-server-cloudimg-s390x.img
+  arch: s390x
+  digest: sha256:0ea6c52f2bbf3d35a767f92afe8adc4a648ebf0d31a325dfb97e21be6ef20c70
+
+# Fallback to the latest release image.
+# Hint: run `limactl prune` to invalidate the cache
+
+- location: https://cloud-images.ubuntu.com/releases/plucky/release/ubuntu-25.04-server-cloudimg-amd64.img
+  arch: x86_64
+
+- location: https://cloud-images.ubuntu.com/releases/plucky/release/ubuntu-25.04-server-cloudimg-arm64.img
+  arch: aarch64
+
+- location: https://cloud-images.ubuntu.com/releases/plucky/release/ubuntu-25.04-server-cloudimg-riscv64.img
+  arch: riscv64
+
+- location: https://cloud-images.ubuntu.com/releases/plucky/release/ubuntu-25.04-server-cloudimg-armhf.img
+  arch: armv7l
+
+- location: https://cloud-images.ubuntu.com/releases/plucky/release/ubuntu-25.04-server-cloudimg-s390x.img
+  arch: s390x
+
+# # NOTE: Intel Mac requires setting vmType to qemu
+# # https://github.com/lima-vm/lima/issues/3334
+# vmType: qemu
diff --git a/templates/_images/ubuntu-lts.yaml b/templates/_images/ubuntu-lts.yaml
new file mode 120000
index 00000000..364aeac0
--- /dev/null
+++ b/templates/_images/ubuntu-lts.yaml
@@ -0,0 +1 @@
+ubuntu-24.04.yaml
\ No newline at end of file
diff --git a/templates/_images/ubuntu.yaml b/templates/_images/ubuntu.yaml
new file mode 120000
index 00000000..9e033b6d
--- /dev/null
+++ b/templates/_images/ubuntu.yaml
@@ -0,0 +1 @@
+ubuntu-24.10.yaml
\ No newline at end of file
diff --git a/templates/almalinux-8.yaml b/templates/almalinux-8.yaml
index f42327e8..691ec6dc 100644
--- a/templates/almalinux-8.yaml
+++ b/templates/almalinux-8.yaml
@@ -1,32 +1,5 @@
-# This template requires Lima v0.8.3 or later.
+minimumLimaVersion: 1.1.0
 
-# NOTE: EL8-based distros are known not to work on M1 chips: https://github.com/lima-vm/lima/issues/841
-# EL9-based distros are known to work.
-
-images:
-- location: "https://repo.almalinux.org/almalinux/8.10/cloud/x86_64/images/AlmaLinux-8-GenericCloud-8.10-20240819.x86_64.qcow2"
-  arch: "x86_64"
-  digest: "sha256:669bd580dcef5491d4dfd5724d252cce7cde1b2b33a3ca951e688d71386875e3"
-- location: "https://repo.almalinux.org/almalinux/8.10/cloud/aarch64/images/AlmaLinux-8-GenericCloud-8.10-20240819.aarch64.qcow2"
-  arch: "aarch64"
-  digest: "sha256:cec6736cbc562d06895e218b6f022621343c553bfa79192ca491381b4636c7b8"
-- location: "https://repo.almalinux.org/almalinux/8.10/cloud/s390x/images/AlmaLinux-8-GenericCloud-8.10-20240819.s390x.qcow2"
-  arch: "s390x"
-  digest: "sha256:7f8866a4247ad57c81f5d2c5a0fa64940691f9df1e858a1510d34a0de008eb16"
-# Fallback to the latest release image.
-# Hint: run `limactl prune` to invalidate the cache
-- location: "https://repo.almalinux.org/almalinux/8/cloud/x86_64/images/AlmaLinux-8-GenericCloud-latest.x86_64.qcow2"
-  arch: "x86_64"
-- location: "https://repo.almalinux.org/almalinux/8/cloud/aarch64/images/AlmaLinux-8-GenericCloud-latest.aarch64.qcow2"
-  arch: "aarch64"
-- location: "https://repo.almalinux.org/almalinux/8/cloud/s390x/images/AlmaLinux-8-GenericCloud-latest.s390x.qcow2"
-  arch: "s390x"
-mountTypesUnsupported: ["9p"]
-mounts:
-- location: "~"
-- location: "/tmp/lima"
-  writable: true
-cpuType:
-  # Workaround for "vmx_write_mem: mmu_gva_to_gpa XXXXXXXXXXXXXXXX failed" on Intel Mac
-  # https://bugs.launchpad.net/qemu/+bug/1838390
-  x86_64: "Haswell-v4"
+base:
+- template://_images/almalinux-8
+- template://_default/mounts
diff --git a/templates/almalinux-9.yaml b/templates/almalinux-9.yaml
index 2e727243..51398f4a 100644
--- a/templates/almalinux-9.yaml
+++ b/templates/almalinux-9.yaml
@@ -1,25 +1,5 @@
-# This template requires Lima v0.11.1 or later.
+minimumLimaVersion: 1.1.0
 
-images:
-- location: "https://repo.almalinux.org/almalinux/9.5/cloud/x86_64/images/AlmaLinux-9-GenericCloud-9.5-20241120.x86_64.qcow2"
-  arch: "x86_64"
-  digest: "sha256:abddf01589d46c841f718cec239392924a03b34c4fe84929af5d543c50e37e37"
-- location: "https://repo.almalinux.org/almalinux/9.5/cloud/aarch64/images/AlmaLinux-9-GenericCloud-9.5-20241120.aarch64.qcow2"
-  arch: "aarch64"
-  digest: "sha256:5ede4affaad0a997a2b642f1628b6268bd8eba775f281346b75be3ed20ec369e"
-- location: "https://repo.almalinux.org/almalinux/9.5/cloud/s390x/images/AlmaLinux-9-GenericCloud-9.5-20241120.s390x.qcow2"
-  arch: "s390x"
-  digest: "sha256:9948ea1c5ee1c6497bde5cec18c71c5f9e50861af4c0f1400c1af504eee2b995"
-# Fallback to the latest release image.
-# Hint: run `limactl prune` to invalidate the cache
-- location: "https://repo.almalinux.org/almalinux/9/cloud/x86_64/images/AlmaLinux-9-GenericCloud-latest.x86_64.qcow2"
-  arch: "x86_64"
-- location: "https://repo.almalinux.org/almalinux/9/cloud/aarch64/images/AlmaLinux-9-GenericCloud-latest.aarch64.qcow2"
-  arch: "aarch64"
-- location: "https://repo.almalinux.org/almalinux/9/cloud/s390x/images/AlmaLinux-9-GenericCloud-latest.s390x.qcow2"
-  arch: "s390x"
-mountTypesUnsupported: ["9p"]
-mounts:
-- location: "~"
-- location: "/tmp/lima"
-  writable: true
+base:
+- template://_images/almalinux-9
+- template://_default/mounts
diff --git a/templates/alpine-iso.yaml b/templates/alpine-iso.yaml
index 5bd83325..0e86c1f1 100644
--- a/templates/alpine-iso.yaml
+++ b/templates/alpine-iso.yaml
@@ -1,18 +1,8 @@
-# This template requires Lima v0.7.0 or later.
-# Using the Alpine 3.20 aarch64 image with vmType=vz requires macOS Ventura 13.3 or later.
+minimumLimaVersion: 1.1.0
 
-images:
-- location: "https://github.com/lima-vm/alpine-lima/releases/download/v0.2.41/alpine-lima-std-3.20.3-x86_64.iso"
-  arch: "x86_64"
-  digest: "sha512:949a353c1676bb406561d22c1b7f9db72fb0cc899c6c50166df3b38e392280a7e7b83f58643a309816d51a48317507c46c3e7e24e52fbc9f20fe817039306db1"
-- location: "https://github.com/lima-vm/alpine-lima/releases/download/v0.2.41/alpine-lima-std-3.20.3-aarch64.iso"
-  arch: "aarch64"
-  digest: "sha512:91ea119fea2bb638519792de2047303b26eaebcdace8df57b76373dc7b1cddcad77aaa9fed2d438fb02351b261783af3264d6bb2716519f8ba211a4b25d6f114"
-
-mounts:
-- location: "~"
-- location: "/tmp/lima"
-  writable: true
+base:
+- template://_images/alpine-iso
+- template://_default/mounts
 
 # The built-in containerd installer does not support Alpine currently.
 # Use a provisioning script to install containerd, buildkit, and nerdctl.
diff --git a/templates/alpine.yaml b/templates/alpine.yaml
index 18975213..c11a7c61 100644
--- a/templates/alpine.yaml
+++ b/templates/alpine.yaml
@@ -1,16 +1,11 @@
-images:
-- location: "https://dl-cdn.alpinelinux.org/alpine/v3.21/releases/cloud/nocloud_alpine-3.21.2-x86_64-uefi-cloudinit-r0.qcow2"
-  arch: "x86_64"
-  digest: "sha512:1aaf22b4a584e69e228e6aa38a295159c0143d9ccebe7ad4928e92b414714066af3bfe5f9e0ca4d4d64a70ca9fea09033af90258a6f2344130d70b660151127a"
-- location: "https://dl-cdn.alpinelinux.org/alpine/v3.21/releases/cloud/nocloud_alpine-3.21.2-aarch64-uefi-cloudinit-r0.qcow2"
-  arch: "aarch64"
-  digest: "sha512:08d340126b222abae651a20aa63c3ee3dc601d703de7879d2a6bc1fe82a3664d058a2c55ad0cf8a874327f7535e3af8a9384ce438217d6f32200cad1462a5b32"
-mounts:
-- location: "~"
-- location: "/tmp/lima"
-  writable: true
+minimumLimaVersion: 1.1.0
+
+base:
+- template://_images/alpine
+- template://_default/mounts
 
 # The built-in containerd installer does not support Alpine currently.
+# Use a provisioning script to install containerd, buildkit, and nerdctl.
 containerd:
   system: false
   user: false
diff --git a/templates/apptainer-rootful.yaml b/templates/apptainer-rootful.yaml
index 04178f38..e62304ad 100644
--- a/templates/apptainer-rootful.yaml
+++ b/templates/apptainer-rootful.yaml
@@ -2,24 +2,12 @@
 # $ limactl start ./apptainer-rootful.yaml
 # $ limactl shell apptainer-rootful apptainer run -u -B $HOME:$HOME docker://alpine
 
-images:
-# Try to use release-yyyyMMdd image if available. Note that release-yyyyMMdd will be removed after several months.
-- location: "https://cloud-images.ubuntu.com/releases/noble/release-20250313/ubuntu-24.04-server-cloudimg-amd64.img"
-  arch: "x86_64"
-  digest: "sha256:eacac65efe9e9bae0cbcb3f9d5c2b5e8c5313fa78a3bc401c3fb28b2d48cefc0"
-- location: "https://cloud-images.ubuntu.com/releases/noble/release-20250313/ubuntu-24.04-server-cloudimg-arm64.img"
-  arch: "aarch64"
-  digest: "sha256:103f31c5a5b7f031a60ce3555c8fbd56317fd8ffbaaa7e17002879e6157d546d"
-# Fallback to the latest release image.
-# Hint: run `limactl prune` to invalidate the cache
-- location: "https://cloud-images.ubuntu.com/releases/noble/release/ubuntu-24.04-server-cloudimg-amd64.img"
-  arch: "x86_64"
-- location: "https://cloud-images.ubuntu.com/releases/noble/release/ubuntu-24.04-server-cloudimg-arm64.img"
-  arch: "aarch64"
-mounts:
-- location: "~"
-- location: "/tmp/lima"
-  writable: true
+minimumLimaVersion: 1.1.0
+
+base:
+- template://_images/ubuntu-lts
+- template://_default/mounts
+
 containerd:
   system: false
   user: false
diff --git a/templates/apptainer.yaml b/templates/apptainer.yaml
index bedd36c2..4053213f 100644
--- a/templates/apptainer.yaml
+++ b/templates/apptainer.yaml
@@ -2,24 +2,12 @@
 # $ limactl start ./apptainer.yaml
 # $ limactl shell apptainer apptainer run -u -B $HOME:$HOME docker://alpine
 
-images:
-# Try to use release-yyyyMMdd image if available. Note that release-yyyyMMdd will be removed after several months.
-- location: "https://cloud-images.ubuntu.com/releases/noble/release-20250313/ubuntu-24.04-server-cloudimg-amd64.img"
-  arch: "x86_64"
-  digest: "sha256:eacac65efe9e9bae0cbcb3f9d5c2b5e8c5313fa78a3bc401c3fb28b2d48cefc0"
-- location: "https://cloud-images.ubuntu.com/releases/noble/release-20250313/ubuntu-24.04-server-cloudimg-arm64.img"
-  arch: "aarch64"
-  digest: "sha256:103f31c5a5b7f031a60ce3555c8fbd56317fd8ffbaaa7e17002879e6157d546d"
-# Fallback to the latest release image.
-# Hint: run `limactl prune` to invalidate the cache
-- location: "https://cloud-images.ubuntu.com/releases/noble/release/ubuntu-24.04-server-cloudimg-amd64.img"
-  arch: "x86_64"
-- location: "https://cloud-images.ubuntu.com/releases/noble/release/ubuntu-24.04-server-cloudimg-arm64.img"
-  arch: "aarch64"
-mounts:
-- location: "~"
-- location: "/tmp/lima"
-  writable: true
+minimumLimaVersion: 1.1.0
+
+base:
+- template://_images/ubuntu-lts
+- template://_default/mounts
+
 containerd:
   system: false
   user: false
diff --git a/templates/archlinux.yaml b/templates/archlinux.yaml
index 8373b9a2..73074e1f 100644
--- a/templates/archlinux.yaml
+++ b/templates/archlinux.yaml
@@ -1,19 +1,5 @@
-# This template requires Lima v0.7.0 or later
-images:
-# Try to use yyyyMMdd.REV image if available. Note that yyyyMMdd.REV will be removed after several months.
+minimumLimaVersion: 1.1.0
 
-- location: "https://geo.mirror.pkgbuild.com/images/v20250315.322357/Arch-Linux-x86_64-cloudimg-20250315.322357.qcow2"
-  arch: "x86_64"
-  digest: "sha256:b162746f6e64064500901ecb61b76f3d2873fcd25bdab4aaa784758719a701c5"
-- location: "https://github.com/mcginty/arch-boxes-arm/releases/download/v20220323/Arch-Linux-aarch64-cloudimg-20220323.0.qcow2"
-  arch: "aarch64"
-  digest: "sha512:27524910bf41cb9b3223c8749c6e67fd2f2fdb8b70d40648708e64d6b03c0b4a01b3c5e72d51fefd3e0c3f58487dbb400a79ca378cde2da341a3a19873612be8"
-# Fallback to the latest release image.
-# Hint: run `limactl prune` to invalidate the cache
-- location: "https://geo.mirror.pkgbuild.com/images/latest/Arch-Linux-x86_64-cloudimg.qcow2"
-  arch: "x86_64"
-
-mounts:
-- location: "~"
-- location: "/tmp/lima"
-  writable: true
+base:
+- template://_images/archlinux
+- template://_default/mounts
diff --git a/templates/buildkit.yaml b/templates/buildkit.yaml
index afa0eb67..1438491c 100644
--- a/templates/buildkit.yaml
+++ b/templates/buildkit.yaml
@@ -10,20 +10,11 @@ message: |
   export BUILDKIT_HOST="unix://{{.Dir}}/sock/buildkitd.sock"
   buildctl debug workers
   -------
-images:
-# Try to use release-yyyyMMdd image if available. Note that release-yyyyMMdd will be removed after several months.
-- location: "https://cloud-images.ubuntu.com/releases/noble/release-20250313/ubuntu-24.04-server-cloudimg-amd64.img"
-  arch: "x86_64"
-  digest: "sha256:eacac65efe9e9bae0cbcb3f9d5c2b5e8c5313fa78a3bc401c3fb28b2d48cefc0"
-- location: "https://cloud-images.ubuntu.com/releases/noble/release-20250313/ubuntu-24.04-server-cloudimg-arm64.img"
-  arch: "aarch64"
-  digest: "sha256:103f31c5a5b7f031a60ce3555c8fbd56317fd8ffbaaa7e17002879e6157d546d"
-# Fallback to the latest release image.
-# Hint: run `limactl prune` to invalidate the cache
-- location: "https://cloud-images.ubuntu.com/releases/noble/release/ubuntu-24.04-server-cloudimg-amd64.img"
-  arch: "x86_64"
-- location: "https://cloud-images.ubuntu.com/releases/noble/release/ubuntu-24.04-server-cloudimg-arm64.img"
-  arch: "aarch64"
+
+minimumLimaVersion: 1.1.0
+
+base: template://_images/ubuntu-lts
+
 containerd:
   system: false
   user: true
diff --git a/templates/centos-stream-10.yaml b/templates/centos-stream-10.yaml
index f3cc1640..3174141b 100644
--- a/templates/centos-stream-10.yaml
+++ b/templates/centos-stream-10.yaml
@@ -1,35 +1,5 @@
-# minimumLimaVersion: "1.0.3"
+minimumLimaVersion: 1.1.0
 
-images:
-# Try to use release-yyyyMMdd image if available. Note that release-yyyyMMdd will be removed after several months.
-- location: "https://cloud.centos.org/centos/10-stream/x86_64/images/CentOS-Stream-GenericCloud-10-20250317.0.x86_64.qcow2"
-  arch: "x86_64"
-  digest: "sha256:24578ef181b03ab577acaa885cbc24b1c91fbae613d50152796cbe6c2e004aab"
-- location: "https://cloud.centos.org/centos/10-stream/aarch64/images/CentOS-Stream-GenericCloud-10-20250317.0.aarch64.qcow2"
-  arch: "aarch64"
-  digest: "sha256:5cfd6199d9f9ada1e4e44113938981b2dce96ba3e9e670549e6e1c1a8e74f167"
-- location: "https://cloud.centos.org/centos/10-stream/s390x/images/CentOS-Stream-GenericCloud-10-20250317.0.s390x.qcow2"
-  arch: "s390x"
-  digest: "sha256:903b47d726fa9a892853cfb805d52a0bf75a7fc710169619bdaae7c3e3a00296"
-# Fallback to the latest release image.
-# Hint: run `limactl prune` to invalidate the cache
-- location: "https://cloud.centos.org/centos/10-stream/x86_64/images/CentOS-Stream-GenericCloud-10-latest.x86_64.qcow2"
-  arch: "x86_64"
-- location: "https://cloud.centos.org/centos/10-stream/aarch64/images/CentOS-Stream-GenericCloud-10-latest.aarch64.qcow2"
-  arch: "aarch64"
-- location: "https://cloud.centos.org/centos/10-stream/s390x/images/CentOS-Stream-GenericCloud-10-latest.s390x.qcow2"
-  arch: "s390x"
-mountTypesUnsupported: ["9p"]
-mounts:
-- location: "~"
-- location: "/tmp/lima"
-  writable: true
-firmware:
-  # CentOS Stream 10 still requires legacyBIOS
-  # https://issues.redhat.com/browse/CS-2672
-  legacyBIOS: true
-cpuType:
-  # When emulating Intel on ARM hosts, Lima uses the "qemu64" CPU by default (https://github.com/lima-vm/lima/pull/494).
-  # However, CentOS Stream 10 kernel reboots indefinitely due to lack of the support for x86_64-v3 instructions.
-  # This issue is tracked in <https://github.com/lima-vm/lima/issues/3063>.
-  x86_64: "Haswell-v4"
+base:
+- template://_images/centos-stream-10
+- template://_default/mounts
diff --git a/templates/centos-stream-9.yaml b/templates/centos-stream-9.yaml
index 37590a74..003b4e83 100644
--- a/templates/centos-stream-9.yaml
+++ b/templates/centos-stream-9.yaml
@@ -1,29 +1,5 @@
-# This template requires Lima v0.11.1 or later.
+minimumLimaVersion: 1.1.0
 
-images:
-# Try to use release-yyyyMMdd image if available. Note that release-yyyyMMdd will be removed after several months.
-- location: "https://cloud.centos.org/centos/9-stream/x86_64/images/CentOS-Stream-GenericCloud-9-20250317.0.x86_64.qcow2"
-  arch: "x86_64"
-  digest: "sha256:d126417bee8428880ec9070f1833adcf75f048be839b7c121fda4f5ef242eea2"
-- location: "https://cloud.centos.org/centos/9-stream/aarch64/images/CentOS-Stream-GenericCloud-9-20250317.0.aarch64.qcow2"
-  arch: "aarch64"
-  digest: "sha256:e292c1dcd2a58c9e7e47b66f8eb565f647743bcce088e2434ccb746b12fe694a"
-- location: "https://cloud.centos.org/centos/9-stream/s390x/images/CentOS-Stream-GenericCloud-9-20250317.0.s390x.qcow2"
-  arch: "s390x"
-  digest: "sha256:b3147474d2332a9d0d47fc0e43ff0c9d37cacf485925396beee0a057a3b7ec6f"
-# Fallback to the latest release image.
-# Hint: run `limactl prune` to invalidate the cache
-- location: "https://cloud.centos.org/centos/9-stream/x86_64/images/CentOS-Stream-GenericCloud-9-latest.x86_64.qcow2"
-  arch: "x86_64"
-- location: "https://cloud.centos.org/centos/9-stream/aarch64/images/CentOS-Stream-GenericCloud-9-latest.aarch64.qcow2"
-  arch: "aarch64"
-- location: "https://cloud.centos.org/centos/9-stream/s390x/images/CentOS-Stream-GenericCloud-9-latest.s390x.qcow2"
-  arch: "s390x"
-mountTypesUnsupported: ["9p"]
-mounts:
-- location: "~"
-- location: "/tmp/lima"
-  writable: true
-firmware:
-  # CentOS Stream 9 still requires legacyBIOS, while AlmaLinux 9 and Rocky Linux 9 do not.
-  legacyBIOS: true
+base:
+- template://_images/centos-stream-9
+- template://_default/mounts
diff --git a/templates/debian-11.yaml b/templates/debian-11.yaml
index 3c430df6..724cf448 100644
--- a/templates/debian-11.yaml
+++ b/templates/debian-11.yaml
@@ -1,24 +1,5 @@
-# This template requires Lima v0.7.0 or later
-images:
-# Try to use release-yyyyMMdd image if available. Note that release-yyyyMMdd will be removed after several months.
-- location: "https://cloud.debian.org/images/cloud/bullseye/20250303-2040/debian-11-genericcloud-amd64-20250303-2040.qcow2"
-  arch: "x86_64"
-  digest: "sha512:3c08356d6860f987089c14b45953fb1f266d1b1b50dd086744925e2ed4113b804e848a8b1b46614febc48cde759f18e824b76bfb02618ed6b3d06ed15ea99283"
-- location: "https://cloud.debian.org/images/cloud/bullseye/20250303-2040/debian-11-genericcloud-arm64-20250303-2040.qcow2"
-  arch: "aarch64"
-  digest: "sha512:c1a1645cf37ce628a8734bb25dce09fcd0858865302635ce0ae88b2da23bb615da43d483984709d743cd6b6b45d56d88e9f6800f0b3110ba1b09c01b990342f3"
-# Fallback to the latest release image.
-# Hint: run `limactl prune` to invalidate the cache
-- location: "https://cloud.debian.org/images/cloud/bullseye/latest/debian-11-genericcloud-amd64.qcow2"
-  arch: "x86_64"
-- location: "https://cloud.debian.org/images/cloud/bullseye/latest/debian-11-genericcloud-arm64.qcow2"
-  arch: "aarch64"
-mountTypesUnsupported: ["9p"]
-mounts:
-- location: "~"
-- location: "/tmp/lima"
-  writable: true
+minimumLimaVersion: 1.1.0
 
-# debian-11 seems incompatible with vz
-# https://github.com/lima-vm/lima/issues/2855
-vmType: "qemu"
+base:
+- template://_images/debian-11
+- template://_default/mounts
diff --git a/templates/debian-12.yaml b/templates/debian-12.yaml
index e12e3460..70649ad8 100644
--- a/templates/debian-12.yaml
+++ b/templates/debian-12.yaml
@@ -1,20 +1,5 @@
-# This template requires Lima v0.7.0 or later
-images:
-# Try to use release-yyyyMMdd image if available. Note that release-yyyyMMdd will be removed after several months.
-- location: "https://cloud.debian.org/images/cloud/bookworm/20250316-2053/debian-12-genericcloud-amd64-20250316-2053.qcow2"
-  arch: "x86_64"
-  digest: "sha512:0ea74c246c5eb8c6eb5b8e3b8b5268b16a791dfbc8f0bca27d9d787a3f4c50a7830bfc690e6902dfe78031fb2b2c3892349990d6b26b13112252a81d6f20f792"
-- location: "https://cloud.debian.org/images/cloud/bookworm/20250316-2053/debian-12-genericcloud-arm64-20250316-2053.qcow2"
-  arch: "aarch64"
-  digest: "sha512:a6733f7f76ef62706e9e04dbad15d7ca251a2875d31025d9e8893391985b7e0610c96b6133ec5b2fa5fc4426bb3e6dcc91da77d0b3dc59bf4352e30625fc180d"
-# Fallback to the latest release image.
-# Hint: run `limactl prune` to invalidate the cache
-- location: "https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-genericcloud-amd64.qcow2"
-  arch: "x86_64"
-- location: "https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-genericcloud-arm64.qcow2"
-  arch: "aarch64"
-mountTypesUnsupported: ["9p"]
-mounts:
-- location: "~"
-- location: "/tmp/lima"
-  writable: true
+minimumLimaVersion: 1.1.0
+
+base:
+- template://_images/debian-12
+- template://_default/mounts
diff --git a/templates/default.yaml b/templates/default.yaml
index eac787d7..6dc3a6fd 100644
--- a/templates/default.yaml
+++ b/templates/default.yaml
@@ -16,37 +16,11 @@ vmType: null
 arch: null
 
 # OpenStack-compatible disk image.
+# Each image has a `location` URL for the disk image, an `arch` setting, and an optional `digest`.
 # 🟢 Builtin default: none (must be specified)
-# 🔵 This file: Ubuntu images
-images:
-# Try to use release-yyyyMMdd image if available. Note that release-yyyyMMdd will be removed after several months.
-- location: "https://cloud-images.ubuntu.com/releases/oracular/release-20250305/ubuntu-24.10-server-cloudimg-amd64.img"
-  arch: "x86_64"
-  digest: "sha256:c2c3ed89097c5f5c90ebbe45216d1569e3ea2d3c8d0993eeae74f859f6467cdb"
-- location: "https://cloud-images.ubuntu.com/releases/oracular/release-20250305/ubuntu-24.10-server-cloudimg-arm64.img"
-  arch: "aarch64"
-  digest: "sha256:9d8e0c98858d53866117d5c701a554a9d2434bedffec1c0ab7253691bfd2c70e"
-- location: "https://cloud-images.ubuntu.com/releases/oracular/release-20250305/ubuntu-24.10-server-cloudimg-riscv64.img"
-  arch: "riscv64"
-  digest: "sha256:be6109cfed964a2b745330681f7ec5b9ddc45bb180f41837b6e3969b4be9e8b5"
-- location: "https://cloud-images.ubuntu.com/releases/oracular/release-20250305/ubuntu-24.10-server-cloudimg-armhf.img"
-  arch: "armv7l"
-  digest: "sha256:8f3a22d7392512b56ffbcbf30d4f5df0805b7d515f08fb86c5a8f87405ca7f02"
-- location: "https://cloud-images.ubuntu.com/releases/oracular/release-20250305/ubuntu-24.10-server-cloudimg-s390x.img"
-  arch: "s390x"
-  digest: "sha256:98b19fee0742b4cfccbfcc72fa82f274355f01dd0e5216263a9988e79e6d03ab"
-# Fallback to the latest release image.
-# Hint: run `limactl prune` to invalidate the cache
-- location: "https://cloud-images.ubuntu.com/releases/oracular/release/ubuntu-24.10-server-cloudimg-amd64.img"
-  arch: "x86_64"
-- location: "https://cloud-images.ubuntu.com/releases/oracular/release/ubuntu-24.10-server-cloudimg-arm64.img"
-  arch: "aarch64"
-- location: "https://cloud-images.ubuntu.com/releases/oracular/release/ubuntu-24.10-server-cloudimg-riscv64.img"
-  arch: "riscv64"
-- location: "https://cloud-images.ubuntu.com/releases/oracular/release/ubuntu-24.10-server-cloudimg-armhf.img"
-  arch: "armv7l"
-- location: "https://cloud-images.ubuntu.com/releases/oracular/release/ubuntu-24.10-server-cloudimg-s390x.img"
-  arch: "s390x"
+# 🔵 This file: Ubuntu images (inherited via the `base` mechanism later in this file)
+images: []
+
 # CPUs
 # 🟢 Builtin default: min(4, host CPU cores)
 cpus: null
@@ -63,51 +37,51 @@ disk: null
 # "location" can use these template variables: {{.Home}}, {{.Dir}}, {{.Name}}, {{.UID}}, {{.User}}, and {{.Param.Key}}.
 # "mountPoint" can use these template variables: {{.Home}}, {{.Name}}, {{.Hostname}}, {{.UID}}, {{.User}}, and {{.Param.Key}}.
 # 🟢 Builtin default: [] (Mount nothing)
-# 🔵 This file: Mount the home as read-only, /tmp/lima as writable
-mounts:
-- location: "~"
-  # Configure the mountPoint inside the guest.
-  # 🟢 Builtin default: value of location
-  mountPoint: null
-  # Setting `writable` to true is discouraged when mountType is set to "reverse-sshfs".
-  # 🟢 Builtin default: false
-  writable: null
-  sshfs:
-    # Enabling the SSHFS cache will increase performance of the mounted filesystem, at
-    # the cost of potentially not reflecting changes made on the host in a timely manner.
-    # Warning: It looks like PHP filesystem access does not work correctly when
-    # the cache is disabled.
-    # 🟢 Builtin default: true
-    cache: null
-    # SSHFS has an optional flag called 'follow_symlinks'. This allows mounts
-    # to be properly resolved in the guest os and allow for access to the
-    # contents of the symlink. As a result, symlinked files & folders on the Host
-    # system will look and feel like regular files directories in the Guest OS.
-    # 🟢 Builtin default: false
-    followSymlinks: null
-    # SFTP driver, "builtin" or "openssh-sftp-server". "openssh-sftp-server" is recommended.
-    # 🟢 Builtin default: "openssh-sftp-server" if OpenSSH SFTP Server binary is found, otherwise "builtin"
-    sftpDriver: null
-  9p:
-    # Supported security models are "passthrough", "mapped-xattr", "mapped-file" and "none".
-    # "mapped-xattr" and "mapped-file" are useful for persistent chown but incompatible with symlinks.
-    # 🟢 Builtin default: "none" (since Lima v0.13)
-    securityModel: null
-    # Select 9P protocol version. Valid options are: "9p2000" (legacy), "9p2000.u", "9p2000.L".
-    # 🟢 Builtin default: "9p2000.L"
-    protocolVersion: null
-    # The number of bytes to use for 9p packet payload, where 4KiB is the absolute minimum.
-    # 🟢 Builtin default: "128KiB"
-    msize: null
-    # Specifies a caching policy. Valid options are: "none", "loose", "fscache" and "mmap".
-    # Try choosing "mmap" or "none" if you see a stability issue with the default "fscache".
-    # See https://www.kernel.org/doc/Documentation/filesystems/9p.txt
-    # 🟢 Builtin default: "fscache" for non-writable mounts, "mmap" for writable mounts
-    cache: null
-- location: "/tmp/lima"
-  # 🟢 Builtin default: false
-  # 🔵 This file: true (only for "/tmp/lima")
-  writable: true
+# 🔵 This file: Mount the home as read-only, /tmp/lima as writable  (inherited via the `base` mechanism later in this file)
+mounts: []
+#- location: "~"
+#  # Configure the mountPoint inside the guest.
+#  # 🟢 Builtin default: value of location
+#  mountPoint: null
+#  # Setting `writable` to true is discouraged when mountType is set to "reverse-sshfs".
+#  # 🟢 Builtin default: false
+#  writable: null
+#  sshfs:
+#    # Enabling the SSHFS cache will increase performance of the mounted filesystem, at
+#    # the cost of potentially not reflecting changes made on the host in a timely manner.
+#    # Warning: It looks like PHP filesystem access does not work correctly when
+#    # the cache is disabled.
+#    # 🟢 Builtin default: true
+#    cache: null
+#    # SSHFS has an optional flag called 'follow_symlinks'. This allows mounts
+#    # to be properly resolved in the guest os and allow for access to the
+#    # contents of the symlink. As a result, symlinked files & folders on the Host
+#    # system will look and feel like regular files directories in the Guest OS.
+#    # 🟢 Builtin default: false
+#    followSymlinks: null
+#    # SFTP driver, "builtin" or "openssh-sftp-server". "openssh-sftp-server" is recommended.
+#    # 🟢 Builtin default: "openssh-sftp-server" if OpenSSH SFTP Server binary is found, otherwise "builtin"
+#    sftpDriver: null
+#  9p:
+#    # Supported security models are "passthrough", "mapped-xattr", "mapped-file" and "none".
+#    # "mapped-xattr" and "mapped-file" are useful for persistent chown but incompatible with symlinks.
+#    # 🟢 Builtin default: "none" (since Lima v0.13)
+#    securityModel: null
+#    # Select 9P protocol version. Valid options are: "9p2000" (legacy), "9p2000.u", "9p2000.L".
+#    # 🟢 Builtin default: "9p2000.L"
+#    protocolVersion: null
+#    # The number of bytes to use for 9p packet payload, where 4KiB is the absolute minimum.
+#    # 🟢 Builtin default: "128KiB"
+#    msize: null
+#    # Specifies a caching policy. Valid options are: "none", "loose", "fscache" and "mmap".
+#    # Try choosing "mmap" or "none" if you see a stability issue with the default "fscache".
+#    # See https://www.kernel.org/doc/Documentation/filesystems/9p.txt
+#    # 🟢 Builtin default: "fscache" for non-writable mounts, "mmap" for writable mounts
+#    cache: null
+#- location: "/tmp/lima"
+#  # 🟢 Builtin default: false
+#  # 🔵 This file: true (only for "/tmp/lima")
+#  writable: true
 
 # List of mount types not supported by the kernel of this distro.
 # Also used to resolve the default mount type when not explicitly specified.
@@ -305,7 +279,8 @@ containerd:
 # A template should specify the minimum Lima version required to parse this template correctly.
 # It should not be set if the minimum version is less than 1.0.0
 # 🟢 Builtin default: not set
-minimumLimaVersion: null
+# 🔵 This file: "1.1.0" to use the `base` templating mechanism
+minimumLimaVersion: 1.1.0
 
 # EXPERIMENTAL
 # Default settings can be imported from base templates. These will be merged in when the instance
@@ -316,7 +291,10 @@ minimumLimaVersion: null
 # The "digest" property is currently unused.
 # Any relative base template name will be resolved relative to the location of the main template.
 # 🟢 Builtin default: no base template
-base: null
+# 🔵 This file: Ubuntu images and default mount points
+base:
+- template://_images/ubuntu
+- template://_default/mounts
 
 # User to be used inside the VM
 user:
diff --git a/templates/docker-rootful.yaml b/templates/docker-rootful.yaml
index f5820f21..037b6b83 100644
--- a/templates/docker-rootful.yaml
+++ b/templates/docker-rootful.yaml
@@ -6,25 +6,12 @@
 # $ export DOCKER_HOST=$(limactl list docker-rootful --format 'unix://{{.Dir}}/sock/docker.sock')
 # $ docker ...
 
-# This template requires Lima v0.20.0 or later
-images:
-# Try to use release-yyyyMMdd image if available. Note that release-yyyyMMdd will be removed after several months.
-- location: "https://cloud-images.ubuntu.com/releases/noble/release-20250313/ubuntu-24.04-server-cloudimg-amd64.img"
-  arch: "x86_64"
-  digest: "sha256:eacac65efe9e9bae0cbcb3f9d5c2b5e8c5313fa78a3bc401c3fb28b2d48cefc0"
-- location: "https://cloud-images.ubuntu.com/releases/noble/release-20250313/ubuntu-24.04-server-cloudimg-arm64.img"
-  arch: "aarch64"
-  digest: "sha256:103f31c5a5b7f031a60ce3555c8fbd56317fd8ffbaaa7e17002879e6157d546d"
-# Fallback to the latest release image.
-# Hint: run `limactl prune` to invalidate the cache
-- location: "https://cloud-images.ubuntu.com/releases/noble/release/ubuntu-24.04-server-cloudimg-amd64.img"
-  arch: "x86_64"
-- location: "https://cloud-images.ubuntu.com/releases/noble/release/ubuntu-24.04-server-cloudimg-arm64.img"
-  arch: "aarch64"
-mounts:
-- location: "~"
-- location: "/tmp/lima"
-  writable: true
+minimumLimaVersion: 1.1.0
+
+base:
+- template://_images/ubuntu-lts
+- template://_default/mounts
+
 # containerd is managed by Docker, not by Lima, so the values are set to false here.
 containerd:
   system: false
diff --git a/templates/docker.yaml b/templates/docker.yaml
index 174e84a9..da114809 100644
--- a/templates/docker.yaml
+++ b/templates/docker.yaml
@@ -6,25 +6,12 @@
 # $ export DOCKER_HOST=$(limactl list docker --format 'unix://{{.Dir}}/sock/docker.sock')
 # $ docker ...
 
-# This template requires Lima v0.8.0 or later
-images:
-# Try to use release-yyyyMMdd image if available. Note that release-yyyyMMdd will be removed after several months.
-- location: "https://cloud-images.ubuntu.com/releases/noble/release-20250313/ubuntu-24.04-server-cloudimg-amd64.img"
-  arch: "x86_64"
-  digest: "sha256:eacac65efe9e9bae0cbcb3f9d5c2b5e8c5313fa78a3bc401c3fb28b2d48cefc0"
-- location: "https://cloud-images.ubuntu.com/releases/noble/release-20250313/ubuntu-24.04-server-cloudimg-arm64.img"
-  arch: "aarch64"
-  digest: "sha256:103f31c5a5b7f031a60ce3555c8fbd56317fd8ffbaaa7e17002879e6157d546d"
-# Fallback to the latest release image.
-# Hint: run `limactl prune` to invalidate the cache
-- location: "https://cloud-images.ubuntu.com/releases/noble/release/ubuntu-24.04-server-cloudimg-amd64.img"
-  arch: "x86_64"
-- location: "https://cloud-images.ubuntu.com/releases/noble/release/ubuntu-24.04-server-cloudimg-arm64.img"
-  arch: "aarch64"
-mounts:
-- location: "~"
-- location: "/tmp/lima"
-  writable: true
+minimumLimaVersion: 1.1.0
+
+base:
+- template://_images/ubuntu-lts
+- template://_default/mounts
+
 # containerd is managed by Docker, not by Lima, so the values are set to false here.
 containerd:
   system: false
diff --git a/templates/experimental/alsa.yaml b/templates/experimental/alsa.yaml
index d61e36da..89204746 100644
--- a/templates/experimental/alsa.yaml
+++ b/templates/experimental/alsa.yaml
@@ -1,27 +1,14 @@
 # A template to run ubuntu using device: default
-# This template requires Lima v0.23.0 or later.
-images:
-# Try to use release-yyyyMMdd image if available. Note that release-yyyyMMdd will be removed after several months.
-- location: "https://cloud-images.ubuntu.com/releases/noble/release-20250313/ubuntu-24.04-server-cloudimg-amd64.img"
-  arch: "x86_64"
-  digest: "sha256:eacac65efe9e9bae0cbcb3f9d5c2b5e8c5313fa78a3bc401c3fb28b2d48cefc0"
-- location: "https://cloud-images.ubuntu.com/releases/noble/release-20250313/ubuntu-24.04-server-cloudimg-arm64.img"
-  arch: "aarch64"
-  digest: "sha256:103f31c5a5b7f031a60ce3555c8fbd56317fd8ffbaaa7e17002879e6157d546d"
-# Fallback to the latest release image.
-# Hint: run `limactl prune` to invalidate the cache
-- location: "https://cloud-images.ubuntu.com/releases/noble/release/ubuntu-24.04-server-cloudimg-amd64.img"
-  arch: "x86_64"
-- location: "https://cloud-images.ubuntu.com/releases/noble/release/ubuntu-24.04-server-cloudimg-arm64.img"
-  arch: "aarch64"
-mounts:
-- location: "~"
-- location: "/tmp/lima"
-  writable: true
 
-vmType: "qemu"
+minimumLimaVersion: 1.1.0
+
+base:
+- template://_images/ubuntu-lts
+- template://_default/mounts
+
+vmType: qemu
 audio:
-  device: "default"
+  device: default
 
 provision:
 - mode: system
diff --git a/templates/experimental/debian-sid.yaml b/templates/experimental/debian-sid.yaml
index d3c5f5fc..b5c844dd 100644
--- a/templates/experimental/debian-sid.yaml
+++ b/templates/experimental/debian-sid.yaml
@@ -1,11 +1,12 @@
-# This template requires Lima v0.7.0 or later
+minimumLimaVersion: 1.1.0
+
+base: template://_default/mounts
+
 images:
-- location: "https://cloud.debian.org/images/cloud/sid/daily/latest/debian-sid-genericcloud-amd64-daily.qcow2"
-  arch: "x86_64"
-- location: "https://cloud.debian.org/images/cloud/sid/daily/latest/debian-sid-genericcloud-arm64-daily.qcow2"
-  arch: "aarch64"
-mountTypesUnsupported: ["9p"]
-mounts:
-- location: "~"
-- location: "/tmp/lima"
-  writable: true
+- location: https://cloud.debian.org/images/cloud/sid/daily/latest/debian-sid-genericcloud-amd64-daily.qcow2
+  arch: x86_64
+
+- location: https://cloud.debian.org/images/cloud/sid/daily/latest/debian-sid-genericcloud-arm64-daily.qcow2
+  arch: aarch64
+
+mountTypesUnsupported: [9p]
diff --git a/templates/experimental/gentoo.yaml b/templates/experimental/gentoo.yaml
index c75374da..bb8a6527 100644
--- a/templates/experimental/gentoo.yaml
+++ b/templates/experimental/gentoo.yaml
@@ -1,13 +1,14 @@
-vmType: "qemu"
+minimumLimaVersion: 1.1.0
+
+base: template://_default/mounts
+
 images:
-- location: "https://distfiles.gentoo.org/experimental/amd64/openstack/gentoo-openstack-amd64-default-latest.qcow2"
-  arch: "x86_64"
-
-mounts:
-- location: "~"
-- location: "/tmp/lima"
-  writable: true
-mountType: "9p"
+- location: https://distfiles.gentoo.org/experimental/amd64/openstack/gentoo-openstack-amd64-default-latest.qcow2
+  arch: x86_64
+
+vmType: qemu
+
+mountType: 9p
 
 # The built-in containerd installer does not support Gentoo currently.
 containerd:
diff --git a/templates/experimental/opensuse-tumbleweed.yaml b/templates/experimental/opensuse-tumbleweed.yaml
index 54a3b642..ce5aaa69 100644
--- a/templates/experimental/opensuse-tumbleweed.yaml
+++ b/templates/experimental/opensuse-tumbleweed.yaml
@@ -1,15 +1,17 @@
-# This template requires Lima v0.11.3 or later
+minimumLimaVersion: 1.1.0
+
+base: template://_default/mounts
+
 images:
 # Hint: run `limactl prune` to invalidate the "Current" cache
-- location: "https://download.opensuse.org/tumbleweed/appliances/openSUSE-Tumbleweed-Minimal-VM.x86_64-Cloud.qcow2"
-  arch: "x86_64"
-- location: "https://download.opensuse.org/ports/aarch64/tumbleweed/appliances/openSUSE-Tumbleweed-Minimal-VM.aarch64-Cloud.qcow2"
-  arch: "aarch64"
+- location: https://download.opensuse.org/tumbleweed/appliances/openSUSE-Tumbleweed-Minimal-VM.x86_64-Cloud.qcow2
+  arch: x86_64
+
+- location: https://download.opensuse.org/ports/aarch64/tumbleweed/appliances/openSUSE-Tumbleweed-Minimal-VM.aarch64-Cloud.qcow2
+  arch: aarch64
+
 # Hint: to allow 9p and virtiofs, replace the `kernel-default-base` package with `kernel-default` and reboot the VM.
 # https://github.com/lima-vm/lima/issues/3055
-mountType: "reverse-sshfs"
-mountTypesUnsupported: ["9p", "virtiofs"]
-mounts:
-- location: "~"
-- location: "/tmp/lima"
-  writable: true
+mountType: reverse-sshfs
+
+mountTypesUnsupported: [9p, virtiofs]
diff --git a/templates/experimental/rke2.yaml b/templates/experimental/rke2.yaml
index 75d88fd7..c23082ba 100644
--- a/templates/experimental/rke2.yaml
+++ b/templates/experimental/rke2.yaml
@@ -11,24 +11,11 @@
 # lima-rke2       Ready    control-plane,etcd,master   68s   v1.27.3+rke2r1
 #
 # For more details of RKE2, please refer to https://docs.rke2.io/
-#
-# This template requires Lima v0.7.0 or later.
 
+minimumLimaVersion: 1.1.0
+
+base: template://_images/ubuntu-lts
 
-images:
-# Try to use release-yyyyMMdd image if available. Note that release-yyyyMMdd will be removed after several months.
-- location: "https://cloud-images.ubuntu.com/releases/noble/release-20250313/ubuntu-24.04-server-cloudimg-amd64.img"
-  arch: "x86_64"
-  digest: "sha256:eacac65efe9e9bae0cbcb3f9d5c2b5e8c5313fa78a3bc401c3fb28b2d48cefc0"
-- location: "https://cloud-images.ubuntu.com/releases/noble/release-20250313/ubuntu-24.04-server-cloudimg-arm64.img"
-  arch: "aarch64"
-  digest: "sha256:103f31c5a5b7f031a60ce3555c8fbd56317fd8ffbaaa7e17002879e6157d546d"
-# Fallback to the latest release image.
-# Hint: run `limactl prune` to invalidate the cache
-- location: "https://cloud-images.ubuntu.com/releases/noble/release/ubuntu-24.04-server-cloudimg-amd64.img"
-  arch: "x86_64"
-- location: "https://cloud-images.ubuntu.com/releases/noble/release/ubuntu-24.04-server-cloudimg-arm64.img"
-  arch: "aarch64"
 # Mounts are disabled in this template, but can be enabled optionally.
 mounts: []
 
diff --git a/templates/experimental/u7s.yaml b/templates/experimental/u7s.yaml
index e0281345..17db4d35 100644
--- a/templates/experimental/u7s.yaml
+++ b/templates/experimental/u7s.yaml
@@ -10,21 +10,10 @@
 # NAME           STATUS   ROLES           AGE   VERSION
 # u7s-lima-u7s   Ready    control-plane   33s   v1.28.0
 
-# This template requires Lima v0.8.0 or later
-images:
-# Try to use release-yyyyMMdd image if available. Note that release-yyyyMMdd will be removed after several months.
-- location: "https://cloud-images.ubuntu.com/releases/noble/release-20250313/ubuntu-24.04-server-cloudimg-amd64.img"
-  arch: "x86_64"
-  digest: "sha256:eacac65efe9e9bae0cbcb3f9d5c2b5e8c5313fa78a3bc401c3fb28b2d48cefc0"
-- location: "https://cloud-images.ubuntu.com/releases/noble/release-20250313/ubuntu-24.04-server-cloudimg-arm64.img"
-  arch: "aarch64"
-  digest: "sha256:103f31c5a5b7f031a60ce3555c8fbd56317fd8ffbaaa7e17002879e6157d546d"
-# Fallback to the latest release image.
-# Hint: run `limactl prune` to invalidate the cache
-- location: "https://cloud-images.ubuntu.com/releases/noble/release/ubuntu-24.04-server-cloudimg-amd64.img"
-  arch: "x86_64"
-- location: "https://cloud-images.ubuntu.com/releases/noble/release/ubuntu-24.04-server-cloudimg-arm64.img"
-  arch: "aarch64"
+minimumLimaVersion: 1.1.0
+
+base: template://_images/ubuntu-lts
+
 # Mounts are disabled in this template, but can be enabled optionally.
 mounts: []
 # containerd is managed by Docker, not by Lima, so the values are set to false here.
diff --git a/templates/experimental/vnc.yaml b/templates/experimental/vnc.yaml
index fd3f2faf..c04a51d9 100644
--- a/templates/experimental/vnc.yaml
+++ b/templates/experimental/vnc.yaml
@@ -1,23 +1,10 @@
 # A template to run ubuntu using display: vnc
-# This template requires Lima v0.20.0 or later.
-images:
-# Try to use release-yyyyMMdd image if available. Note that release-yyyyMMdd will be removed after several months.
-- location: "https://cloud-images.ubuntu.com/releases/noble/release-20250313/ubuntu-24.04-server-cloudimg-amd64.img"
-  arch: "x86_64"
-  digest: "sha256:eacac65efe9e9bae0cbcb3f9d5c2b5e8c5313fa78a3bc401c3fb28b2d48cefc0"
-- location: "https://cloud-images.ubuntu.com/releases/noble/release-20250313/ubuntu-24.04-server-cloudimg-arm64.img"
-  arch: "aarch64"
-  digest: "sha256:103f31c5a5b7f031a60ce3555c8fbd56317fd8ffbaaa7e17002879e6157d546d"
-# Fallback to the latest release image.
-# Hint: run `limactl prune` to invalidate the cache
-- location: "https://cloud-images.ubuntu.com/releases/noble/release/ubuntu-24.04-server-cloudimg-amd64.img"
-  arch: "x86_64"
-- location: "https://cloud-images.ubuntu.com/releases/noble/release/ubuntu-24.04-server-cloudimg-arm64.img"
-  arch: "aarch64"
-mounts:
-- location: "~"
-- location: "/tmp/lima"
-  writable: true
+
+minimumLimaVersion: 1.1.0
+
+base:
+- template://_images/ubuntu-lts
+- template://_default/mounts
 
 vmType: "qemu"
 video:
diff --git a/templates/faasd.yaml b/templates/faasd.yaml
index 5667c97d..219ab260 100644
--- a/templates/faasd.yaml
+++ b/templates/faasd.yaml
@@ -2,8 +2,6 @@
 #
 # It can be accessed from the host by authenticating with faas-cli;
 # the ports are already forwarded automatically by lima.
-#
-# This template requires Lima v0.7.0 or later.
 
 message: |
   # Get the faas-cli from one of following sources:
@@ -24,20 +22,10 @@ message: |
   faas-cli store deploy NodeInfo
   ------
 
-images:
-# Try to use release-yyyyMMdd image if available. Note that release-yyyyMMdd will be removed after several months.
-- location: "https://cloud-images.ubuntu.com/releases/noble/release-20250313/ubuntu-24.04-server-cloudimg-amd64.img"
-  arch: "x86_64"
-  digest: "sha256:eacac65efe9e9bae0cbcb3f9d5c2b5e8c5313fa78a3bc401c3fb28b2d48cefc0"
-- location: "https://cloud-images.ubuntu.com/releases/noble/release-20250313/ubuntu-24.04-server-cloudimg-arm64.img"
-  arch: "aarch64"
-  digest: "sha256:103f31c5a5b7f031a60ce3555c8fbd56317fd8ffbaaa7e17002879e6157d546d"
-# Fallback to the latest release image.
-# Hint: run `limactl prune` to invalidate the cache
-- location: "https://cloud-images.ubuntu.com/releases/noble/release/ubuntu-24.04-server-cloudimg-amd64.img"
-  arch: "x86_64"
-- location: "https://cloud-images.ubuntu.com/releases/noble/release/ubuntu-24.04-server-cloudimg-arm64.img"
-  arch: "aarch64"
+minimumLimaVersion: 1.1.0
+
+base: template://_images/ubuntu-lts
+
 # Mounts are disabled in this template, but can be enabled optionally.
 mounts: []
 
diff --git a/templates/fedora-41.yaml b/templates/fedora-41.yaml
index e344c6e2..022fc4d0 100644
--- a/templates/fedora-41.yaml
+++ b/templates/fedora-41.yaml
@@ -1,16 +1,5 @@
-# This template requires Lima v0.7.0 or later.
-images:
-- location: "https://download.fedoraproject.org/pub/fedora/linux/releases/41/Cloud/x86_64/images/Fedora-Cloud-Base-Generic-41-1.4.x86_64.qcow2"
-  arch: "x86_64"
-  digest: "sha256:6205ae0c524b4d1816dbd3573ce29b5c44ed26c9fbc874fbe48c41c89dd0bac2"
-- location: "https://download.fedoraproject.org/pub/fedora/linux/releases/41/Cloud/aarch64/images/Fedora-Cloud-Base-Generic-41-1.4.aarch64.qcow2"
-  arch: "aarch64"
-  digest: "sha256:085883b42c7e3b980e366a1fe006cd0ff15877f7e6e984426f3c6c67c7cc2faa"
-mounts:
-- location: "~"
-- location: "/tmp/lima"
-  writable: true
+minimumLimaVersion: 1.1.0
 
-# 9p is broken in Linux v6.9, v6.10, and v6.11 (used by Fedora 41).
-# The issue was fixed in Linux v6.12-rc5 (https://github.com/torvalds/linux/commit/be2ca38).
-mountTypesUnsupported: ["9p"]
+base:
+- template://_images/fedora-41
+- template://_default/mounts
diff --git a/templates/fedora-42.yaml b/templates/fedora-42.yaml
index 96ad4645..003ba9ba 100644
--- a/templates/fedora-42.yaml
+++ b/templates/fedora-42.yaml
@@ -1,16 +1,5 @@
-# This template requires Lima v0.7.0 or later.
-images:
-- location: "https://download.fedoraproject.org/pub/fedora/linux/releases/42/Cloud/x86_64/images/Fedora-Cloud-Base-Generic-42-1.1.x86_64.qcow2"
-  arch: "x86_64"
-  digest: "sha256:e401a4db2e5e04d1967b6729774faa96da629bcf3ba90b67d8d9cce9906bec0f"
-- location: "https://download.fedoraproject.org/pub/fedora/linux/releases/42/Cloud/aarch64/images/Fedora-Cloud-Base-Generic-42-1.1.aarch64.qcow2"
-  arch: "aarch64"
-  digest: "sha256:e10658419a8d50231037dc781c3155aa94180a8c7a74e5cac2a6b09eaa9342b7"
-mounts:
-- location: "~"
-- location: "/tmp/lima"
-  writable: true
+minimumLimaVersion: 1.1.0
 
-# # NOTE: Intel Mac requires setting vmType to qemu
-# # https://github.com/lima-vm/lima/issues/3334
-# vmType: qemu
+base:
+- template://_images/fedora-42
+- template://_default/mounts
diff --git a/templates/k3s.yaml b/templates/k3s.yaml
index 4057bf84..9b84d591 100644
--- a/templates/k3s.yaml
+++ b/templates/k3s.yaml
@@ -9,31 +9,17 @@
 # $ kubectl get no
 # NAME       STATUS   ROLES                  AGE   VERSION
 # lima-k3s   Ready    control-plane,master   69s   v1.21.1+k3s1
-#
-# This template requires Lima v0.7.0 or later.
 
-images:
-# Try to use release-yyyyMMdd image if available. Note that release-yyyyMMdd will be removed after several months.
-- location: "https://cloud-images.ubuntu.com/releases/noble/release-20250313/ubuntu-24.04-server-cloudimg-amd64.img"
-  arch: "x86_64"
-  digest: "sha256:eacac65efe9e9bae0cbcb3f9d5c2b5e8c5313fa78a3bc401c3fb28b2d48cefc0"
-- location: "https://cloud-images.ubuntu.com/releases/noble/release-20250313/ubuntu-24.04-server-cloudimg-arm64.img"
-  arch: "aarch64"
-  digest: "sha256:103f31c5a5b7f031a60ce3555c8fbd56317fd8ffbaaa7e17002879e6157d546d"
-# Fallback to the latest release image.
-# Hint: run `limactl prune` to invalidate the cache
-- location: "https://cloud-images.ubuntu.com/releases/noble/release/ubuntu-24.04-server-cloudimg-amd64.img"
-  arch: "x86_64"
-- location: "https://cloud-images.ubuntu.com/releases/noble/release/ubuntu-24.04-server-cloudimg-arm64.img"
-  arch: "aarch64"
+minimumLimaVersion: 1.1.0
+
+base: template://_images/ubuntu-lts
+
 # Mounts are disabled in this template, but can be enabled optionally.
 mounts: []
-
 # containerd is managed by k3s, not by Lima, so the values are set to false here.
 containerd:
   system: false
   user: false
-
 provision:
 - mode: system
   script: |
diff --git a/templates/k8s.yaml b/templates/k8s.yaml
index ed588bc6..3bcc6c9a 100644
--- a/templates/k8s.yaml
+++ b/templates/k8s.yaml
@@ -10,21 +10,10 @@
 # NAME       STATUS   ROLES                  AGE   VERSION
 # lima-k8s   Ready    control-plane,master   44s   v1.22.3
 
-# This template requires Lima v0.20.0 or later.
-images:
-# Try to use release-yyyyMMdd image if available. Note that release-yyyyMMdd will be removed after several months.
-- location: "https://cloud-images.ubuntu.com/releases/noble/release-20250313/ubuntu-24.04-server-cloudimg-amd64.img"
-  arch: "x86_64"
-  digest: "sha256:eacac65efe9e9bae0cbcb3f9d5c2b5e8c5313fa78a3bc401c3fb28b2d48cefc0"
-- location: "https://cloud-images.ubuntu.com/releases/noble/release-20250313/ubuntu-24.04-server-cloudimg-arm64.img"
-  arch: "aarch64"
-  digest: "sha256:103f31c5a5b7f031a60ce3555c8fbd56317fd8ffbaaa7e17002879e6157d546d"
-# Fallback to the latest release image.
-# Hint: run `limactl prune` to invalidate the cache
-- location: "https://cloud-images.ubuntu.com/releases/noble/release/ubuntu-24.04-server-cloudimg-amd64.img"
-  arch: "x86_64"
-- location: "https://cloud-images.ubuntu.com/releases/noble/release/ubuntu-24.04-server-cloudimg-arm64.img"
-  arch: "aarch64"
+minimumLimaVersion: 1.1.0
+
+base: template://_images/ubuntu-lts
+
 # Mounts are disabled in this template, but can be enabled optionally.
 mounts: []
 containerd:
diff --git a/templates/opensuse-leap.yaml b/templates/opensuse-leap.yaml
index 475db8a8..8c460bfe 100644
--- a/templates/opensuse-leap.yaml
+++ b/templates/opensuse-leap.yaml
@@ -1,15 +1,5 @@
-# This template requires Lima v0.7.0 or later
-images:
-# Hint: run `limactl prune` to invalidate the "Current" cache
-- location: "https://download.opensuse.org/distribution/leap/15.6/appliances/openSUSE-Leap-15.6-Minimal-VM.x86_64-Cloud.qcow2"
-  arch: "x86_64"
-- location: "https://download.opensuse.org/distribution/leap/15.6/appliances/openSUSE-Leap-15.6-Minimal-VM.aarch64-Cloud.qcow2"
-  arch: "aarch64"
-# Hint: to allow 9p and virtiofs, replace the `kernel-default-base` package with `kernel-default` and reboot the VM.
-# https://github.com/lima-vm/lima/issues/3055
-mountType: "reverse-sshfs"
-mountTypesUnsupported: ["9p", "virtiofs"]
-mounts:
-- location: "~"
-- location: "/tmp/lima"
-  writable: true
+minimumLimaVersion: 1.1.0
+
+base:
+- template://_images/opensuse-leap
+- template://_default/mounts
diff --git a/templates/oraclelinux-8.yaml b/templates/oraclelinux-8.yaml
index 74731ac9..be7b6ce9 100644
--- a/templates/oraclelinux-8.yaml
+++ b/templates/oraclelinux-8.yaml
@@ -1,26 +1,5 @@
-# This template requires Lima v0.9.0 or later.
-# Oracle image license: https://www.oracle.com/downloads/licenses/oracle-linux-license.html
-# Image source: https://yum.oracle.com/oracle-linux-templates.html
+minimumLimaVersion: 1.1.0
 
-# NOTE: EL8-based distros are known not to work on M1 chips: https://github.com/lima-vm/lima/issues/841
-# EL9-based distros are known to work.
-
-images:
-- location: "https://yum.oracle.com/templates/OracleLinux/OL8/u10/x86_64/OL8U10_x86_64-kvm-b237.qcow2"
-  arch: "x86_64"
-  digest: "sha256:53a5eee27c59f335ba1bdb0afc2c3273895f128dd238b51a78f46ad515cbc662"
-- location: "https://yum.oracle.com/templates/OracleLinux/OL8/u10/aarch64/OL8U10_aarch64-kvm-cloud-b100.qcow2"
-  arch: "aarch64"
-  digest: "sha256:def7b8055e275507a593f07dc6076a2adc5967af046c003072b479e69f25f407"
-mountTypesUnsupported: ["9p"]
-mounts:
-- location: "~"
-- location: "/tmp/lima"
-  writable: true
-firmware:
-  # Oracle Linux 8 still requires legacyBIOS, while AlmaLinux 8 and Rocky Linux 8 do not.
-  legacyBIOS: true
-cpuType:
-  # Workaround for "vmx_write_mem: mmu_gva_to_gpa XXXXXXXXXXXXXXXX failed" on Intel Mac
-  # https://bugs.launchpad.net/qemu/+bug/1838390
-  x86_64: "Haswell-v4"
+base:
+- template://_images/oraclelinux-8
+- template://_default/mounts
diff --git a/templates/oraclelinux-9.yaml b/templates/oraclelinux-9.yaml
index 4db5d177..a00338f1 100644
--- a/templates/oraclelinux-9.yaml
+++ b/templates/oraclelinux-9.yaml
@@ -1,19 +1,5 @@
-# This template requires Lima v0.11.3 or later.
-# Oracle image license: https://www.oracle.com/downloads/licenses/oracle-linux-license.html
-# Image source: https://yum.oracle.com/oracle-linux-templates.html
+minimumLimaVersion: 1.1.0
 
-images:
-- location: "https://yum.oracle.com/templates/OracleLinux/OL9/u5/x86_64/OL9U5_x86_64-kvm-b253.qcow2"
-  arch: "x86_64"
-  digest: "sha256:3b00bbbefc8e78dd28d9f538834fb9e2a03d5ccdc2cadf2ffd0036c0a8f02021"
-- location: "https://yum.oracle.com/templates/OracleLinux/OL9/u5/aarch64/OL9U5_aarch64-kvm-cloud-b117.qcow2"
-  arch: "aarch64"
-  digest: "sha256:6b62b633eb66cd1769015c25699d4d5f15c41c8fe5ef6ec3e81f0f2d5ed9e4d4"
-mountTypesUnsupported: ["9p"]
-mounts:
-- location: "~"
-- location: "/tmp/lima"
-  writable: true
-firmware:
-  # Oracle Linux 9 still requires legacyBIOS, while AlmaLinux 9 and Rocky Linux 9 do not.
-  legacyBIOS: true
+base:
+- template://_images/oraclelinux-9
+- template://_default/mounts
diff --git a/templates/podman-rootful.yaml b/templates/podman-rootful.yaml
index f6955587..c0dcebe9 100644
--- a/templates/podman-rootful.yaml
+++ b/templates/podman-rootful.yaml
@@ -10,19 +10,12 @@
 # $ export DOCKER_HOST=$(limactl list podman-rootful --format 'unix://{{.Dir}}/sock/podman.sock')
 # $ docker ...
 
-# This template requires Lima v0.20.0 or later
-images:
-- location: "https://download.fedoraproject.org/pub/fedora/linux/releases/41/Cloud/x86_64/images/Fedora-Cloud-Base-Generic-41-1.4.x86_64.qcow2"
-  arch: "x86_64"
-  digest: "sha256:6205ae0c524b4d1816dbd3573ce29b5c44ed26c9fbc874fbe48c41c89dd0bac2"
-- location: "https://download.fedoraproject.org/pub/fedora/linux/releases/41/Cloud/aarch64/images/Fedora-Cloud-Base-Generic-41-1.4.aarch64.qcow2"
-  arch: "aarch64"
-  digest: "sha256:085883b42c7e3b980e366a1fe006cd0ff15877f7e6e984426f3c6c67c7cc2faa"
+minimumLimaVersion: 1.1.0
+
+base:
+- template://_images/fedora-41
+- template://_default/mounts
 
-mounts:
-- location: "~"
-- location: "/tmp/lima"
-  writable: true
 containerd:
   system: false
   user: false
@@ -68,7 +61,3 @@ message: |
   podman system connection default lima-{{.Name}}
   podman{{if eq .HostOS "linux"}} --remote{{end}} run quay.io/podman/hello
   ------
-
-# 9p is broken in Linux v6.9, v6.10, and v6.11 (used by Fedora 41).
-# The issue was fixed in Linux v6.12-rc5 (https://github.com/torvalds/linux/commit/be2ca38).
-mountTypesUnsupported: ["9p"]
diff --git a/templates/podman.yaml b/templates/podman.yaml
index dd0b7f50..e50cf370 100644
--- a/templates/podman.yaml
+++ b/templates/podman.yaml
@@ -10,19 +10,12 @@
 # $ export DOCKER_HOST=$(limactl list podman --format 'unix://{{.Dir}}/sock/podman.sock')
 # $ docker ...
 
-# This template requires Lima v0.8.0 or later
-images:
-- location: "https://download.fedoraproject.org/pub/fedora/linux/releases/41/Cloud/x86_64/images/Fedora-Cloud-Base-Generic-41-1.4.x86_64.qcow2"
-  arch: "x86_64"
-  digest: "sha256:6205ae0c524b4d1816dbd3573ce29b5c44ed26c9fbc874fbe48c41c89dd0bac2"
-- location: "https://download.fedoraproject.org/pub/fedora/linux/releases/41/Cloud/aarch64/images/Fedora-Cloud-Base-Generic-41-1.4.aarch64.qcow2"
-  arch: "aarch64"
-  digest: "sha256:085883b42c7e3b980e366a1fe006cd0ff15877f7e6e984426f3c6c67c7cc2faa"
+minimumLimaVersion: 1.1.0
+
+base:
+- template://_images/fedora-41
+- template://_default/mounts
 
-mounts:
-- location: "~"
-- location: "/tmp/lima"
-  writable: true
 containerd:
   system: false
   user: false
@@ -57,7 +50,3 @@ message: |
   podman system connection default lima-{{.Name}}
   podman{{if eq .HostOS "linux"}} --remote{{end}} run quay.io/podman/hello
   ------
-
-# 9p is broken in Linux v6.9, v6.10, and v6.11 (used by Fedora 41).
-# The issue was fixed in Linux v6.12-rc5 (https://github.com/torvalds/linux/commit/be2ca38).
-mountTypesUnsupported: ["9p"]
diff --git a/templates/rocky-8.yaml b/templates/rocky-8.yaml
index e2ad6e66..e69c9b4f 100644
--- a/templates/rocky-8.yaml
+++ b/templates/rocky-8.yaml
@@ -1,27 +1,5 @@
-# This template requires Lima v0.8.3 or later.
+minimumLimaVersion: 1.1.0
 
-# NOTE: EL8-based distros are known not to work on M1 chips: https://github.com/lima-vm/lima/issues/841
-# EL9-based distros are known to work.
-
-images:
-- location: "https://dl.rockylinux.org/pub/rocky/8.10/images/x86_64/Rocky-8-GenericCloud-Base-8.10-20240528.0.x86_64.qcow2"
-  arch: "x86_64"
-  digest: "sha256:e56066c58606191e96184de9a9183a3af33c59bcbd8740d8b10ca054a7a89c14"
-- location: "https://dl.rockylinux.org/pub/rocky/8.10/images/aarch64/Rocky-8-GenericCloud-Base-8.10-20240528.0.aarch64.qcow2"
-  arch: "aarch64"
-  digest: "sha256:946b5b9845aa5e3ed98f1bc6ee9873201712a2aef01b87731aed16857e0ca13f"
-# Fallback to the latest release image.
-# Hint: run `limactl prune` to invalidate the cache
-- location: "https://dl.rockylinux.org/pub/rocky/8/images/x86_64/Rocky-8-GenericCloud.latest.x86_64.qcow2"
-  arch: "x86_64"
-- location: "https://dl.rockylinux.org/pub/rocky/8/images/aarch64/Rocky-8-GenericCloud.latest.aarch64.qcow2"
-  arch: "aarch64"
-mountTypesUnsupported: ["9p"]
-mounts:
-- location: "~"
-- location: "/tmp/lima"
-  writable: true
-cpuType:
-  # Workaround for "vmx_write_mem: mmu_gva_to_gpa XXXXXXXXXXXXXXXX failed" on Intel Mac
-  # https://bugs.launchpad.net/qemu/+bug/1838390
-  x86_64: "Haswell-v4"
+base:
+- template://_images/rocky-8
+- template://_default/mounts
diff --git a/templates/rocky-9.yaml b/templates/rocky-9.yaml
index 2d8fb19a..548bb301 100644
--- a/templates/rocky-9.yaml
+++ b/templates/rocky-9.yaml
@@ -1,21 +1,5 @@
-# This template requires Lima v0.11.1 or later.
+minimumLimaVersion: 1.1.0
 
-images:
-- location: "https://dl.rockylinux.org/pub/rocky/9.5/images/x86_64/Rocky-9-GenericCloud-Base-9.5-20241118.0.x86_64.qcow2"
-  arch: "x86_64"
-  digest: "sha256:069493fdc807300a22176540e9171fcff2227a92b40a7985a0c1c9e21aeebf57"
-# No 20240609.1 for aarch64
-- location: "https://dl.rockylinux.org/pub/rocky/9.5/images/aarch64/Rocky-9-GenericCloud-Base-9.5-20241118.0.aarch64.qcow2"
-  arch: "aarch64"
-  digest: "sha256:5443bcc0507fadc3d7bd3e8d266135ab8db6966c703216933f824164fd3252f1"
-# Fallback to the latest release image.
-# Hint: run `limactl prune` to invalidate the cache
-- location: "https://dl.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud.latest.x86_64.qcow2"
-  arch: "x86_64"
-- location: "https://dl.rockylinux.org/pub/rocky/9/images/aarch64/Rocky-9-GenericCloud.latest.aarch64.qcow2"
-  arch: "aarch64"
-mountTypesUnsupported: ["9p"]
-mounts:
-- location: "~"
-- location: "/tmp/lima"
-  writable: true
+base:
+- template://_images/rocky-9
+- template://_default/mounts
diff --git a/templates/ubuntu-20.04.yaml b/templates/ubuntu-20.04.yaml
index ccc9d5e2..c4e363c2 100644
--- a/templates/ubuntu-20.04.yaml
+++ b/templates/ubuntu-20.04.yaml
@@ -1,30 +1,5 @@
-# This template requires Lima v0.7.0 or later.
-images:
-# Try to use release-yyyyMMdd image if available. Note that release-yyyyMMdd will be removed after several months.
-- location: "https://cloud-images.ubuntu.com/releases/focal/release-20250303/ubuntu-20.04-server-cloudimg-amd64.img"
-  arch: "x86_64"
-  digest: "sha256:77a68bd67a78754bafb4a709d1af27e9a6ccf5dc9753302c6e6407c27d4f7fa0"
-- location: "https://cloud-images.ubuntu.com/releases/focal/release-20250303/ubuntu-20.04-server-cloudimg-arm64.img"
-  arch: "aarch64"
-  digest: "sha256:7ca528c6d6a28fb631760a06e5b2462f5d2a64fdf136c810d6083bf0b0bf4a1f"
-- location: "https://cloud-images.ubuntu.com/releases/focal/release-20250303/ubuntu-20.04-server-cloudimg-armhf.img"
-  arch: "armv7l"
-  digest: "sha256:b3eea15775504e94d145ba31a9171dae213c8b253cc5e99d8d4a9994d9902a24"
-- location: "https://cloud-images.ubuntu.com/releases/focal/release-20250303/ubuntu-20.04-server-cloudimg-s390x.img"
-  arch: "s390x"
-  digest: "sha256:de1c7370d59563caf29d0b6a9af43d5ab44e57e23fbda54d4b12b26bcbf6c7cf"
-# Fallback to the latest release image.
-# Hint: run `limactl prune` to invalidate the cache
-- location: "https://cloud-images.ubuntu.com/releases/focal/release/ubuntu-20.04-server-cloudimg-amd64.img"
-  arch: "x86_64"
-- location: "https://cloud-images.ubuntu.com/releases/focal/release/ubuntu-20.04-server-cloudimg-arm64.img"
-  arch: "aarch64"
-- location: "https://cloud-images.ubuntu.com/releases/focal/release/ubuntu-20.04-server-cloudimg-armhf.img"
-  arch: "armv7l"
-- location: "https://cloud-images.ubuntu.com/releases/focal/release/ubuntu-20.04-server-cloudimg-s390x.img"
-  arch: "s390x"
+minimumLimaVersion: 1.1.0
 
-mounts:
-- location: "~"
-- location: "/tmp/lima"
-  writable: true
+base:
+- template://_images/ubuntu-20.04
+- template://_default/mounts
diff --git a/templates/ubuntu-22.04.yaml b/templates/ubuntu-22.04.yaml
index 293db989..2974fd0c 100644
--- a/templates/ubuntu-22.04.yaml
+++ b/templates/ubuntu-22.04.yaml
@@ -1,34 +1,5 @@
-minimumLimaVersion: "1.0.0"
-images:
-# Try to use release-yyyyMMdd image if available. Note that release-yyyyMMdd will be removed after several months.
-- location: "https://cloud-images.ubuntu.com/releases/jammy/release-20250305/ubuntu-22.04-server-cloudimg-amd64.img"
-  arch: "x86_64"
-  digest: "sha256:eb4707ac0dec191347bb5123ad2fd2b372077a66e5300ddb4c0d16444f619fa6"
-- location: "https://cloud-images.ubuntu.com/releases/jammy/release-20250305/ubuntu-22.04-server-cloudimg-arm64.img"
-  arch: "aarch64"
-  digest: "sha256:46113bedf45e3429bc7e0a74e9bca0a75768c595f61ee45d9cd0141838bda2ca"
-- location: "https://cloud-images.ubuntu.com/releases/jammy/release-20250305/ubuntu-22.04-server-cloudimg-riscv64.img"
-  arch: "riscv64"
-  digest: "sha256:0cede637b61ff3575a7648414573d1ee31e36b0d014d3755fb84c7a32bff0bf1"
-- location: "https://cloud-images.ubuntu.com/releases/jammy/release-20250305/ubuntu-22.04-server-cloudimg-armhf.img"
-  arch: "armv7l"
-  digest: "sha256:852da1f71a43c7e4a782fb2ae93379eb5810cdd445570f807ede118926a11d06"
-- location: "https://cloud-images.ubuntu.com/releases/jammy/release-20250305/ubuntu-22.04-server-cloudimg-s390x.img"
-  arch: "s390x"
-  digest: "sha256:5caf61c680e6aa0b82265d93e953a6b49a5f7961ee2f5cedf8070b6efc9a2339"
-# Fallback to the latest release image.
-# Hint: run `limactl prune` to invalidate the cache
-- location: "https://cloud-images.ubuntu.com/releases/jammy/release/ubuntu-22.04-server-cloudimg-amd64.img"
-  arch: "x86_64"
-- location: "https://cloud-images.ubuntu.com/releases/jammy/release/ubuntu-22.04-server-cloudimg-arm64.img"
-  arch: "aarch64"
-- location: "https://cloud-images.ubuntu.com/releases/jammy/release/ubuntu-22.04-server-cloudimg-riscv64.img"
-  arch: "riscv64"
-- location: "https://cloud-images.ubuntu.com/releases/jammy/release/ubuntu-22.04-server-cloudimg-armhf.img"
-  arch: "armv7l"
-- location: "https://cloud-images.ubuntu.com/releases/jammy/release/ubuntu-22.04-server-cloudimg-s390x.img"
-  arch: "s390x"
-mounts:
-- location: "~"
-- location: "/tmp/lima"
-  writable: true
+minimumLimaVersion: 1.1.0
+
+base:
+- template://_images/ubuntu-22.04
+- template://_default/mounts
diff --git a/templates/ubuntu-24.04.yaml b/templates/ubuntu-24.04.yaml
index 4f4d3abb..396fd228 100644
--- a/templates/ubuntu-24.04.yaml
+++ b/templates/ubuntu-24.04.yaml
@@ -1,34 +1,5 @@
-minimumLimaVersion: "1.0.0"
-images:
-# Try to use release-yyyyMMdd image if available. Note that release-yyyyMMdd will be removed after several months.
-- location: "https://cloud-images.ubuntu.com/releases/noble/release-20250313/ubuntu-24.04-server-cloudimg-amd64.img"
-  arch: "x86_64"
-  digest: "sha256:eacac65efe9e9bae0cbcb3f9d5c2b5e8c5313fa78a3bc401c3fb28b2d48cefc0"
-- location: "https://cloud-images.ubuntu.com/releases/noble/release-20250313/ubuntu-24.04-server-cloudimg-arm64.img"
-  arch: "aarch64"
-  digest: "sha256:103f31c5a5b7f031a60ce3555c8fbd56317fd8ffbaaa7e17002879e6157d546d"
-- location: "https://cloud-images.ubuntu.com/releases/noble/release-20250313/ubuntu-24.04-server-cloudimg-riscv64.img"
-  arch: "riscv64"
-  digest: "sha256:bfd6a91a7ee84e26f33ce6b2df2e415b038214db67f009206b40cf2e9158fc3f"
-- location: "https://cloud-images.ubuntu.com/releases/noble/release-20250313/ubuntu-24.04-server-cloudimg-armhf.img"
-  arch: "armv7l"
-  digest: "sha256:0b862b6a4811f23c76e292ffe5a7cd90a4f03db9f48f664a2a943b02f83621c3"
-- location: "https://cloud-images.ubuntu.com/releases/noble/release-20250313/ubuntu-24.04-server-cloudimg-s390x.img"
-  arch: "s390x"
-  digest: "sha256:7e7080ed67f148373ac9645f48fc3f4206fc1e8b517c316f3fc03fca9c04713c"
-# Fallback to the latest release image.
-# Hint: run `limactl prune` to invalidate the cache
-- location: "https://cloud-images.ubuntu.com/releases/noble/release/ubuntu-24.04-server-cloudimg-amd64.img"
-  arch: "x86_64"
-- location: "https://cloud-images.ubuntu.com/releases/noble/release/ubuntu-24.04-server-cloudimg-arm64.img"
-  arch: "aarch64"
-- location: "https://cloud-images.ubuntu.com/releases/noble/release/ubuntu-24.04-server-cloudimg-riscv64.img"
-  arch: "riscv64"
-- location: "https://cloud-images.ubuntu.com/releases/noble/release/ubuntu-24.04-server-cloudimg-armhf.img"
-  arch: "armv7l"
-- location: "https://cloud-images.ubuntu.com/releases/noble/release/ubuntu-24.04-server-cloudimg-s390x.img"
-  arch: "s390x"
-mounts:
-- location: "~"
-- location: "/tmp/lima"
-  writable: true
+minimumLimaVersion: 1.1.0
+
+base:
+- template://_images/ubuntu-24.04
+- template://_default/mounts
diff --git a/templates/ubuntu-24.10.yaml b/templates/ubuntu-24.10.yaml
index c4e3527d..1aa8769f 100644
--- a/templates/ubuntu-24.10.yaml
+++ b/templates/ubuntu-24.10.yaml
@@ -1,38 +1,5 @@
-minimumLimaVersion: "1.0.0"
-images:
-# Try to use release-yyyyMMdd image if available. Note that release-yyyyMMdd will be removed after several months.
-- location: "https://cloud-images.ubuntu.com/releases/oracular/release-20250305/ubuntu-24.10-server-cloudimg-amd64.img"
-  arch: "x86_64"
-  digest: "sha256:c2c3ed89097c5f5c90ebbe45216d1569e3ea2d3c8d0993eeae74f859f6467cdb"
-- location: "https://cloud-images.ubuntu.com/releases/oracular/release-20250305/ubuntu-24.10-server-cloudimg-arm64.img"
-  arch: "aarch64"
-  digest: "sha256:9d8e0c98858d53866117d5c701a554a9d2434bedffec1c0ab7253691bfd2c70e"
-- location: "https://cloud-images.ubuntu.com/releases/oracular/release-20250305/ubuntu-24.10-server-cloudimg-riscv64.img"
-  arch: "riscv64"
-  digest: "sha256:be6109cfed964a2b745330681f7ec5b9ddc45bb180f41837b6e3969b4be9e8b5"
-- location: "https://cloud-images.ubuntu.com/releases/oracular/release-20250305/ubuntu-24.10-server-cloudimg-armhf.img"
-  arch: "armv7l"
-  digest: "sha256:8f3a22d7392512b56ffbcbf30d4f5df0805b7d515f08fb86c5a8f87405ca7f02"
-- location: "https://cloud-images.ubuntu.com/releases/oracular/release-20250305/ubuntu-24.10-server-cloudimg-s390x.img"
-  arch: "s390x"
-  digest: "sha256:98b19fee0742b4cfccbfcc72fa82f274355f01dd0e5216263a9988e79e6d03ab"
-# Fallback to the latest release image.
-# Hint: run `limactl prune` to invalidate the cache
-- location: "https://cloud-images.ubuntu.com/releases/oracular/release/ubuntu-24.10-server-cloudimg-amd64.img"
-  arch: "x86_64"
-- location: "https://cloud-images.ubuntu.com/releases/oracular/release/ubuntu-24.10-server-cloudimg-arm64.img"
-  arch: "aarch64"
-- location: "https://cloud-images.ubuntu.com/releases/oracular/release/ubuntu-24.10-server-cloudimg-riscv64.img"
-  arch: "riscv64"
-- location: "https://cloud-images.ubuntu.com/releases/oracular/release/ubuntu-24.10-server-cloudimg-armhf.img"
-  arch: "armv7l"
-- location: "https://cloud-images.ubuntu.com/releases/oracular/release/ubuntu-24.10-server-cloudimg-s390x.img"
-  arch: "s390x"
-mounts:
-- location: "~"
-- location: "/tmp/lima"
-  writable: true
+minimumLimaVersion: 1.1.0
 
-# 9p is broken in Linux v6.9, v6.10, and v6.11 (used by Ubuntu 24.10).
-# The issue was fixed in Linux v6.12-rc5 (https://github.com/torvalds/linux/commit/be2ca38).
-mountTypesUnsupported: ["9p"]
+base:
+- template://_images/ubuntu-24.10
+- template://_default/mounts
diff --git a/templates/ubuntu-25.04.yaml b/templates/ubuntu-25.04.yaml
index 0f339256..67a5ec2a 100644
--- a/templates/ubuntu-25.04.yaml
+++ b/templates/ubuntu-25.04.yaml
@@ -1,38 +1,5 @@
-# This template requires Lima v0.7.0 or later.
-images:
-# Try to use release-yyyyMMdd image if available. Note that release-yyyyMMdd will be removed after several months.
-- location: "https://cloud-images.ubuntu.com/releases/plucky/release-20250415/ubuntu-25.04-server-cloudimg-amd64.img"
-  arch: "x86_64"
-  digest: "sha256:6fb0299c53b8872c51b96c54947ee25383378ed5045f2ef18c751be0cab42ecd"
-- location: "https://cloud-images.ubuntu.com/releases/plucky/release-20250415/ubuntu-25.04-server-cloudimg-arm64.img"
-  arch: "aarch64"
-  digest: "sha256:d599b0769b6df1a2c9c6a04108beaa265a354f93db15f219c820567a42231486"
-- location: "https://cloud-images.ubuntu.com/releases/plucky/release-20250415/ubuntu-25.04-server-cloudimg-riscv64.img"
-  arch: "riscv64"
-  digest: "sha256:accc86a8fea04dff4599fe776fddcaa5ae7d498cbac69a0c25d4dd0292b79b38"
-- location: "https://cloud-images.ubuntu.com/releases/plucky/release-20250415/ubuntu-25.04-server-cloudimg-armhf.img"
-  arch: "armv7l"
-  digest: "sha256:28f9959f528f3c7e172b367fdae4032a09e75b4a8499283c6c4c611d91bf9699"
-- location: "https://cloud-images.ubuntu.com/releases/plucky/release-20250415/ubuntu-25.04-server-cloudimg-s390x.img"
-  arch: "s390x"
-  digest: "sha256:0ea6c52f2bbf3d35a767f92afe8adc4a648ebf0d31a325dfb97e21be6ef20c70"
-# Fallback to the latest release image.
-# Hint: run `limactl prune` to invalidate the cache
-- location: "https://cloud-images.ubuntu.com/releases/plucky/release/ubuntu-25.04-server-cloudimg-amd64.img"
-  arch: "x86_64"
-- location: "https://cloud-images.ubuntu.com/releases/plucky/release/ubuntu-25.04-server-cloudimg-arm64.img"
-  arch: "aarch64"
-- location: "https://cloud-images.ubuntu.com/releases/plucky/release/ubuntu-25.04-server-cloudimg-riscv64.img"
-  arch: "riscv64"
-- location: "https://cloud-images.ubuntu.com/releases/plucky/release/ubuntu-25.04-server-cloudimg-armhf.img"
-  arch: "armv7l"
-- location: "https://cloud-images.ubuntu.com/releases/plucky/release/ubuntu-25.04-server-cloudimg-s390x.img"
-  arch: "s390x"
-mounts:
-- location: "~"
-- location: "/tmp/lima"
-  writable: true
+minimumLimaVersion: 1.1.0
 
-# # NOTE: Intel Mac requires setting vmType to qemu
-# # https://github.com/lima-vm/lima/issues/3334
-# vmType: qemu
+base:
+- template://_images/ubuntu-25.04
+- template://_default/mounts
diff --git a/website/content/en/docs/config/environment-variables.md b/website/content/en/docs/config/environment-variables.md
index 9d7d863e..b4d991b2 100644
--- a/website/content/en/docs/config/environment-variables.md
+++ b/website/content/en/docs/config/environment-variables.md
@@ -27,6 +27,16 @@ This page documents the environment variables used in Lima.
   lima
   ```
 
+### `LIMA_TEMPLATES_PATH`
+
+- **Description**: Specifies the directories used to resolve `template://` URLs.
+- **Default**: `/usr/local/share/lima/templates`
+- **Usage**:
+  ```sh
+  export LIMA_TEMPLATES_PATH="$HOME/.config/lima/templates:/usr/local/share/lima/templates"
+  limactl create --name my-vm template://my-distro
+  ```
+
 ### `LIMA_WORKDIR`
 
 - **Description**: Specifies the initial working directory inside the Lima instance.
diff --git a/website/content/en/docs/dev/internals.md b/website/content/en/docs/dev/internals.md
index 8e3bbe4a..19acca80 100644
--- a/website/content/en/docs/dev/internals.md
+++ b/website/content/en/docs/dev/internals.md
@@ -135,6 +135,10 @@ The directory contains the following files:
 - `$LIMA_SHELL`: `lima ...` is expanded to `limactl shell --shell ${LIMA_SHELL} ...`.
   - No default : will use the user's shell configured inside the instance
 
+- `$LIMA_TEMPLATES_PATH`: A list of directories to locate templates via
+  the `template://` schema.
+  - Default: the `/usr/local/share/lima/templates` directory.
+
 - `$LIMA_WORKDIR`: `lima ...` is expanded to `limactl shell --workdir ${LIMA_WORKDIR} ...`.
   - No default : will attempt to use the current directory from the host
 



Test patch:
diff --git a/pkg/limayaml/limayaml_test.go b/pkg/limayaml/limayaml_test.go
index 345dee54..a0320232 100644
--- a/pkg/limayaml/limayaml_test.go
+++ b/pkg/limayaml/limayaml_test.go
@@ -37,6 +37,8 @@ func TestDefaultYAML(t *testing.T) {
 	assert.NilError(t, err)
 	y.Images = nil                // remove default images
 	y.Mounts = nil                // remove default mounts
+	y.Base = nil                  // remove default base templates
+	y.MinimumLimaVersion = nil    // remove minimum Lima version
 	y.MountTypesUnsupported = nil // remove default workaround for kernel 6.9-6.11
 	t.Log(dumpJSON(t, y))
 	b, err := Marshal(&y, false)
diff --git a/pkg/limayaml/validate_test.go b/pkg/limayaml/validate_test.go
index 3a690510..7e90bc82 100644
--- a/pkg/limayaml/validate_test.go
+++ b/pkg/limayaml/validate_test.go
@@ -4,8 +4,6 @@
 package limayaml
 
 import (
-	"os"
-	"runtime"
 	"testing"
 
 	"gotest.tools/v3/assert"
@@ -18,22 +16,6 @@ func TestValidateEmpty(t *testing.T) {
 	assert.Error(t, err, "field `images` must be set")
 }
 
-// Note: can't embed symbolic links, use "os"
-
-func TestValidateDefault(t *testing.T) {
-	if runtime.GOOS == "windows" {
-		// FIXME: `assertion failed: error is not nil: field `mounts[1].location` must be an absolute path, got "/tmp/lima"`
-		t.Skip("Skipping on windows")
-	}
-
-	bytes, err := os.ReadFile("default.yaml")
-	assert.NilError(t, err)
-	y, err := Load(bytes, "default.yaml")
-	assert.NilError(t, err)
-	err = Validate(y, true)
-	assert.NilError(t, err)
-}
-
 func TestValidateProbes(t *testing.T) {
 	images := `images: [{"location": "/"}]`
 	validProbe := `probes: [{"script": "#!foo"}]`
diff --git a/pkg/templatestore/templatestore.go b/pkg/templatestore/templatestore.go
index 104d26b7..e76803b1 100644
--- a/pkg/templatestore/templatestore.go
+++ b/pkg/templatestore/templatestore.go
@@ -4,6 +4,8 @@
 package templatestore
 
 import (
+	"errors"
+	"fmt"
 	"io/fs"
 	"os"
 	"path/filepath"
@@ -20,9 +22,15 @@ type Template struct {
 }
 
 func Read(name string) ([]byte, error) {
-	dir, err := usrlocalsharelima.Dir()
-	if err != nil {
-		return nil, err
+	var pathList []string
+	if tmplPath := os.Getenv("LIMA_TEMPLATES_PATH"); tmplPath != "" {
+		pathList = strings.Split(tmplPath, string(filepath.ListSeparator))
+	} else {
+		dir, err := usrlocalsharelima.Dir()
+		if err != nil {
+			return nil, err
+		}
+		pathList = []string{filepath.Join(dir, "templates")}
 	}
 	ext := filepath.Ext(name)
 	// Append .yaml extension if name doesn't have an extension, or if it starts with a digit.
@@ -30,11 +38,16 @@ func Read(name string) ([]byte, error) {
 	if len(ext) < 2 || unicode.IsDigit(rune(ext[1])) {
 		name += ".yaml"
 	}
-	filePath, err := securejoin.SecureJoin(filepath.Join(dir, "templates"), name)
-	if err != nil {
-		return nil, err
+	for _, path := range pathList {
+		filePath, err := securejoin.SecureJoin(path, name)
+		if err != nil {
+			return nil, err
+		}
+		if b, err := os.ReadFile(filePath); !errors.Is(err, os.ErrNotExist) {
+			return b, err
+		}
 	}
-	return os.ReadFile(filePath)
+	return nil, fmt.Errorf("template %q not found", name)
 }
 
 const Default = "default"