- Add detailed overview of what the repository provides - Document all included components (tarball, services, shell integration) - Add practical examples for using in custom bootc images - Include basic, advanced, and Universal Blue integration examples - Document build process and runtime behavior - Add environment variables and file locations reference - Include systemd service details - Add troubleshooting section for common issues - Document contribution guidelines and related projects |
||
|---|---|---|
| .github | ||
| system_files | ||
| Containerfile | ||
| cosign.pub | ||
| Justfile | ||
| LICENSE | ||
| README.md | ||
brew
Repository for generating Homebrew tarballs for redistribution on image-based systems via an OCI image.
This includes general settings you'd want to use when using Homebrew on a bootc system, including a tarball and services for setting it up.
Overview
This repository builds an OCI container image that packages:
- A pre-installed Homebrew tarball (
homebrew.tar.zst) - Systemd services for automated setup, updates, and upgrades
- Shell integration scripts (bash, fish)
- Security limits and tmpfiles configuration
The image is designed to be consumed by custom bootc-based container images, providing a seamless way to include Homebrew package management in immutable Linux systems.
What's Included
Homebrew Tarball
- Pre-built Homebrew installation at
/usr/share/homebrew.tar.zst - Built from official Homebrew installer in a clean Wolfi container
- Compressed with zstd for efficient storage
Systemd Services
brew-setup.service
Runs on first boot to extract and configure Homebrew:
- Extracts tarball to
/var/home/linuxbrew/.linuxbrew - Sets appropriate ownership (UID 1000)
- Creates marker file to prevent re-running
brew-update.timer & brew-update.service
Automatically keeps Homebrew up to date:
- Runs daily to update Homebrew itself
- Ensures formula database is current
brew-upgrade.timer & brew-upgrade.service
Automatically upgrades installed packages:
- Runs on a regular schedule
- Keeps installed packages up to date
Shell Integration
- Bash:
/etc/profile.d/brew.sh- Automatically configures Homebrew environment - Fish:
/usr/share/fish/vendor_conf.d/ublue-brew.fish- Fish shell support - Bash Completion:
/etc/profile.d/brew-bash-completion.sh
Configuration Files
- Security Limits:
/etc/security/limits.d/30-brew-limits.conf - Tmpfiles:
/usr/lib/tmpfiles.d/homebrew.conf - Systemd Presets:
/usr/lib/systemd/system-preset/01-homebrew.preset
Using in Custom bootc Images
Basic Example
To include Homebrew in your custom bootc image, copy the files from this repository's OCI image:
FROM quay.io/fedora/fedora-bootc:41
# Copy Homebrew files from the brew image
COPY --from=ghcr.io/ublue-os/brew:latest /system_files /
This will:
- Install the Homebrew tarball to
/usr/share/homebrew.tar.zst - Install all systemd services and timers
- Add shell integration scripts
- Configure system limits and tmpfiles
On first boot, brew-setup.service will automatically:
- Extract Homebrew to
/var/home/linuxbrew/.linuxbrew - Set up proper permissions
- Make Homebrew ready to use
Advanced Example with Pre-installed Packages
If you want to pre-install Homebrew packages in your image:
FROM quay.io/fedora/fedora-bootc:41
# Copy Homebrew files
COPY --from=ghcr.io/ublue-os/brew:latest /system_files /
# Install Homebrew packages during image build
RUN mkdir -p /var/home/linuxbrew && \
tar --zstd -xvf /usr/share/homebrew.tar.zst -C /tmp && \
mv /tmp/home/linuxbrew/.linuxbrew /var/home/linuxbrew/ && \
eval "$(/var/home/linuxbrew/.linuxbrew/bin/brew shellenv)" && \
brew install gcc neovim ripgrep && \
brew cleanup && \
tar --zstd -cvf /usr/share/homebrew.tar.zst /var/home/linuxbrew/.linuxbrew && \
rm -rf /var/home/linuxbrew/.linuxbrew /tmp/home
This approach:
- Extracts the Homebrew tarball during build
- Installs desired packages
- Re-compresses everything back into the tarball
- Removes temporary files
On first boot, users get Homebrew with your pre-installed packages ready to use.
Using with Universal Blue Images
For Universal Blue-based images, you can use this as a MODULE:
FROM ghcr.io/ublue-os/bluefin-dx:latest
# Include Homebrew support
COPY --from=ghcr.io/ublue-os/brew:latest /system_files /
Disabling Auto-Updates
If you want Homebrew installed but prefer manual updates:
FROM quay.io/fedora/fedora-bootc:41
COPY --from=ghcr.io/ublue-os/brew:latest /system_files /
# Disable automatic update timers
RUN systemctl disable brew-update.timer && \
systemctl disable brew-upgrade.timer
Building the Image
Prerequisites
- Podman or Docker
- Make (optional, for using Justfile)
Build Command
podman build -t brew:latest -f ./Containerfile .
Or using just:
just build
Multi-Architecture Builds
The GitHub Actions workflow builds for both amd64 and arm64 architectures automatically.
How It Works
Build Process
-
Builder Stage: Uses Wolfi base image to create a minimal, secure build environment
- Installs necessary tools (curl, git, zstd, tar, etc.)
- Downloads official Homebrew installer
- Runs Homebrew installation in isolated environment
- Compresses installation to tarball with zstd
-
Final Stage: Creates a scratch image with just the necessary files
- Copies system configuration files
- Includes compressed Homebrew tarball
- No runtime dependencies
Runtime Behavior
When a bootc system using this image boots:
-
First Boot:
brew-setup.servicedetects no existing Homebrew installation- Extracts tarball to
/var/home/linuxbrew/.linuxbrew - Sets ownership to first user (UID 1000)
- Creates marker file to prevent re-extraction
-
Subsequent Boots:
brew-setup.serviceskips (marker file exists)brew-update.timerruns daily to update Homebrewbrew-upgrade.timerruns to upgrade packages- Shell integration automatically available to users
Environment Variables
When users log in, the shell integration scripts set up:
HOMEBREW_PREFIX="/home/linuxbrew/.linuxbrew"
HOMEBREW_CELLAR="/home/linuxbrew/.linuxbrew/Cellar"
HOMEBREW_REPOSITORY="/home/linuxbrew/.linuxbrew/Homebrew"
PATH="/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin:$PATH"
MANPATH="/home/linuxbrew/.linuxbrew/share/man:$MANPATH"
INFOPATH="/home/linuxbrew/.linuxbrew/share/info:$INFOPATH"
File Locations
| Path | Purpose |
|---|---|
/usr/share/hobrew.tar.zst |
Compressed Homebrew installation |
/var/home/linuxbrew/.linuxbrew |
Extracted Homebrew (runtime) |
/etc/.linuxbrew |
Marker file indicating setup cn |
/usr/share/fish/vendor_conf.d/ublue-brew.fish |
Fish shell integration |
Systemd Service Details
brew-setup.service
Type: oneshot
When: First boot only
Conditions:
/etc/.linuxbrewdoes not exist/var/home/linuxbrew/.linuxbrewdoes not exist/usr/share/homstexists
brew-update.timer
Schedule: Daily
Purpose: Update Homebrew repository and formula database
brew-upgrade.timer
Schedule: Regular intervals
Purpose: Upgrade installed Homebrew packages
Troubleshooting
Homebrew not in PATH
Make sure your shell is properly loading the profile scripts:
source /etc/profile.d/brew.sh
Or manually:
eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
Permission Issues
Homebrew expects to be owned by the first user (UID 1000). If you have permission issues:
sudo chown -R $(id -u):$(id -g) /var/home/linuxbrew
Force Re-extraction
If you need to re-extract the Homebrew tarball:
sudo rm /etc/.linuxbrew
sudo systemctl start brew-setup.service
License
See LICENSE file for details.
Contributing
This repository is part of the Universal Blue project. Contributions are welcome via pull requests.