Skip to content

mohdfareed/machine

Repository files navigation

Machine Setup & Dotfiles

Cross-platform dotfiles and machine manager for macOS, Windows, and Linux.

Setup

Bootstrap a bare machine (installs uv and git if needed, clones repo, installs mc):

Unix (macOS/Linux/WSL):

curl -LsSf https://raw.githubusercontent.com/mohdfareed/machine/main/scripts/bootstrap.sh | sh

Windows (PowerShell):

irm https://raw.githubusercontent.com/mohdfareed/machine/main/scripts/bootstrap.ps1 | iex

The repo is cloned to ~/.machine by default. Override with MC_HOME=<path> before running. Re-run bootstrap on an existing machine to reinstall the CLI after moving the repo:

cd $MC_HOME
./scripts/bootstrap.sh

Usage

mc apply [modules]   # Deploy configs, packages, and scripts
mc sync              # Pull and push latest repo changes
mc update [modules]  # Update packages and run update scripts

Run mc -h or mc <command> -h for full options.

Design

~/.machine/
├── config/                  <- shared modules (git, shell, ...)
│   └── <name>/
│       ├── module.py        <- Module(files, packages, scripts)
│       └── ...
├── machines/                <- per-host manifests
│   └── <id>/
│       ├── manifest.py      <- MachineManifest(modules, files, packages, scripts)
│       ├── machine.env      <- committed config vars (paths, hostname, ...)
│       └── ...
└── src/machine/             <- CLI (core.py, app.py, cli.py, manifest.py)

Modules (config/<name>/module.py) export a Module:

Field Description
files FileMapping(source, target) → symlinked to ~
packages Package(name, brew=, apt=, snap=, winget=, scoop=, mas=, script=)
scripts Platform-tagged scripts to run
overrides FileMapping(source, target) → machine-local override symlinks
depends Module names that must be included before this

Manifests (machines/<id>/manifest.py) export a MachineManifest:

Field Description
name Public display name; defaults to machine ID
modules Module names to compose
files Machine-specific symlinks
packages Machine-specific packages
scripts Machine-specific scripts

Platform tags on script filenames filter by platform - no tag means all platforms:

Tag Runs on
.macos macOS
.linux Linux
.unix macOS, Linux, WSL, GHCS
.win Windows
.wsl WSL
.ghcs GitHub Codespaces

Script prefixes control execution behavior:

Prefix Behavior
init_ Runs before packages (env/tool setup)
once_ Runs once per machine, then skipped
watch_ Reruns when the script's content changes
up_ Runs only during mc update

Env vars are available to every script subprocess at runtime via three-tier sourcing:

  1. ~/.env - generated by mc apply, contains only MC_HOME and MC_ID
  2. $MC_HOME/machines/$MC_ID/machine.env - machine-specific config vars
  3. $MC_PRIVATE/env/$MC_ID.env - machine secrets, plain dotenv format

mc loads all three tiers into every script subprocess. Shell profiles (.zshenv, profile.ps1) source the same three tiers.

Local overrides: modules declare which machine-specific files they accept via the overrides field. Drop matching files in your machine dir and they are auto-discovered and symlinked:

  • ~/.gitconfig.local - declared by git module, included by gitconfig
  • ~/.zshenv.local - declared by shell module, sourced by zshenv
  • ~/.zshrc.local - declared by shell module, sourced by zshrc
  • ~/term.settings.json - declared by win-term module, used by Windows Terminal

Secrets (MC_PRIVATE)

Secrets are stored outside the repo in MC_PRIVATE - defaults to app_dir/private but typically overridden in machine.env (e.g. $ICLOUD/.machine on macOS, $HOME/.machine on Linux). The directory is never checked into git.

MC_PRIVATE/
├── env/
│   └── <MC_ID>.env  <- per-machine secrets (plain dotenv)
├── ssh/
│   └── <MC_ID>      <- machine private key (optional)
│   └── <MC_ID>.pub  <- matching public key (optional)

Docker Services

The homelab module (config/homelab/) deploys and manages Docker Compose services over Tailscale. See config/homelab/README.md for architecture, environment variables, and setup instructions.

Any machine can include this module as a deployment target. By default, the homelab machine acts as the central orchestrator and also serves as a target for its own services.

Development

cd $MC_HOME

# build and run for development
uv sync --dev
uv run mc --help

# format and auto-fix (run before committing)
./scripts/fix.sh
# code validation (run before committing)
./scripts/check.sh

About

Machine setup CLI app.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Packages

 
 
 

Contributors