A reproducible, security-conscious developer workstation for CachyOS + GNOME.
Modern web development, AI coding agents, containers, databases, remote access, media tools and everyday productivity — documented, scripted and verifiable.
Verified against GNOME Shell 50.5 on Wayland · last audit 2026-10-02
This repository documents and automates a professional CachyOS developer workstation from a clean installation to a complete daily-driver environment.
It is designed around:
- CachyOS / Arch Linux
- GNOME + Catppuccin Mocha (Colloid GTK3/GTK4, Tela-circle icons, Bibata cursor)
- GNOME Shell extensions (dash-to-dock, blur-my-shell, Vitals, user-theme, gsconnect, tilingshell, just-perfection)
- Ghostty (+ Ptyxis, Alacritty)
- zsh + oh-my-zsh + Powerlevel10k (CachyOS system packaging), fish retained as fallback
- Git + GitHub
- Node.js, npm, pnpm, Bun
- Python + pipx
- PostgreSQL + sqlite3
- Podman
- Playwright
- Postman
- Zed (VS Code optional)
- Firefox + Chrome + Zen + Brave
- Claude Code, Codex, Kiro CLI, Pi, OpenCode, Herdr, Hermes
- Oh My Pi / Oh My Claude / Oh My Codex (oh-my-claude-sisyphus via npm)
- Tailscale
- Caddy
- Proton VPN
- Kooha (+ OBS Studio optional) + KTorrent
- Obsidian
- Thunderbird
- Telegram Desktop (
telegram-desktoppackage; binary name differs — verify withpacman -Ql) - SSHFS
- Modern CLIs: bat, eza, btop, fastfetch, duf, ripgrep, fd, fzf, delta, lazygit, zoxide, go-yq
- Terminal workflow: neovim, tmux, mosh (for Tailscale SSH sessions)
- Runtime management: mise (Node/Python versions), uv (Python projects)
- Encrypted secrets: age + sops
- UFW and additional system hardening
The goal is repeatability without blindly copying a personal machine configuration.
This repository is a setup guide and automation starting point, not a universal one-click installer.
Review each phase before executing it on another machine.
Do not commit:
- SSH private keys
- API keys
- cloud credentials
.envfiles containing secrets- Tailscale auth keys
- GitHub tokens
- AI provider credentials
- browser profiles
- personal databases
- personal shell history
Internet
│
┌────────────┴────────────┐
│ │
Proton VPN Tailscale
│ │
│ Private remote access
│ │
Normal outbound SSH / services
│ │
└────────────┬────────────┘
│
┌─────────▼─────────┐
│ CachyOS + GNOME │
└─────────┬─────────┘
│
┌──────────────────────┼──────────────────────┐
│ │ │
Development AI Infrastructure
│ │ │
Node / Bun / pnpm Claude / Codex PostgreSQL
Python / Playwright Kiro / Pi Podman
VS Code / Zed OpenCode / Herdr Caddy
│ │ │
└──────────────────────┼──────────────────────┘
│
Daily productivity
│
Obsidian / Thunderbird / Telegram
OBS / Kooha / KTorrent
cachyos-dev-workstation/
├── README.md
├── CLAUDE.md
├── LICENSE
├── .gitignore
├── docs/
│ ├── 00-overview.md
│ ├── 01-installation.md
│ ├── 02-base-system.md
│ ├── 03-gnome.md
│ ├── 04-development.md
│ ├── 05-ai-tooling.md
│ ├── 06-browsers-editors.md
│ ├── 07-databases-containers.md
│ ├── 08-networking.md
│ ├── 09-security.md
│ ├── 10-productivity-media.md
│ ├── 11-verification.md
│ ├── 12-maintenance.md
│ ├── 13-terminals.md
│ ├── 14-shell.md
│ └── 15-cli-tooling.md
├── scripts/
│ ├── 00-system-update.sh
│ ├── 01-base-packages.sh
│ ├── 02-development.sh
│ ├── 03-ai-tools.sh
│ ├── 04-applications.sh
│ ├── 05-security-audit.sh
│ ├── 06-cli-tooling.sh
│ ├── 07-gnome-theming.sh
│ └── verify.sh
├── assets/
│ └── cachyos.svg
└── .github/
└── workflows/
└── markdown.yml
The scripts are intentionally separated. You can execute the documentation manually or use the scripts as a starting point.
| Document | Covers | |
|---|---|---|
| 🗺️ | 00-overview | Scope and design goals |
| 💽 | 01-installation | Clean CachyOS install |
| 🧱 | 02-base-system | Base packages, build tools |
| 🎨 | 03-gnome | GNOME, Catppuccin theming, extensions |
| 🛠️ | 04-development | Languages and runtimes |
| 🤖 | 05-ai-tooling | AI coding agents and MCP |
| 🌐 | 06-browsers-editors | Browsers, Zed, VS Code |
| 🗄️ | 07-databases-containers | PostgreSQL, Podman |
| 🔗 | 08-networking | Tailscale, Caddy, SSHFS |
| 🔐 | 09-security | UFW, SSH hardening, age/sops |
| 📦 | 10-productivity-media | Obsidian, OBS, Kooha |
| ✅ | 11-verification | Drift detection |
| 🔄 | 12-maintenance | Updates and upkeep |
| 🖥️ | 13-terminals | Ghostty, Ptyxis, Alacritty |
| 🐚 | 14-shell | zsh + oh-my-zsh, the PATH trap |
| ⚡ | 15-cli-tooling | Modern CLI replacements |
Install CachyOS using the official installer and select:
- GNOME
- UEFI
- your intended filesystem
- your intended bootloader
- your normal user account
Then reboot into the installed system.
CachyOS provides multiple desktop environments through its current installer, including GNOME.
git clone https://github.com/RavenRepo/cachyos-dev-workstation.git
cd cachyos-dev-workstationbash scripts/00-system-update.sh
bash scripts/01-base-packages.sh
bash scripts/02-development.sh
bash scripts/03-ai-tools.sh
bash scripts/04-applications.sh
bash scripts/05-security-audit.sh
bash scripts/06-cli-tooling.sh
bash scripts/07-gnome-theming.sh
bash scripts/verify.shDo not run all phases blindly on an existing machine. Read the corresponding documentation first.
| Phase | Purpose |
|---|---|
| 00 | System update and baseline |
| 01 | Git, build tools, shell (zsh stack + fish fallback) and common utilities |
| 02 | Node, Bun, pnpm, Python, PostgreSQL, Podman, Playwright |
| 03 | AI coding agents and agent runtimes |
| 04 | Browsers, editors, terminals, themes, VPN, productivity and media |
| 05 | Security audit helpers |
| 06 | Terminal editor, multiplexer, git tooling, runtime managers, secrets tooling |
| 07 | GNOME theming (Catppuccin Mocha, GTK3 + GTK4, icons, panel) — no root |
| Verify | Validate the installation |
Update first:
sudo pacman -SyuInstall core tooling:
sudo pacman -S --needed \
base-devel \
git \
curl \
wget \
unzip \
zip \
jq \
ripgrep \
fd \
fzf \
tree \
rsync \
openssh \
man-db \
man-pages \
bat \
eza \
btop \
fastfetch \
duf \
sqlite3Install the AUR helper used by this setup:
sudo pacman -S --needed yayVerify:
git --version
yay --version
curl --version
rg --version
bat --version
eza --version
sqlite3 --versionThis workstation uses zsh with oh-my-zsh and Powerlevel10k as the primary interactive shell. fish is retained as a fallback.
Full detail, including the migration procedure and the PATH trap described
below, is in docs/14-shell.md.
sudo pacman -S --needed \
zsh oh-my-zsh-git cachyos-zsh-config zsh-theme-powerlevel10k \
zsh-autosuggestions zsh-completions zsh-syntax-highlighting \
zsh-history-substring-searchAll of these are in official CachyOS/extra repositories. The AUR is not
needed.
CachyOS packages oh-my-zsh system-wide at /usr/share/oh-my-zsh, not
~/.oh-my-zsh, and pacman owns updates.
source /usr/share/cachyos-zsh-config/cachyos-config.zshThat single line provides the Powerlevel10k instant prompt, ZSH=/usr/share/oh-my-zsh,
plugins=(git fzf extract), oh-my-zsh itself, and the p10k theme. Do not clone
oh-my-zsh into $HOME on top of it, and do not run upgrade_oh_my_zsh. Custom
plugins belong in $ZSH_CUSTOM.
A clean zsh login does not inherit ~/.local/bin or ~/.bun/bin. fish gets
them from fish_add_path in cachyos-config.fish; the CachyOS zsh config has no
equivalent. Since the AI agent CLIs live in ~/.local/bin and bun/omp live
in ~/.bun/bin, running chsh without fixing PATH first removes the entire
agent toolchain from your shell.
This is invisible when testing from an existing session, because a child shell inherits the parent's PATH. Test with a scrubbed environment instead:
env -i HOME="$HOME" USER="$USER" TERM=xterm /usr/bin/zsh -ic 'print -l $path'Add the PATH block from docs/14-shell.md to ~/.zshrc above the
source line, then:
exec zsh -l
p10k configure
bash scripts/verify.sh
chsh -s /usr/bin/zsh # only after the above passesLog out and back in.
sudo pacman -S --needed fish cachyos-fish-configsource /usr/share/cachyos-fish-config/cachyos-config.fish
# disables the greeting and its fastfetch block
function fish_greeting
endReverting is chsh -s /usr/bin/fish. Keep ~/.config/fish/config.fish in
place so the fallback stays usable.
Note that fish is not POSIX-compatible, so the export VAR=... lines that
upstream curl | bash installers append to ~/.zshrc and ~/.bashrc have no
effect in fish and must be rewritten by hand. That is the main practical reason
this workstation prefers zsh.
Install GNOME components as needed:
sudo pacman -S --needed \
gnome-shell \
gnome-control-center \
gnome-tweaks \
gnome-keyring \
gnome-terminal \
nautilus \
file-roller \
xdg-user-dirsFor GNOME extensions:
sudo pacman -S --needed gnome-extensions-appVerify:
gnome-shell --version
gnome-extensions versionThis workstation uses Catppuccin Mocha: Colloid-Purple-Dark-Catppuccin
for GTK3 and GTK4/libadwaita, Tela-circle-purple-dark icons,
Bibata-Modern-Ice cursor, Adwaita Sans 11, purple accent, stock shell theme
with a rounded blurred panel.
bash scripts/07-gnome-theming.sh # no root requiredTwo things that trip up most GNOME theming guides:
- Nothing in GNOME Tweaks themes GTK4/libadwaita apps. "Legacy
Applications" sets the GTK3 theme only. GTK4 is themed exclusively by
~/.config/gtk-4.0/gtk.css, which is why the theme is built from source with vinceliuice's-lflag rather than installed from the AUR. - Open Bar does not support GNOME 50. Panel styling here goes through Blur
My Shell's
corner-radiuskey instead. Always check an extension against the extensions.gnome.org API before installing.
adw-gtk3-dark is the documented fallback if the custom theme becomes a
maintenance burden — it matches both toolkits, honours the native accent
colour, and survives GNOME upgrades untouched.
Full detail, verified findings and rollback snapshots: docs/03-gnome.md.
The reproducible extension list (dash-to-dock, blur-my-shell, Vitals,
user-theme, gsconnect, CoverflowAltTab, tilingshell, just-perfection) is in the
same document.
Ghostty is the primary terminal (Ptyxis and Alacritty as alternatives);
see docs/13-terminals.md. GNOME Terminal is intentionally not installed.
Recommended philosophy:
- keep the desktop minimal
- install extensions deliberately
- avoid extensions that duplicate core GNOME functionality
- remove abandoned extensions
- review extension compatibility after GNOME upgrades
- snapshot
dconf dump /org/gnome/before any theming change
Configure Git identity:
git config --global user.name "YOUR NAME"
git config --global user.email "YOUR_EMAIL"Recommended defaults:
git config --global init.defaultBranch main
git config --global pull.rebase false
git config --global fetch.prune true
git config --global core.editor "code --wait"Verify:
git config --global --listGenerate an Ed25519 key:
ssh-keygen -t ed25519 -C "YOUR_EMAIL"Start the agent:
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519Print the public key:
cat ~/.ssh/id_ed25519.pubAdd it to GitHub.
Test:
ssh -T git@github.comNever publish ~/.ssh/id_ed25519.
Install Node.js and npm from the system repositories:
sudo pacman -S --needed nodejs npmVerify:
node --version
npm --versionFor projects that require multiple Node versions, use a version manager rather than replacing system packages manually.
Install:
sudo pacman -S --needed pnpmVerify:
pnpm --versioncorepack is a separate extra package — it is not bundled with nodejs
or npm on Arch, and it is not installed by this setup. Standalone pnpm needs
no corepack enable step. Install the corepack package explicitly only if a
project requires it.
Install Bun using its upstream installer:
curl -fsSL https://bun.sh/install | bashReload your shell or source the generated environment.
Verify:
bun --versionInstall the system Python stack:
sudo pacman -S --needed \
python \
python-pip \
python-pipxInitialize pipx:
pipx ensurepathVerify:
python --version
pip --version
pipx --versionUse virtual environments for project dependencies.
Install:
sudo pacman -S --needed postgresqlInitialize the database cluster:
sudo -u postgres initdb -D /var/lib/postgres/dataEnable and start:
sudo systemctl enable --now postgresqlVerify:
systemctl status postgresql --no-pagerOpen PostgreSQL:
sudo -u postgres psqlCreate a development role/database according to the project instead of exposing PostgreSQL to the network by default.
Check listening sockets:
sudo ss -lntp | grep postgresPrefer local-only PostgreSQL for development.
Install:
sudo pacman -S --needed \
podman \
podman-compose \
buildah \
skopeoVerify:
podman --version
podman infoRootless containers are preferred.
Test:
podman run --rm docker.io/library/hello-worldCheck:
podman ps
podman imagesDo not globally expose container ports through the firewall. Audit each published port first.
For Node projects:
pnpm add -D playwrightInstall browsers:
pnpm exec playwright installFor a system-wide development environment, keep Playwright browser installation project-specific whenever possible.
Verify:
pnpm exec playwright --versionChoose one installation source.
Repository package:
sudo pacman -S --needed codeOr AUR binary package:
yay -S visual-studio-code-binDo not install both unless you intentionally need both variants.
Verify:
code --versionsudo pacman -S --needed zedVerify:
zeditor --versionyay -S --needed postman-binVerify with the real binary name:
command -v postmanInstall the browsers you actually use.
yay -S --needed \
google-chrome \
zen-browser-bin \
brave-binVerify:
Firefox ships with CachyOS GNOME. Verify with the real binary names:
google-chrome-stable --version
zen-browser --version
brave --version
firefox --versionKeep browser profiles separate from the configuration repository.
AI tools change quickly. Prefer their official installers and verify versions after installation.
Current upstream installation:
curl -fsSL https://claude.ai/install.sh | bashVerify:
claude --versionAuthenticate:
claudeDo not use sudo npm install -g @anthropic-ai/claude-code.
Current upstream installer:
curl -fsSL https://cli.kiro.dev/install | bashVerify:
kiro-cli --versionIf the command name differs in a future release, follow the current Kiro CLI documentation.
Install using the current official OpenAI instructions for your account/platform.
Keep authentication outside this repository.
Prefer the current upstream installer:
curl -fsSL https://opencode.ai/install | bashAlternatively, if the Arch package is current on your system:
sudo pacman -S --needed opencodeVerify:
opencode --versionHerdr is an AI-agent runtime, not Laravel Herd.
Install:
curl -fsSL https://herdr.dev/install.sh | shVerify:
herdr --versionInstall integrations as needed:
herdr integration install pi
herdr integration install omp
herdr integration install claude
herdr integration install codex
herdr integration install opencode
herdr integration install hermesOnly install integrations you actually use.
Observed on this workstation (2026-10-02): claude 2.1.287, codex 0.159.3,
kiro-cli 2.21.2, pi 0.87.1, herdr 0.9.3 (all ~/.local/bin via
upstream installers), opencode v2.0.11 (~/.opencode/bin via upstream
installer), omp 18.4.4
(~/.bun/bin/omp via Bun), plus hermes/hermes-acp/hermes-agent v0.21.1,
antigravity (IDE v2.13.0, ~/.local/bin), agent-memory, jev-gate.
npm global: oh-my-claude-sisyphus, neon, llm-checker. Bun global:
@oh-my-pi/pi-coding-agent. Agent state (~/.claude/,
~/.codex/config.toml) stays out of Git. Details: docs/05-ai-tooling.md.
This setup can include:
Claude Code
Codex
Kiro CLI
Pi
OpenCode
Herdr
Oh My Pi
Oh My Claude
Oh My Codex
Hermes
Treat each tool as an independent executable.
Do not put:
- provider tokens
- MCP credentials
- agent secrets
- personal prompts containing secrets
- private project data
into this repository.
Recommended MCP categories:
Codebase MCP
Context7
Sequential Thinking
Exa
Browserbase
Install and configure them at the appropriate agent/client layer.
Do not copy credentials into Git.
A safe repository pattern is:
docs/
ai-tooling.md
examples/
mcp.example.json
.local/
# ignored
Use placeholders in example configuration.
Install using the official package/instructions appropriate for your system.
sudo pacman -S --needed tailscaleEnable:
sudo systemctl enable --now tailscaledAuthenticate:
sudo tailscale upCheck:
tailscale status
tailscale ip
tailscale netcheckTailscale should be the preferred path for private remote access.
Avoid exposing SSH globally to the public internet.
If you intentionally use Tailscale SSH:
sudo tailscale set --sshThen verify:
tailscale debug prefs
tailscale statusTailscale SSH still depends on your tailnet access policy.
Do not assume that knowing a Tailscale IP automatically grants SSH access.
Install:
sudo pacman -S --needed opensshCreate a drop-in:
sudo nano /etc/ssh/sshd_config.d/10-hardening.confSuggested baseline:
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitEmptyPasswords no
PubkeyAuthentication yes
X11Forwarding no
MaxAuthTries 3
LoginGraceTime 20
ClientAliveInterval 300
ClientAliveCountMax 2
Before restarting SSH, validate the configuration:
sudo sshd -tThen:
sudo systemctl restart sshdIf your workflow uses Tailscale SSH exclusively, do not expose TCP/22 globally through UFW.
Check current status:
sudo ufw status verboseSet the baseline:
sudo ufw default deny incoming
sudo ufw default allow outgoingEnable:
sudo ufw enableDo not blindly run:
sudo ufw allow 22/tcpFor this workstation, SSH should preferably remain private through Tailscale.
Inspect:
sudo ufw status numberedRemove an accidental global SSH rule:
sudo ufw delete allow 22/tcpBefore opening any port:
sudo ss -lntupAlso inspect:
sudo ss -lntp
sudo ss -lnupCategorize every listener:
127.0.0.1 / ::1
Local-only service.
Tailscale IP
Private tailnet service.
0.0.0.0 / ::
Potentially network-accessible service.
Never open a port simply because an application says it can use one.
Caddy is intended for controlled reverse proxying and local/Tailscale service exposure.
Install:
sudo pacman -S --needed caddyVerify the binary before starting anything:
caddy versionRead the packaged configuration before enabling the unit, because enabling it starts a listener you have not reviewed:
cat /etc/caddy/Caddyfile
caddy validate --config /etc/caddy/CaddyfileOnce your own configuration is in place:
sudo systemctl enable --now caddy
systemctl status caddy --no-pager
sudo ss -lntp | grep caddyConfirm the bind address in that last command. 127.0.0.1 or a Tailscale
address is what you want for development; 0.0.0.0 means the machine is
serving the network.
Start with local services.
Example conceptual configuration:
service.example.internal {
reverse_proxy 127.0.0.1:3000
}
Do not publish a development application to the public internet until:
- authentication exists
- firewall rules are reviewed
- Caddy configuration is validated
- logs are monitored
- secrets are protected
Install:
sudo pacman -S --needed sshfsPrefer Tailscale addresses for remote machines.
Example:
mkdir -p ~/mnt/remote
sshfs user@tailscale-host:/path ~/mnt/remoteFor permanent mounts, use a systemd user mount rather than an ad-hoc shell command.
Unmount:
fusermount3 -u ~/mnt/remoteCurrent Arch installation:
sudo pacman -S --needed proton-vpn-gtk-app gnome-keyringProton VPN's Linux documentation also calls out NetworkManager and systemd-resolved requirements for relevant functionality.
Launch:
protonvpn-appDo not enable a VPN kill switch until you have tested interaction with:
- Tailscale
- UFW
- local development
- DNS
- Podman
- Caddy
A kill switch can intentionally break remote-access and development workflows if routing is not designed first.
Install:
sudo pacman -S --needed \
obsidian \
thunderbird \
telegram-desktopLaunch:
obsidian
thunderbird
telegram-desktopKeep application profiles outside this repository.
Install:
sudo pacman -S --needed obs-studioVerify:
obs --versionRecommended architecture:
Webcam
│
└── Rounded webcam overlay
│
Screen ──────┼──► OBS
│
Mic ─────────┘
For the described workflow:
- use the boAt earbuds microphone as the primary microphone
- avoid relying on desktop audio as the primary recording source
- configure PipeWire routing in OBS
- use mic filters
- keep desktop audio optional
sudo pacman -S --needed koohaLaunch:
koohaKooha is useful for quick screen recordings; OBS remains the full production workflow.
Install:
sudo pacman -S --needed ktorrentLaunch:
ktorrentDo not automatically open a torrent listening port through UFW.
First inspect:
sudo ss -lntupThen decide whether inbound peer connectivity is actually needed.
sudo pacman -Syusystemctl --failedsystemctl list-unit-files --state=enabledsudo ss -lntupsudo ufw status verbosetailscale status
tailscale netcheckls -ld ~
ls -ld ~/.sshSSH directory should normally be:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/* 2>/dev/null || true
chmod 644 ~/.ssh/*.pub 2>/dev/null || trueThis setup does not require AppArmor.
Security layers are instead built around:
- timely updates
- least privilege
- rootless containers
- UFW
- Tailscale private networking
- SSH key authentication
- systemd service management
- controlled reverse proxying
- careful port exposure
- secrets outside Git
- GitHub repository security
- application-level authentication
If you later add another mandatory access-control framework, document it as a separate architectural decision.
Never commit:
.env
.env.*
*.pem
*.key
id_rsa
id_ed25519
credentials.json
service-account.json
tokens.json
Use:
- environment variables loaded from a
600-mode file outside Git age+sopsfor secrets that must be versioned- GNOME Keyring
- application credential stores
- password managers
- secret managers
The machine-local pattern this workstation uses:
mkdir -p ~/.config/secrets && chmod 700 ~/.config/secrets
install -m 600 /dev/null ~/.config/secrets/env
# put `export SOME_API_KEY="..."` in that file, then in ~/.zshrc:
[[ -r "$HOME/.config/secrets/env" ]] && source "$HOME/.config/secrets/env"Do not assign credentials inline in .bashrc, .zshrc, or
.config/fish/config.fish. Those files are mode 644 by default, they end up
in dotfiles repositories, and the value leaks into ~/.bash_history as well.
scripts/verify.sh fails the build if it finds an inline export *KEY=,
*TOKEN=, or *SECRET= in a shell rc file.
Anything that has ever been in a shell rc file, a history file, or a Git object
must be rotated, not merely deleted. Full procedure in docs/09-security.md.
Recommended workspace:
~/Projects/ # active work (observed 2026-09-19: anatomy, ladder, stuntkit, ...)
├── personal/
├── work/
├── experiments/
├── open-source/
└── archived/
/mnt/kronos/Projects/ # bulk archive (129 entries observed 2026-09-19)
/mnt/kronos/jev/ # Jev risk gate (canonical, not a project workspace)
Example:
mkdir -p ~/Projects/{personal,work,experiments,open-source,archived}Keep ~/ root clean: ~/main, ~/src/theming, ~/postiz, ~/twenty,
~/researchdoc, stray ~/package.json / ~/node_modules belong under
~/Projects/ or /mnt/kronos/Projects/.
A typical project:
project/
├── .github/
├── docs/
├── src/
├── tests/
├── scripts/
├── public/
├── .env.example
├── .gitignore
├── README.md
├── package.json
└── pnpm-lock.yaml
Run:
bash scripts/verify.shManual verification:
echo "=== OS ==="
cat /etc/os-release
echo
echo "=== Kernel ==="
uname -r
echo
echo "=== Git ==="
git --version
echo
echo "=== Node ==="
node --version
echo
echo "=== pnpm ==="
pnpm --version
echo
echo "=== Bun ==="
bun --version
echo
echo "=== Python ==="
python --version
echo
echo "=== PostgreSQL ==="
psql --version
echo
echo "=== Podman ==="
podman --version
echo
echo "=== Tailscale ==="
tailscale version
echo
echo "=== Firewall ==="
sudo ufw status verbose
echo
echo "=== Listening sockets ==="
sudo ss -lntupMonthly:
sudo pacman -SyuReview AUR packages:
yayReview services:
systemctl --failedReview network exposure:
sudo ss -lntup
sudo ufw status numberedReview Tailscale devices:
tailscale statusReview containers:
podman ps -a
podman imagesReview PostgreSQL:
systemctl status postgresql --no-pagerReview Caddy:
systemctl status caddy --no-pagerWhen something breaks, inspect the system before changing configuration.
Use:
systemctl status SERVICE --no-pager
journalctl -u SERVICE -b --no-pager
ss -lntup
ip addr
ip route
resolvectl statusFor user services:
systemctl --user status SERVICE --no-pager
journalctl --user -u SERVICE -b --no-pagerFor PipeWire:
wpctl statusFor Tailscale:
tailscale status
tailscale netcheck
tailscale debug prefsFor firewall:
sudo ufw status verboseAvoid random fixes from old blog posts.
The following should remain deliberate:
- bootloader replacement
- disk partitioning
- filesystem formatting
- SSH key creation
- GitHub authentication
- Tailscale authentication
- VPN kill-switch activation
- firewall port opening
- public reverse proxy exposure
- database network exposure
- AI credentials
- browser profile migration
- secret manager configuration
- Baseline GNOME configuration (Catppuccin Mocha: Colloid GTK3+GTK4 / Tela-circle / Bibata,
docs/03-gnome.md) - GTK4/libadwaita theming solved via
~/.config/gtk-4.0/gtk.css(docs/03-gnome.md) - Root-free, idempotent theming phase (
scripts/07-gnome-theming.sh) - Reproducible GNOME extension list (
docs/03-gnome.md) - zsh + oh-my-zsh migration with the PATH trap documented (
docs/14-shell.md) - CLI tooling phase with verified package names (
docs/15-cli-tooling.md) - Machine-local secrets pattern +
age/sopsworkflow (docs/09-security.md) -
verify.shrewritten to detect repo/system drift instead of masking it - Add Caddy templates
- Add rootless Podman Quadlet examples
- Add systemd user SSHFS examples
- Add hardened sysctl profile
- Add security audit script
- Add workstation backup strategy (
resticrepository + systemd timer) - Add dotfiles repository integration (
stowlayout) - Decide on shared shell history (
atuin) across zsh and fish - Pick a password-manager CLI and wire
sopsto it - Add optional NVIDIA/Wayland tuning
- Replace the local
sasscextraction withpacman -S sassc libsass - Decide on floating panel (
--tweaks float) vs current rounded panel - Install
refinefor GNOME settings not exposed in Settings/Tweaks - Add developer project bootstrap scripts
- Add CI for Markdown/link validation
Official documentation should take precedence over this repository when software changes.
- CachyOS Wiki: https://wiki.cachyos.org/
- Arch Linux: https://archlinux.org/
- GitHub Docs: https://docs.github.com/
- Claude Code: https://code.claude.com/
- Kiro CLI: https://kiro.dev/cli/
- Tailscale: https://tailscale.com/docs/
- Proton VPN: https://protonvpn.com/support/linux-vpn-arch
MIT. See LICENSE.
- Contributing guide: ground rules, workflow, commit style
- Code of Conduct: Contributor Covenant 2.1
- Security policy: report vulnerabilities privately, not in public issues
- Bugs and feature requests: use the issue templates
Amit Kumar
Issues and pull requests welcome. Please do not include machine-specific credentials, hostnames or Tailscale keys in reports.
Built on CachyOS · themed with Catppuccin · themes by vinceliuice