Files
dotfiles/README.md
Kenji Morishige a6296da5df feat: add hosts/ convention for centrally managed server .bashrc.local
- hosts/etqc-kenjim-11.bashrc.local: per-host local config for work server,
  managed from kenjim-mbp and deployed via 'dotfiles deploy-to'.
  Credentials replaced with CHANGEME placeholders — set real values on
  server after first deploy, never commit actual secrets.
- dotfiles_manager.sh: deploy-to step 5 auto-detects hosts/<hostname>.bashrc.local
  and SCPs it to ~/.bashrc.local on the remote (with backup of existing file)
- .gitignore: clarify that hosts/*.bashrc.local is intentionally tracked
  (existing .bashrc.local rule only matches the exact filename)
- README.md: document hosts/ layout, workflow, and credential placeholder strategy
2026-02-23 17:12:29 -06:00

12 KiB

dotfiles

Centralized configuration and environment management for kenjim.
Remote: http://172.27.0.35:3000/kenjim/dotfiles


Overview

This repo tracks shell configs, SSH settings, and editor dotfiles via a git repo hosted on a local Gitea server. On any machine, a single command restores the full environment: directories, environment variables, shell aliases, and symlinked config files.

Three scripts drive the system:

Script Role
scripts/setup_enterprise_ai_bash.sh First-time setup — creates the directory tree, writes shell config, initializes dotfiles repo, migrates files
scripts/dotfiles_manager.sh Day-to-day management — add/remove tracked files, push/pull, SSH key handling, multi-machine bootstrap
scripts/bootstrap.sh Restore shortcut — reloads shell config and runs dotfiles sync to pull latest changes
install.sh New-machine restore — applies all symlinks after cloning; auto-generated by dotfiles_manager.sh

Directory Layout

setup_enterprise_ai_bash.sh creates the following structure under $HOME:

~/
├── workspace/
│   ├── src/
│   │   ├── personal/          # personal projects
│   │   ├── work/              # work projects
│   │   └── research/          # research / papers
│   ├── experiments/           # throwaway experiments
│   ├── notebooks/             # Jupyter / Marimo notebooks
│   ├── sandboxes/             # isolated test environments
│   └── archive/               # completed / mothballed work
│
├── data/
│   ├── raw/                   # unmodified source data (excluded from Time Machine)
│   ├── processed/             # cleaned / transformed datasets
│   ├── embeddings/            # vector embeddings
│   └── synthetic/             # generated / synthetic data
│
├── models/                    # excluded from Time Machine
│   ├── huggingface/           # HF_HOME cache
│   ├── ollama/                # OLLAMA_MODELS store
│   └── fine-tuned/            # locally fine-tuned checkpoints
│
├── infra/
│   ├── docker/                # Compose files, Dockerfiles
│   ├── terraform/             # IaC configs
│   └── scripts/               # infra automation
│
├── ops/                       # operational runbooks, monitoring configs
├── scripts/                   # local utility scripts (dotfiles_manager, bootstrap, etc.)
├── vault/                     # secrets / credentials (never committed)
│
├── dotfiles/                  # ← this repo
│   ├── .bashrc                → symlinked from ~/.bashrc
│   ├── .bash_profile          → symlinked from ~/.bash_profile
│   ├── .bash_aliases          → symlinked from ~/.bash_aliases
│   ├── .gitconfig             → symlinked from ~/.gitconfig
│   ├── .vimrc                 → symlinked from ~/.vimrc
│   ├── .tmux.conf             → symlinked from ~/.tmux.conf
│   ├── .inputrc               → symlinked from ~/.inputrc
│   ├── .ssh/
│   │   ├── config             → symlinked from ~/.ssh/config
│   │   └── keys/              # .pub files + GPG-encrypted private keys
│   ├── scripts/
│   │   ├── dotfiles_manager.sh        → symlinked from ~/scripts/dotfiles_manager.sh
│   │   ├── setup_enterprise_ai_bash.sh → symlinked from ~/scripts/setup_enterprise_ai_bash.sh
│   │   └── bootstrap.sh               → symlinked from ~/scripts/bootstrap.sh
│   ├── .dotfiles_manifest     # internal list of tracked HOME-relative paths
│   ├── hosts/
│   │   └── <hostname>.bashrc.local  # per-server local configs (deployed via deploy-to)
│   ├── install.sh             # portable restore script (auto-generated)
│   └── README.md              # this file
│
└── Cloud/                     # personal profile only
    ├── ProtonDrive/           # PROTON_ROOT
    └── GoogleDrive/           # GDRIVE_ROOT
    # work profile instead creates:
    # ~/OneDrive → ~/Library/CloudStorage/OneDrive-*/  (symlink)

