This year I rebuilt my main home server using vanilla LXD/LXC instead of Proxmox. One issue I’d had previously was the process of updating all my containers, at times twenty ArchLinux containers which would download the same package repeatedly.
Therefore I looked into sharing the pacman cache (and subsequently AUR cache) with my LXC containers. The process below was inspired by the great wiki article about sharing your Pacman cache over a network.
Permission Setup
First thing we need is a common group mapping between host and containers to share files and permissions. For this post I will be using the following values:
Group Name: dcache
Group GID: 9999
On host and container(s):
Allow root to use this supplementary group on the host and container(s):
Enable your LXC unprivileged containers the ability to map this group. Append to /etc/subgid:
Allow the container to map these IDs:
This group can also be used to write files back to the host from inside the container. You can achieve this by changing the users primary group to dcache or overriding a systemd service file changing the executing group.
Setup Pacman
This section will assume you have setup an AUR helper to build and cache packages. In my instance I use aurutils and save packages to /var/cache/aur/custompkgs. I compile my AUR packages on the host as this bypasses any restrictive CPU limits I have set on my containers designed to limit services during normal operation.
By default pacman cache’s group is set to root, lets change this on our host to the new group:
Create mount points in our container:
Share host folder to container mount points:
Instruct Pacman where to find cached packages, modify /etc/pacman.conf to include the following lines:
In my case for aurutils I have to instruct pacman where it can find the AUR packages by adding the following lines to /etc/pacman.conf:
You should now have Pacman sharing cache between your host and containers!
Reflector with mirrorlist syncing
Another point of duplication was Pacman’s /etc/pacman.d/mirrorlist. I use reflector to keep my mirrorlist up to date which would be identical for every container. Instead of running reflector in every container I wrote a small piece of automation that allowed the hosts mirrorlist to be pushed to every container.
Host files can be pushed into a container with the following command:
Using LXC’s custom metadata functionality we tag every container that requires the updated mirrorlist with the following command:
The following systemd service file saved to /etc/systemd/system/lxd-reflector-update.service loops through all containers with user.reflector=true metadata and updates the /etc/pacman.d/mirrorlist file:
Then add a timer /etc/systemd/system/lxd-reflector-update.timer:
You can then enable and start the timer to run the update daily:
In future I would like to override the reflector.service to execute lxd-reflector-update.service once it has updated.
Automation
There have been a lot of commands throughout this post. I don’t remember them all, as such I have a simple bash script that automates the setup of a new container. Some of this can be achieved by LXD profiles but I’m yet to investigate that.
Reach out and let me know if there is a better way!