An idempotent setup system for fresh Ubuntu and Arch Linux installations. All setup code lives in os-setup/, with distro-specific logic isolated under os-setup/<distro>/ and shared resources in os-setup/common/.
Run the main entrypoint (auto-detects OS):
./os-setup/setup.shOr run directly for your distro:
./os-setup/ubuntu/setup.sh # Ubuntu
./os-setup/arch/setup.sh # Arch LinuxInstall only specific modules:
OS_SETUP_MODULES="01-basic-tools,02-nginx" ./os-setup/ubuntu/setup.shFor automation or CI/CD:
DEBIAN_FRONTEND=noninteractive TZ=UTC ./os-setup/ubuntu/setup.sh| Module | Description |
|---|---|
01-basic-tools |
fnm, fzf, oh-my-posh, git-utils (SSH key management) |
02-nginx |
Nginx web server, UFW firewall |
03-php |
PHP-FPM and extensions from ondrej/php PPA |
04-mariadb-and-phpmyadmin |
MariaDB, phpMyAdmin at http://db.localhost |
05-apps |
Brave Browser, Signal Desktop |
| Module | Description |
|---|---|
01-postinstall |
Hyprland, Waybar, SDDM, hyprlock, libinput-gestures |
02-basic-tools |
fnm, fzf, oh-my-posh, git-utils (SSH key management) |
03-nginx |
Nginx web server |
04-php |
PHP-FPM and extensions |
05-mariadb-and-phpmyadmin |
MariaDB, phpMyAdmin at http://db.localhost |
06-apps |
Brave Browser, Signal Desktop |
Custom git helpers for managing multiple SSH identities:
git-init- Set git identity for a repositorygit-clone- Clone using SSH aliases (e.g.,git-clone me:user/repo)git-fix- Convert HTTPS remotes to SSH
Edit os-setup/<distro>/setup.sh and comment out unwanted modules:
DEFAULT_MODULES=(
"01-basic-tools"
"02-nginx"
# "03-php" # Disabled
# "04-mariadb-and-phpmyadmin" # Disabled
"05-apps"
)- Create directory:
os-setup/<distro>/NN-my-module/ - Add
setup.shscript - Make it executable:
chmod +x setup.sh - Add to
DEFAULT_MODULESinos-setup/<distro>/setup.sh
Test Ubuntu setup in Docker:
make test-ubuntu # Run test
make test-ubuntu-clean # Clean and re-test
make clean # Remove all test artifactsLogs saved to .sandbox/test-ubuntu.log.
-
Restart terminal or run
source ~/.bashrc -
Install Node.js (if fnm was installed):
fnm install --lts fnm use lts-latest
-
Add SSH keys to GitHub/GitLab:
cat ~/.ssh/id_ed25519_<keyname>.pub
-
Access phpMyAdmin (if installed):
http://db.localhost
- Ubuntu 20.04+ or Arch Linux
- Sudo privileges (do not run as root)
- Internet connection
- Docker (optional, for testing)
- Idempotent: Safe to run multiple times
- Modular: Each module is self-contained and can be skipped
- Deterministic: Modules run in numbered order
- Non-interactive: No prompts except where explicitly needed (git-utils)
- Robust: Bash strict mode (
set -euo pipefail)
- Scripts require sudo but must not be run as root
- MariaDB uses
unix_socketauthentication - SSH keys generated with ed25519
Permission denied:
chmod +x os-setup/setup.shCommand not found after install:
source ~/.bashrcNginx config test:
sudo nginx -tPersonal dotfiles configuration. Use at your own risk.