Machine Profiles

The setup supports two profiles selected at first-run (or via MACHINE_PROFILE=work|personal):

work personal
Cloud root ~/OneDrive (symlink to macOS mount) ~/Cloud
CLOUD_ROOT $HOME/OneDrive $HOME/Cloud
Extra vars ONEDRIVE_ROOT PROTON_ROOT, GDRIVE_ROOT
Extra aliases onedrive cloud, proton, gdrive
Committed? No — written to ~/.bashrc.local No — written to ~/.bashrc.local

Shell Config Layering

~/.bash_profile
  └── sources ~/.bashrc
        ├── ### ENTERPRISE_AI_ENV ###    ← shared vars (WORKSPACE, DATA_ROOT, MODEL_ROOT, …)
        ├── ### DOTFILES_ALIASES ###     ← dotfiles / dot / dots-sync / dots-push / dots-status
        └── sources ~/.bashrc.local      ← machine-specific (profile, cloud paths, MACHINE_HOST)
File Committed to dotfiles? Purpose
~/.bashrc Yes Shared env vars, aliases, loads .bashrc.local
~/.bash_profile Yes macOS login shell — sources .bashrc
~/.bashrc.local No Machine-specific overrides (profile, cloud paths)

~/.bashrc.local is written by setup_enterprise_ai_bash.sh and regenerated when running it again. It is listed in .gitignore and never pushed to the remote.


Key Environment Variables

Variable Value Set in
WORKSPACE $HOME/workspace ~/.bashrc
DATA_ROOT $HOME/data ~/.bashrc
MODEL_ROOT $HOME/models ~/.bashrc
HF_HOME $MODEL_ROOT/huggingface ~/.bashrc
OLLAMA_MODELS $MODEL_ROOT/ollama ~/.bashrc
DOTFILES_DIR $HOME/dotfiles ~/.bashrc
DOTFILES_REMOTE http://172.27.0.35:3000/kenjim/dotfiles ~/.bashrc
MACHINE_PROFILE work or personal ~/.bashrc.local
MACHINE_HOST hostname -s output ~/.bashrc.local
CLOUD_ROOT ~/OneDrive or ~/Cloud ~/.bashrc.local

Shell Aliases

Alias Expands to
ws cd $WORKSPACE
src cd $WORKSPACE/src
data cd $DATA_ROOT
models cd $MODEL_ROOT
cloud cd $CLOUD_ROOT
dotfiles / dot bash ~/scripts/dotfiles_manager.sh
dots-sync dotfiles sync
dots-push dotfiles push
dots-status dotfiles status

Bootstrap Flow

First-time setup on a new machine

# 1. Run the full setup wizard (creates dirs, shell config, dotfiles repo):
bash scripts/setup_enterprise_ai_bash.sh

# 2. Reload shell:
source ~/.bash_profile

The wizard will interactively:

  1. Select a machine profile (work / personal)
  2. Create the full directory tree
  3. Write ~/.bashrc env block and ~/.bashrc.local
  4. Initialize or clone the dotfiles repo from Gitea
  5. Add dotfiles aliases to ~/.bashrc
  6. Offer to migrate shell configs, .gitconfig, scripts into dotfiles
  7. Offer SSH config setup + GPG key export
  8. Offer to push everything to $DOTFILES_REMOTE
  9. Offer Time Machine exclusions for ~/data/raw and ~/models
  10. Offer to bootstrap a remote machine over SSH

Restore an existing setup on a new machine

# Clone the repo and run the portable restore script:
git clone http://172.27.0.35:3000/kenjim/dotfiles ~/dotfiles
bash ~/dotfiles/install.sh
source ~/.bash_profile

