-
Notifications
You must be signed in to change notification settings - Fork 0
Profile System
Manage different configurations for different machines and environments with Heimdal's profile system.
- Overview
- Why Use Profiles?
- Basic Profile Setup
- Profile Inheritance
- Profile Commands
- Conditional Configuration
- Best Practices
- Troubleshooting
Profiles let you define different configurations for different contexts:
- Work laptop — Corporate tools, VPN configs, work-specific settings
- Personal desktop — Personal apps, gaming tools, media configs
- Server — Minimal setup, no GUI apps, server utilities
One dotfiles repository, multiple configurations.
Without profiles, you'd need separate dotfiles repositories per machine or manual cherry-picking of configurations. Profiles give you:
- One repository for all machines
- Shared base configuration with machine-specific additions
- Easy switching between setups
- Inheritance to reduce duplication
heimdal:
version: "1"
profiles:
default:
packages:
homebrew: [git, vim, tmux]
apt: [git, vim, tmux]
dotfiles:
- .vimrc
- .zshrcApply:
heimdal applyheimdal:
version: "1"
profiles:
work-laptop:
packages:
homebrew: [git, vim, tmux, kubectl, docker]
dotfiles:
- .vimrc
- .zshrc
personal-desktop:
packages:
apt: [git, vim, tmux, gimp]
dotfiles:
- .vimrc
- .bashrc
server:
packages:
apt: [git, vim, tmux, htop]
dotfiles:
- .vimrc
- .bashrcSwitch to a profile and apply:
heimdal profile switch work-laptop
heimdal applyProfiles can extend other profiles with extends:. The merge rules are:
-
packages,dotfiles,templates,ignore— unioned (child entries are added on top of parent entries; per-manager package lists are merged) -
hooks— replaced by the child (child hooks completely override parent hooks)
profiles:
default:
packages:
common: [git, vim, tmux]
dotfiles:
- .vimrc
- .zshrc
ignore:
- "*.swp"
work-laptop:
extends: default
packages:
homebrew: [kubectl, slack, zoom]
hooks:
post_apply:
- "echo 'Work laptop configured'"
personal-desktop:
extends: default
packages:
homebrew_casks: [spotify, discord]The effective work-laptop profile has git, vim, tmux (inherited from default), plus kubectl, slack, and zoom.
See what a profile looks like after inheritance is applied:
heimdal profile show work-laptop --resolvedYou can chain inheritance up to any depth, though keeping it shallow (2–3 levels) is recommended for clarity:
profiles:
base:
packages:
common: [git, vim]
developer:
extends: base
packages:
homebrew: [gh, docker]
web-dev:
extends: developer
packages:
homebrew: [node, yarn]Switch the active profile. Run heimdal apply afterward to apply it:
heimdal profile switch <name>
heimdal applyheimdal profile currentheimdal profile list# Show the raw profile definition
heimdal profile show <name>
# Show the profile after inheritance is resolved
heimdal profile show <name> --resolved# Compare active profile with another
heimdal profile diff <name>
# Compare two specific profiles
heimdal profile diff <profile1> <profile2>heimdal profile create <name>
# Create extending an existing profile
heimdal profile create <name> --extends <base>heimdal profile clone <source> <dest>Package lists per manager are automatically scoped to the current OS. If a profile defines both homebrew and apt packages, only the relevant manager's packages are installed.
For dotfiles, use when conditions to restrict individual entries:
profiles:
default:
dotfiles:
- .vimrc
- .zshrc
# Only on macOS
- source: .config/nvim
target: ~/.config/nvim
when:
os: [macos]
# Only on machines whose hostname matches this pattern
- source: .ssh/config.work
target: ~/.ssh/config
when:
hostname: "work-*"See Dotfile Management — Conditional Dotfiles for the full when field reference.
profiles:
default:
packages:
common: [git, vim, tmux]
dotfiles:
- .vimrc
- .zshrc
work:
extends: default
# Only work-specific config here
personal:
extends: default
# Only personal-specific config hereGood names: work-mac, personal-linux, dev-server, home-desktop
Avoid: profile1, laptop, config
Each profile should have a clear, single purpose. Avoid putting everything into one profile.
heimdal profile show work-laptop --resolved
heimdal apply --dry-runAdd YAML comments explaining each profile's purpose and the machines it's used on:
profiles:
# Work laptop (MacBook Pro 2024)
# Includes: Kubernetes, Docker, corporate tools
work-mac:
extends: default
packages:
homebrew: [kubectl, docker]# List available profiles
heimdal profile list
# Check spelling in heimdal.yamlEnsure the parent profile is defined before the child:
profiles:
default: # parent must exist
packages:
common: [git]
work:
extends: default # references existing parentRemember that packages are unioned. If the parent has a homebrew: [git, vim] and the child has homebrew: [slack], the child's effective list is [git, vim, slack].
To see exactly what will be installed:
heimdal profile show <name> --resolvedheimdal profile list
heimdal profile show <name>
heimdal profile show <name> --resolved
heimdal profile switch <name>
heimdal profile current
heimdal profile create <name> --extends <base>
heimdal profile clone <source> <dest>
heimdal profile diff <name1> <name2>