A rapid run through autopkg.
This isn’t a full blown autopkg guide - that’s what the autopkg wiki is for… this is a “let’s get this working quickly” guide…
Last time, we set up a dockerised Nginx web server to host our Munki Repo. Now we want to get that repo populated with a few test apps, quickly and easily.
The plan was always to build a home lab setup that was at least production adjacent, even if it’s not full prod. In the real world, folks use autopkg to automatically manage applications in their munki repo - manually importing apps is great for testing, or for one off apps or nopkgs, but otherwise… automation is our friend. At least until it isn’t.
What’s autopkg again?
Autopkg is basically a swiss army knife of tools (called processors) that admins can orchestrate to download, unzip, repackage…
…basically do all kinds of things to get software from a vendor website into your package management tool of choice, like Munki, or Jamf Pro.
The steps for each package are captured in an XML file, known as a recipe. And recipes can call other recipes. So - it’s common (and indeed, best practise) to have a “download” recipe - which can be called by another recipe to perform specific processing steps to upload the downloaded package into Munki, Jamf, Iru, etc…
But writing your own recipes is a lot of work if you don’t need to do so. We just want to grab a few popular software titles and get ‘em into our new Munki repo. Again - my goal is a “production-like” setup quickly and easily.

Quick and dirty (aka - I just want some software to use with my new munki repo)
- Download and install autopkg
- Point it at your local munki folder with the following command:
defaults write com.github.autopkg MUNKI_REPO /path/to/munki_repo
- Add some recipes
autopkg repo-add recipes
- Run the recipes you care about.
autopkg run Firefox.munki.recipeautopkg run GoogleChrome.munki.recipe- repeat for all the apps you want to use in your homelab…
- then finally, run
autopkg run makecatalogs.munki
Profit?
Er, I mean - Boom - our munki repo now contains some software! That was easy… We’ve added the latest Firefox and Chrome - and that final autopkg run makecatalogs.munki is a special recipe that updates the catalog files that Munki uses to make sense of the software contained within the repo, and will make Munki aware of any new software discovered in our check for updates.
So we’re done? I mean, kinda… but…
(Crash) Overrides?
Overrides? We don’t need no stinking overrides! Well, actually - we probably do. Autopkg best practice is to create an override for all recipes you run.
Good job that it’s so easy to do.
autopkg make-override Firefox.munki.recipe
Which creates an overridden version of the recipe in your home directory
~/Library/AutoPkg/RecipeOverrides/Firefox.munki.recipe (for example)
And now you can run your overridden recipe instead of the raw recipe
autopkg run ~/Library/AutoPkg/RecipeOverrides/Firefox.munki.recipe
But it works without bothering with overrides? Why do I need them?
I’m glad you asked. Creating an override:
- Allows for customisation of input variables and other values in a recipe without messing with the original upstream file.
- Perhaps you want the UK version of Firefox (by changing the LOCALE value in the recipe to
en-gb) - Your munki repo folders may have a different layout (so the default Chrome recipe drops Google Chrome into
/appsin a munki repo, perhaps you’d rather it went into/apps/browsersin your munki repo.)
- Perhaps you want the UK version of Firefox (by changing the LOCALE value in the recipe to
But the BIGGEST benefit of using overrides is about trusting parent recipes…
Indeed - there’s a whole podcast episode (from 2016!) about it…
Autopkg is all about standing on the shoulders of giants - you don’t need to reinvent the wheel when adding software to your repo when someone else has already written a recipe.
BUT!
An upstream recipe may have been changed to improve it, or because the vendor has changed how and where they host the software, OR EVEN - what if it’s been compromised by a bad actor?
If you have an overridden version of a recipe, and the original recipe changes - autopkg will fail to run correctly until you’ve validated those upstream changes. Once you’re happy with the changes?
autopkg update-trust-info override_name
Then you’re back in business.
What next?
For now we only have the default recipes installed. I wanted to add one for the IINA media player - which isn’t one of the default recipes. How can we find other suitable repos?
A couple of ways. From within autopkg itself -
autopkg search iina
Or - you can try autopkgweb…
In this instance, both options return this repo -
https://github.com/autopkg/hjuutilainen-recipes
We can add it via
autopkg repo-add hjuutilainen-recipes
And now we have recipes for iina we can create overrides for, and start using.
(yes - I’m busy ignoring actually writing my own recipes, and am busy re-using the wonderful resources the Mac admin community are so good at sharing. Rest assured, if I need to write my own recipes - I’ll blog about it!)
Automate all the things…
Finally - I want this to be set and forget. I want a daily check for new software. I’ve achieved this with a simple shell script and a LaunchAgent to run the script every day at 14:30 hours.
The shell script writes the date and time it runs to a local log file - and then outputs verbose (-vv) output to the file too, so I can check the logs to see if it’s actually working or not.
We’ll ignore that I had to chat to an LLM to get my LaunchAgent syntax working - but I did get it working eventually - so here are both bits.
(at some point in the future I’ll add these resources to a github repo too)
Script:
#!/bin/zsh
/bin/date >> /Users/Shared/autopkg.log
OVERRIDE_DIR="/Users/steve/Library/AutoPkg/RecipeOverrides"
/usr/local/bin/autopkg run -vv \
$OVERRIDE_DIR/Firefox.munki.recipe \
$OVERRIDE_DIR/VLC.munki.recipe \
$OVERRIDE_DIR/GoogleChrome.munki.recipe \
$OVERRIDE_DIR/msedge.munki.recipe \
$OVERRIDE_DIR/IINA.munki.recipe \
makecatalogs.munki \
>> /Users/Shared/autopkg.log
LaunchAgent:
(drop this into ~/Library/LaunchAgents/com.autopkg.plist)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.autopkg.test</string>
<key>ProgramArguments</key>
<array>
<string>/bin/zsh</string>
<string>/Users/steve/autopkg/autopkg_update.sh</string>
</array>
<key>StartCalendarInterval</key>
<dict>
<key>Minute</key>
<integer>30</integer>
<key>Hour</key>
<integer>14</integer>
</dict>
<key>StandardOutPath</key>
<string>/tmp/myscript.out</string>
<key>StandardErrorPath</key>
<string>/tmp/myscript.err</string>
</dict>
</plist>
So - we have a Munki Server - hosting some apps - and new versions will be added automatically.
Are we done yet?
At this point we should probably start to make our newly discovered and downloaded software available to client devices. That can be the next installment… which I should probably get on with writing…
