diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..51ab1bc --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.bak.* diff --git a/README.md b/README.md new file mode 100644 index 0000000..892419d --- /dev/null +++ b/README.md @@ -0,0 +1,92 @@ +# bootstrap + +Turn a fresh Debian/Ubuntu/Arch VPS into a familiar workstation in one command. Detects the distro, installs a curated CLI package set, sets up zsh + oh-my-zsh with your ported config, brings your nvim config, hardens sane system defaults, and reports state. + +## Usage + +```sh +curl -fsSL | bash +# run everything non-interactively: +curl -fsSL | bash -s -- --yes +# run a single step: +curl -fsSL | bash -s -- --only packages +``` + +The shortener points at the **raw `install.sh`** in this repo, which clones the +full repo to `~/.bootstrap` and runs `setup.sh`. To update: `cd ~/.bootstrap && +git pull` (or just re-run the one-liner — it pulls existing clones). + +Re-run individual steps locally after the initial bootstrap: + +```sh +bash ~/.bootstrap/setup.sh --only shell-zsh +bash ~/.bootstrap/setup.sh --only hardening +``` + +## Steps + +| # | step | what it does | +|---|-------------|--------------------------------------------------------------------| +| 0 | preflight | verify distro + network + privileges | +| 1 | packages | git, byobu, ufw, mosh, btop, eza, fzf, ripgrep, bat, zoxide, jq, fd, tree, ncdu, lazygit, starship, … (+ `yay` on Arch) | +| 2 | docker | Docker engine + compose v2 plugin, `$USER` in `docker` group | +| 3 | angie | Angie (nginx fork) web server | +| 4 | shell-zsh | zsh + oh-my-zsh + plugins, set default shell, ship config | +| 5 | nvm | nvm → `~/.nvm` + Node LTS | +| 6 | nvim | clone `g.mk.fo/bootstrap/nvim-minimal` → `~/.config/nvim` | +| 7 | hardening | ssh (key-only root), ufw, updates, unattended-upgrades, tz, hostname, swapfile, locale, fail2ban | +| 8 | sanity | read-only report + recommended manual follow-ups | + +Every step is idempotent — re-running is safe. + +## Zsh plugins enabled (oh-my-zsh) + +`git sudo command-not-found colored-man-pages extract copypath dirhistory` +plus, cloned into `$ZSH_CUSTOM`: `zsh-autosuggestions`, +`zsh-syntax-highlighting` (loaded last), `zsh-completions`, +`history-substring-search`, `fzf-tab`. Prompt: **starship**. + +## Config layout (shipped to `~/.config/zsh`) + +``` +config/zsh/ + zshrc # main config (sources the pieces below) + path.zsh # PATH + env (XDG, EDITOR, LANG, nvm, pnpm) + aliases.zsh # ported from fish + curated defaults + aliases-extras.zsh # your personal additions (preserved across re-runs) + functions.zsh # mcd, conf, so, ssh-wrapper, dot-expansion + plugins.zsh # omz plugin list + load oh-my-zsh +``` + +`~/.zshrc` is a tiny shim that sets `ZDOTDIR=~/.config/zsh` and sources the +real config there — keeps omz "happy" while your config lives under XDG. + +## Hardening choices + +- **SSH**: `PermitRootLogin prohibit-password` + `PasswordAuthentication no`. + Root key login stays available; password login is disabled. A backup is + made and `sshd -t` runs before reload. **Always keep your current session + open and test a new login before closing it.** +- **ufw**: deny incoming, allow `22/tcp`, `60000:61000/udp` (mosh), + `80,443/tcp` (angie). +- **updates + unattended-upgrades** (Debian), system upgrade on Arch. +- **timezone** (default UTC), **hostname** (optional). +- **swapfile** 2G if RAM < 2G and no swap present. +- **locale** en_US.UTF-8. +- **fail2ban** with an sshd jail. + +## Supported hosts + +- Debian / Ubuntu (via apt) +- Arch (via pacman + yay for AUR) +- Architectures: `amd64`, `arm64` + +## Notes + +- `aliases-extras.zsh` is seeded once and then left alone — re-running the + shell-zsh step won't clobber your personal aliases. +- On Debian, `fd`/`bat` ship as `fdfind`/`batcat`; symlinks to the canonical + names are created in `~/.local/bin` (which is on `PATH` via `path.zsh`). +- Some Go/Rust CLIs (`dust`, `duf`, `procs`, `lazygit`) are fetched from + the latest GitHub release tarball when the distro package is missing; this + is best-effort and warned (not fatal) on failure. \ No newline at end of file