Server Deployment Guide¶
How to deploy dotfiles to servers, containers, and CI/CD environments.
Deployment Modes¶
| Mode | Tools Installed | Packages | Use Case |
|---|---|---|---|
| Full | All (mise.toml) | Yes (run_once scripts) | Personal workstations |
| Server | Server-safe (mise-server.toml) | Yes (run_once scripts) | Dev servers, VMs |
| Dotfiles Only | None (chezmoi only) | No | Shared servers, containers, CI |
Shell Policy¶
- Server deployments keep
bashas the default stable baseline. zshremains available as an opt-in interactive shell.- Workstation installs can still switch default shell to
zsh.
Decision Guide¶
Do you have root/sudo access?
├── Yes → Do you want desktop/UI tools?
│ ├── Yes → Full Mode
│ └── No → Server Mode
└── No → Dotfiles Only Mode
Deploying to Work/Corporate Servers?
For professional environments with security and compliance requirements, see the dedicated Work Environments Guide which covers:
- Corporate policy considerations
- Personal vs work separation strategies
- Git identity management
- Secrets isolation for work servers
Dotfiles Only (No Root Required)¶
The lightest deployment - applies config files without installing packages or tools.
Prerequisites¶
Install chezmoi:
Deploy¶
# Standard deployment
chezmoi init --apply jerdaw/dotfiles --exclude "run_once_*"
# Skip encrypted files (no age key available)
chezmoi init --apply jerdaw/dotfiles --exclude "run_once_*" --exclude encrypted
Minimal Clone (Slow Networks)¶
For deploying to many servers or slow connections:
git clone --filter=blob:none --sparse https://github.com/jerdaw/dotfiles ~/.local/share/chezmoi
cd ~/.local/share/chezmoi
git sparse-checkout set 'dot_*' '.chezmoi*'
chezmoi apply --exclude "run_once_*"
Server Mode (With Tools)¶
Installs server-safe tools via mise-server.toml, excluding desktop/UI applications.
What's Excluded¶
Server mode skips these desktop-only tools:
| Excluded Tool | Reason |
|---|---|
| yazi | TUI file manager (interactive) |
| lazygit | Git TUI (interactive) |
| lazydocker | Docker TUI (interactive) |
| atuin | Shell history sync daemon |
| glow | Terminal markdown viewer |
| lolcat | Rainbow text output |
| tinty | Theme manager |
| pnpm, bun | Extra JS runtimes |
| onefetch | Git repo summary |
| lnav | Log navigator |
Deploy¶
# Clone the repository
git clone https://github.com/jerdaw/dotfiles.git ~/repos/dotfiles
cd ~/repos/dotfiles
# Run bootstrap with server profile
./scripts/bootstrap --server
# OR with a specific profile
./scripts/bootstrap --profile minimal
Profiles¶
The bootstrap script supports profiles to customize the installed toolset:
- default: Installs everything in
mise.toml(Workstation). - server: Installs tools from
mise-server.toml(No GUI tools). - minimal: Installs dotfiles only, no tools.
Custom Profiles: You can create custom profiles in mise-profiles/<name>.toml and use them with --profile <name>.
Make Server Mode Permanent¶
To ensure mise always uses the server configuration:
Docker Deployment¶
Development Container¶
Use the provided example Dockerfile:
Multi-Stage Build¶
FROM ubuntu:24.04 AS base
RUN apt-get update && apt-get install -y curl git zsh
# Install chezmoi
RUN sh -c "$(curl -fsLS get.chezmoi.io)" -- -b /usr/local/bin
# Apply dotfiles (no packages, no encrypted files)
RUN chezmoi init --apply jerdaw/dotfiles \
--exclude "run_once_*" \
--exclude encrypted
CMD ["zsh"]
See examples/Dockerfile for a complete example.
Ansible Deployment¶
Use the provided playbook for fleet deployment:
The playbook:
- Installs chezmoi on target hosts
- Clones the dotfiles repository
- Applies dotfiles (excluding run_once scripts and encrypted files)
- Verifies key config files were created
See examples/ansible-playbook.yml for the full playbook.
CI/CD Deployment¶
Add dotfiles to your CI pipeline for consistent development environments:
# In your GitHub Actions workflow
- name: Install chezmoi
run: sh -c "$(curl -fsLS get.chezmoi.io)" -- -b /usr/local/bin
- name: Apply dotfiles
run: chezmoi init --apply jerdaw/dotfiles --exclude "run_once_*" --exclude encrypted
See examples/ci-deploy.yml for a complete reusable workflow.
Environment Variables¶
| Variable | Default | Description |
|---|---|---|
DOTFILES_DIR | ~/repos/dotfiles | Repository location |
SERVER_MODE | unset | Set to 1 to skip desktop tool checks in doctor |
MISE_CONFIG_FILE | mise.toml | Override to use mise-server.toml |
DOTFILES_SKIP_CHSH | unset | Set to 1 to skip changing default shell |
DOTFILES_SKIP_DOCTOR | unset | Set to 1 to skip health check after install |
Verification¶
After deployment, verify the installation:
# Check key files exist
[ -f ~/.bashrc ] && echo "bashrc: OK" || echo "bashrc: MISSING"
[ -f ~/.zshrc ] && echo "zshrc: OK (optional)" || echo "zshrc: MISSING (optional)"
[ -f ~/.gitconfig ] && echo "gitconfig: OK" || echo "gitconfig: MISSING"
[ -d ~/.config ] && echo "config dir: OK" || echo "config dir: MISSING"
# If mise is installed, run health check
mise run doctor
# Server-specific health check (skips desktop tools)
SERVER_MODE=1 mise run doctor
Troubleshooting¶
Template Errors During Apply¶
Fix: Chezmoi templates may reference variables set during chezmoi init. Run with --promptDefaults for non-interactive defaults:
Age Encryption Errors¶
Fix: Skip encrypted files when no age key is available:
Permission Denied on Shared Servers¶
If you don't have write access to standard locations:
# Install chezmoi to a user-writable location
sh -c "$(curl -fsLS get.chezmoi.io)" -- -b "$HOME/.local/bin"
export PATH="$HOME/.local/bin:$PATH"
# Apply dotfiles normally
chezmoi init --apply jerdaw/dotfiles --exclude "run_once_*"
Shell Strategy on Servers¶
By design, server mode keeps bash as default. If you want zsh on a specific host:
# Option 1: Set in SSH config on the client side
# ~/.ssh/config
# Host myserver
# RequestTTY yes
# RemoteCommand zsh -l
# Option 2: One-off per session
exec zsh
Related Documentation¶
- Architecture - System diagrams
- Testing - CI pipeline details
- Troubleshooting - General troubleshooting
- Secrets - Age encryption setup