install.sh will:

  • Apply all symlinks listed in .dotfiles_manifest
  • Prompt for machine profile and run setup_enterprise_ai_bash.sh if no .bashrc.local exists
  • Prompt to GPG-decrypt any SSH private keys stored in dotfiles/.ssh/keys/*.gpg

Day-to-day sync

After editing on one machine, push and sync on the other:

# On the machine where you made changes:
dotfiles push "describe what changed"

# On the other machine to pick up the changes:
dotfiles sync
# Other useful commands:
dotfiles status        # check symlink health
dotfiles sync          # pull + rebase + reapply symlinks (also callable as: bash ~/scripts/bootstrap.sh)

Remote machine bootstrap (from this machine)

dotfiles remote-bootstrap user@hostname
dotfiles remote-bootstrap user@hostname --profile work

This uploads the scripts, then runs the full setup interactively over SSH.

Deploy to a server with no Gitea access

Linux servers at work can't clone the private Gitea repo. Use deploy-to to SCP tracked dotfiles and scripts directly to their HOME paths — no git required on the remote.

# Push everything (dotfiles + scripts):
dotfiles deploy-to user@server

# Scripts only (dotfiles_manager.sh, bootstrap.sh, setup script):
dotfiles deploy-to user@server --scripts-only

# Preview what would be transferred without doing it:
dotfiles deploy-to user@server --dry-run

# Also deploy ~/.ssh/config (skipped by default for security):
dotfiles deploy-to user@server --include-ssh

# Skip the pre-deploy backup (faster, but no safety net):
dotfiles deploy-to user@server --no-backup

Before overwriting any file, deploy-to SCPs the server's existing versions to ~/.dotfiles_backup/remote-<host>-<timestamp>/ on your local machine. Files are copied directly (not symlinked). Re-run deploy-to any time you want to push updates. ~/.ssh/ is skipped by default to avoid accidentally pushing private keys or your personal known_hosts to a shared server.

Centrally managing ~/.bashrc.local for servers

Work servers can't reach the Gitea repo, so their ~/.bashrc.local is managed centrally from kenjim-mbp using per-host files in dotfiles/hosts/:

dotfiles/hosts/
└── <hostname>.bashrc.local    # deployed as ~/.bashrc.local on that server

deploy-to automatically detects and deploys the matching file:

# Edit the server's local config on kenjim-mbp:
$EDITOR ~/dotfiles/hosts/etqc-kenjim-11.bashrc.local

# Commit and push from kenjim-mbp:
dotfiles push "fix: update etqc-kenjim-11 local config"

# Deploy to the server (no git access needed on the server):
dotfiles deploy-to kenjim@etqc-kenjim-11

The hosts/ files are committed to git. They may contain non-secret machine-specific variables (MACHINE_PROFILE, MACHINE_HOST, AWS_PROFILE, etc.). Do not commit real passwords or tokens — use CHANGEME placeholders and set real values manually on the server after first deploy.


~/dotfiles/.bashrc   ←──────────── ~/dotfiles/ (git repo)
      ↑
  symlink
      │
~/.bashrc            ←── shell reads this

dotfiles add <file> moves the file into ~/dotfiles/, creates a symlink at the original HOME location, and records the relative path in .dotfiles_manifest. dotfiles install re-creates all symlinks from the manifest (idempotent — safe to re-run). Conflicts are backed up to ~/.dotfiles_backup/<timestamp>/ before being replaced.


SSH Key Strategy

Item Committed? Details
~/.ssh/config Yes Shared SSH client configuration
~/.ssh/*.pub Yes Public keys are safe to store
~/.ssh/id_* (private) No Listed in .gitignore
~/.ssh/keys/*.gpg Yes GPG-encrypted private key backups
# Encrypt private keys and save to dotfiles:
dotfiles ssh-export

# Decrypt on another machine after sync:
dotfiles ssh-import

Gitea Authentication

HTTP push/pull uses a Personal Access Token saved locally (never committed):

dotfiles auth
# → Settings (avatar) → Applications → Generate Token → paste here

Credentials are stored at ~/.config/dotfiles/credentials (chmod 600).


Time Machine Exclusions

During setup you are offered the option to exclude large AI folders:

~/data/raw      — large raw datasets
~/models        — multi-GB model weights

To add manually:

sudo tmutil addexclusion ~/data/raw
sudo tmutil addexclusion ~/models