Templates and tags
Terms
| Term | Meaning |
|---|---|
| Template | A VM that has at least one tag. In a registry, the template holds the tags for that VM. |
| Tag | A saved state of a template, such as vanilla or v1. |
| Base tag | The tag that a newer tag builds on. If you push xcode-27.1 after vanilla on the same VM, vanilla is the base tag of xcode-27.1. |
| Full tag | A tag that includes its base tags and the macOS disk. The Anka Registry stores only full tags. An OCI registry stores a full tag when you push with push_mode 1. |
| OCI tag | A set of file layers in an OCI registry. You make one when you push with push_mode 2 or --thin, or when you push an archive. Public OCI artifacts, such as Homebrew bottles, are also OCI tags. See OCI tags. |
| Ankafile | A file that lists the macOS version and the OCI tags to pull, in order. anka create builds one VM from it. See Creating VMs with an Ankafile. |
Local tags, clones, and how clones share disk layers are in VM clones, tags, and templates.
Anka Registry tags and OCI tags
OCI tags and Anka Registry tags behave differently. Here are some important differences to be aware of:
- OCI tags are stored only in an OCI registry.
- Pulling an OCI tag that is already on the VM shows
already up-to-date. It does not remove contents from the VM. Pulling a Anka Registry Tag will force the exact state of the VM when the tag was created, always, even if you made changes but haven’t pushed a new tag. OCI Tags pulled up until then will be removed. Ultimately, Anka Registry tags and OCI tags can be combined only if you first pull the Anka Registry tag. - OCI tags stack on a VM. They do not remove contents from the VM (unless you whiteout a file in the archive you pull). Pro Tip: Pull an OCI tag onto a VM that already has an Anka Registry tag on it, and you can revert to it whenever you mess up the OCI tags and want a clean slate.
Push modes
Machines that push to an OCI registry need the right push_mode. push_mode 1 pushes the full tag, including its base tag. push_mode 2 pushes only the changes since the base tag. A push to the Anka Registry does not use push_mode. The Anka Registry always stores the full tag.
push_mode 1
This is the default in Anka 3.10.x. The push includes the base tag. A push to the Anka Registry always works this way.
Remember, both OCI and the Anka Registry try to optimize disk usage by reusing existing disk images in the registry, no matter if they are OCI tags or Anka Registry tags.
Example: 27.0.1-arm64:vanilla is already on a host. You anka pull cmake onto that VM, then push the result as 27.0.1-arm64:cmake.
On an Anka Registry or an OCI registry, cmake is a new tag whose base is the vanilla tag. The push reuses the vanilla tag the registry already has, so that tag stays unchanged. The registry stores the cmake tag on top of it.
push_mode 2
The push stores the changes since the base tag. The base tag stays out of the manifest, so you can apply the tool tag onto another VM. Use this mode for OCI tags. It works only with an OCI registry.
With push_mode 2, that same push stores the file changes. The macOS base disk stays out of the manifest.
Set the push mode
❯ anka config push_mode 2
ANKA_PUSH_MODEsets the mode for one command. Use it when a change toanka configis a problem. Example:ANKA_PUSH_MODE=2 anka push 27.0.1 -t xcode-27.1 oci://registry.example.com/v2/
Exclude files from a push
When you push or export a VM with push_mode 2, Anka does not include the paths in the ankaignore file. The default file is /Applications/Anka.app/Contents/Resources/ankaignore. It excludes caches, logs, temporary files, and Spotlight data.
To exclude more paths, copy the default file, add your paths, and set the ankaignore config key to your copy:
❯ cp /Applications/Anka.app/Contents/Resources/ankaignore ~/ankaignore
❯ echo 'Users/*/Downloads' >> ~/ankaignore
❯ anka config ankaignore ~/ankaignore
To use a different file for one command only, set ANKA_ANKAIGNORE:
❯ ANKA_ANKAIGNORE=~/xcode.ankaignore ANKA_PUSH_MODE=2 anka push xcode-builder -t xcode-26.1 oci://registry.example.com/v2/xcode
Anka also uses a .ankaignore file in the current directory. Put one in each tool’s build folder, then run anka push from that folder:
❯ cd ~/tools/xcode
❯ cp /Applications/Anka.app/Contents/Resources/ankaignore .ankaignore
❯ echo 'Users/*/Downloads' >> .ankaignore
❯ ANKA_PUSH_MODE=2 anka push xcode-builder -t xcode-26.1 oci://registry.example.com/v2/xcode
Anka uses only one file. It uses the first file that it finds, in this order:
.ankaignorein the current directory.- The file in
ANKA_ANKAIGNORE. - The file in the
ankaignoreconfig key. If you do not change it, this is the default file.
Your file replaces the default file, so keep the default lines. The rules are like .dockerignore:
- Each path is relative to the root of the VM disk, with no leading
/. A path without a/matches that name in any folder. *matches one folder level.**matches any number of levels.- When you exclude a folder, Anka also excludes all of its contents.
- A line that starts with
!keeps a path that a line above it excludes. - A line that starts with
#is a comment.
Thin pushes and pulls
--thin pushes or pulls only the last layer of a tag. The base tags stay out. --thin works with push_mode 1 and with push_mode 2. Like push_mode, --thin applies only to an OCI registry.
For an example, see Push OCI tags with --thin.