Moving to OCI tags
You do not have to replace the Anka Registry to use OCI tags. We recommend this approach:
- Keep the full templates in the Anka Registry.
- Move only the tool layers of each template, such as Xcode, Homebrew, and language runtimes, to OCI tags.
- Build each final template on a producer host and push it back to the Anka Registry with the same name.
The Build Cloud Controller, your CI plugins, and your template names stay the same. The tools become small layers that you can pull onto more than one macOS version.
Should you move?
- You use Anka Build Cloud: move only the tool layers. The Controller pulls templates only from the Anka Registry, so the final templates must stay there.
- You use only the Anka CLI and have a container registry: you can move all templates, including the macOS base, to your OCI registry. After that, you do not need the Anka Registry.
- You have one or two templates that do not change often: you get little from the change. Stay on the Anka Registry.
Map your template hierarchy to OCI tags
Many teams use the clone hierarchy that we recommend for templates: a vanilla macOS VM, then a clone with Homebrew and git, then a clone with Xcode, then one clone for each project. Move each step as follows:
| Step in the hierarchy | Where it goes |
|---|---|
| vanilla macOS | A full tag. Keep it in the Anka Registry, or push it to an OCI registry with push_mode 1. |
| Homebrew and git | An OCI tag. |
| Port forwarding, CPU, RAM, and other VM settings | The base template, or EXPOSE, LABEL, and MOUNT in an Ankafile. An OCI tag holds files. Do not use it for VM settings. |
| Xcode | One OCI tag for each Xcode version. You can use one Xcode tag with any base template, including base templates that you make in the future. Of course, the macOS version of the base template must support that Xcode version. |
| Project dependencies | An OCI tag when more than one template uses them. If not, keep them in the final template. |
Move in phases
Phase 1: Upgrade with no change in behavior
Install Anka 3.10.0 on your producer/builder hosts first. Ensure anka config push_mode is 1 (the default). Your current push and pull scripts work the same, they’ll just avoid pushing things that will be isolated into OCI tags later on.
Note: Anka Nodes that run VMs need Anka 3.10.0 only when they pull OCI tags.
Phase 2: Make your first tool tag from a clean base
Set up access to your OCI registry. Then clone your vanilla VM, mark it with a local tag, install one tool, and push only the changes:
❯ anka clone 26.4.1 xcode-builder
❯ anka push --local --tag base xcode-builder
❯ anka start xcode-builder
# install Xcode in the VM, then stop it
❯ anka stop xcode-builder
❯ ANKA_PUSH_MODE=2 anka push xcode-builder -t xcode-26.1 oci://registry.example.com/v2/xcode
The xcode-26.1 tag holds only the files that changed after the local base tag.
When you push withpush_mode2, Anka does not push the paths in theankaignorefile, such as caches and logs. To exclude more paths from your tool tag, see Exclude files from a push.
Install each tool again on a clean clone. Do not try to take it out of an existing Anka Registry tag. An existing tag often holds more than one change, and also caches and logs.
Pull the new tag onto a clone of your vanilla VM and run your tests before you go to the next phase:
❯ anka clone 26.4.1 xcode-test
❯ anka pull xcode-test oci://registry.example.com/v2/xcode:xcode-26.1
Phase 3: Build your final templates from the base and the OCI tags
On a producer host, pull the base template from the Anka Registry. Pull the OCI tags in order. Push the result to the Anka Registry with the existing template name. The Anka Registry stores it as a full tag, and the Controller uses it like any other template.
A full tag needs
push_mode1. If you setpush_mode2on the producer host, set it back before you push the final template:❯ anka config push_mode 1
See Preparing a build VM for the commands.
Keep the pull order in an Ankafile in your source control. Each change to a template then goes through code review, and you can build the same template again at any time.
Phase 4 (optional): Remove the Anka Registry
This phase is only for teams that do not use Anka Build Cloud. Push the macOS base to your OCI registry with push_mode 1. Then let each runner create its VM from the Ankafile, or pull the finished template from the OCI registry.
Rules to follow
- Pull the Anka Registry tag first. Then pull the OCI tags. A pull of an Anka Registry tag removes the OCI tags that you pulled before it. See Anka Registry tags and OCI tags.
- Set the push mode for one command. Use
ANKA_PUSH_MODE=2on the push. Do not setpush_mode2globally on a producer host that also pushes full templates to an OCI registry. A full template pushed withpush_mode2does not include the macOS disk. - Use tag names that do not change. Use names such as
xcode-26.1, notxcode-latest. The Anka Registry gives each new tag a new number. An OCI registry replaces a tag when you push the same tag name again. - Record the minimum macOS version. An OCI tag applies to any VM, but the tool in it can need a specific macOS version. Put the version in the tag name or the tag description.
- Remove files with a whiteout. To remove a file from an OCI tag, append an archive with a whiteout. You do not rebuild the earlier layers.
- Refresh registry credentials in CI. Some registry credentials expire. For example, Amazon ECR credentials expire after about 12 hours.
Go back to the old templates
In Phases 2 and 3, your old templates stay in the Anka Registry, and nothing changes them. To go back, point your CI jobs at the old tag.
On a VM, pull the Anka Registry tag again to get a clean VM. When you delete a local OCI tag, the files from that tag stay on the VM.