configs
Devices#
PC Master Race
- OS: Kubuntu 26.04 LTS
- CPU: AMD Ryzen 5 3600
- GPU: AMD Radeon RX 6800 16 GB
- RAM: 32 GB (4×8 GB GeIL Super Luce DDR4 3200 MHz)
- NVMe: 1 TB (2×512 GB Adata XPG Spectrix S40G)
- Motherboard: ASUS TUF Gaming X570-PRO (Wi-Fi)
- Mouse: Logitech G305
- Keyboard: HyperX Alloy Origins Core with Razer Pink PBT keycaps
- Headphones: Audio-Technica ATH-M50x with FiiO BTA10 and Sony Inzone H9
Base installation#
Kubuntu 26.04 installed in UEFI mode. Both NVMe drives use LUKS2.
System disk:
- 1 GiB EFI system partition
- 4 GiB ext4
/boot - LUKS2 -> LVM
- 96 GiB Btrfs
/with subvolumes/@and/@swap - 370 GiB XFS
/homeon a 357 GiB VDO pool with compression and deduplication - 4 GiB swap file at
/swap/swapfile
Data disk:
- LUKS2 -> LVM VDO -> 470 GiB XFS
/data - 453 GiB physical VDO pool with compression and deduplication
- Automatic unlock with a key stored on the encrypted system disk; separate recovery passphrase
BIOS#
- Load optimized defaults
- Set RAM to 3200 MHz with DOCP/XMP
- Enable Above 4G Decoding
- Enable Resizable BAR
- Enable SVM Mode / AMD-V
- Disable Secure Boot
- Disable CSM
- Tune fan curves for silence
Linux#
GRUB#
sudo tee /etc/default/grub.d/99-preempt.cfg > /dev/null << 'EOF'
GRUB_CMDLINE_LINUX_DEFAULT="$GRUB_CMDLINE_LINUX_DEFAULT preempt=full"
EOF
sudo update-grub
LUKS performance#
The persistent options are in /etc/crypttab:
system_crypt UUID=<system-luks-uuid> none luks,discard,no-read-workqueue,no-write-workqueue
data_crypt UUID=<data-luks-uuid> /etc/cryptsetup-keys.d/data_crypt.key luks,discard,no-read-workqueue,no-write-workqueue,nofail
Verify the live mappings:
sudo cryptsetup status system_crypt
sudo cryptsetup status data_crypt
no-read-workqueue/no-write-workqueuebypass the internal dm-crypt workqueues on the NVMe drives.discardpasses discard requests through LUKS. This helps the SSD and VDO reclaim deleted blocks, but reveals allocation patterns.- The data-disk key is protected at rest by the system disk’s LUKS encryption.
Filesystems and VDO#
Relevant /etc/fstab entries:
UUID=<root-btrfs-uuid> / btrfs subvol=/@,defaults,noatime,compress=zstd:3,discard=async 0 0
UUID=<home-xfs-uuid> /home xfs defaults,noatime 0 2
UUID=<root-btrfs-uuid> /swap btrfs subvol=/@swap,defaults,noatime 0 0
/swap/swapfile none swap defaults 0 0
UUID=<data-xfs-uuid> /data xfs defaults,noatime,nofail,x-systemd.device-timeout=30s 0 2
Both XFS filesystems have VDO compression and deduplication below them. Each VDO pool uses 95% of its volume group’s initial free space. The remaining extents let LVM extend a pool if physical usage becomes high.
# /etc/lvm/lvm.conf
activation {
vdo_pool_autoextend_threshold=70
vdo_pool_autoextend_percent=5
}
Automatic extension requires dmeventd to monitor each VDO pool. Check that seg_monitor reports monitored in the lvs output.
sudo lvs -a -o name,vg_name,lv_size,segtype,data_percent,seg_monitor,vdo_compression,vdo_deduplication
sudo vdostats --human-readable
sysctl#
sudo tee /etc/sysctl.d/99-zram.conf > /dev/null << 'EOF'
vm.swappiness = 150
EOF
sudo tee /etc/sysctl.d/99-inotify.conf > /dev/null << 'EOF'
fs.inotify.max_user_instances = 8192
fs.inotify.max_user_watches = 524288
fs.inotify.max_queued_events = 16384
EOF
sudo sysctl --system
zram#
sudo apt install systemd-zram-generator && \
sudo tee /etc/systemd/zram-generator.conf > /dev/null << 'EOF'
[zram0]
zram-size = ram / 2
compression-algorithm = zstd
swap-priority = 100
EOF
sudo systemctl daemon-reload && sudo systemctl start dev-zram0.swap
Btrfs swap file#
sudo swapoff /swap/swapfile && \
sudo rm -f -- /swap/swapfile && \
sudo btrfs filesystem mkswapfile --size 4G /swap/swapfile && \
sudo swapon /swap/swapfile
Disk swap stays as a fallback when zram fills up.
OOM#
sudo apt install systemd-oomd && \
sudo systemctl enable --now systemd-oomd.service
CPU#
powerprofilesctl set performance
Intel AX200 WiFi#
sudo mkdir -p /etc/modprobe.d && \
sudo tee /etc/modprobe.d/iwlwifi-fix.conf > /dev/null << 'EOF'
options iwlmvm power_scheme=1
EOF
NetworkManager#
sudo tee /etc/NetworkManager/conf.d/99-mac-address-policy.conf > /dev/null << 'EOF'
[connection]
wifi.cloned-mac-address=stable
EOF
sudo systemctl restart NetworkManager
Packages#
apt#
apt_packages=(
# Build and development
autoconf automake bear build-essential clang cmake
libfuse-dev libfuse3-dev libtool meson ninja-build pkg-config
python-is-python3 python3-dev python3-full python3-venv valgrind
# Shell and CLI
ble.sh direnv jo thefuck universal-ctags xmlstarlet
# Networking and security
aria2 axel hashcat httpie
nethogs nload nmap redis-tools speedtest-cli ssh sshpass
torbrowser-launcher tshark whois wireshark
# Audio, video, and images
audacity ffmpegthumbnailer gifsicle handbrake mpv optipng pamixer
pdfgrep playerctl pngquant tidy vlc
# Containers and virtualization
buildah cockpit cockpit-podman criu distrobox libvirt-daemon-system podman
podman-docker podman-toolbox qemu-system-x86 virt-manager
# Hardware and desktop
adb brightnessctl ddcui ddcutil fastboot filelight flatpak gamemode ghostty
kde-config-flatpak openrgb
plasma-discover-backend-flatpak ydotool
# Languages and spell checking
aspell-es fcitx5-mozc hunspell-es hyphen-en-us hyphen-es
mythes-en-us mythes-es
# System utilities and maintenance
antiword bleachbit btop cabextract clamav diffoscope duf expect firejail
hw-probe hyperfine inotify-tools iotop-c ncdu needrestart nvtop procs
timeshift trash-cli tree unrar
# Fun
cmatrix fortune-mod sl toilet
)
sudo apt install "${apt_packages[@]}"
if command -v fdfind >/dev/null; then
mkdir -p "$HOME/.local/bin" && \
ln -sfn "$(command -v fdfind)" "$HOME/.local/bin/fd"
fi
User permissions#
sudo usermod -aG kvm,libvirt "$USER"
sudo usermod -aG wireshark "$USER"
ROCm#
sudo apt install rocm rocm-podman-support && \
sudo usermod -aG render,video "$USER"
Log out and back in.
APT security auto-updates#
sudo apt install unattended-upgrades && \
sudo tee /etc/apt/apt.conf.d/20auto-upgrades > /dev/null << 'EOF'
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Download-Upgradeable-Packages "1";
APT::Periodic::AutocleanInterval "7";
APT::Periodic::Unattended-Upgrade "1";
EOF
Ubuntu Pro#
sudo pro attach
pro status
External repos#
extrepo#
extrepo manages external repositories. Search with extrepo search, enable with extrepo enable.
sudo apt install extrepo && \
sudo extrepo enable brave_release librewolf steam tailscale vscode && \
sudo apt update && \
sudo apt install brave-browser code librewolf steam tailscale && \
sudo tailscale up
Package managers and runtimes#
Homebrew#
/bin/bash -c "$(curl --proto '=https' --tlsv1.2 -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" && \
eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" && \
brew install atuin bat cowsay croc editorconfig eza fd fnm gh glab go hugo just \
lazygit magic-wormhole moreutils neovim pandoc pipx pre-commit ripgrep-all \
shellcheck shfmt starship tealdeer tmux topgrade ugrep uv yq yt-dlp zoxide
Topgrade config#
mkdir -p "$HOME/.config" && \
cat > "$HOME/.config/topgrade.toml" << 'EOF'
[misc]
assume_yes = true
cleanup = true
ask_retry = false
notify_end = "on_failure"
EOF
pnpm global#
eval "$(fnm env --use-on-cd --shell bash)" && \
fnm install --lts --use && \
fnm default "$(fnm current)" && \
(command -v corepack >/dev/null || npm install --global corepack@latest) && \
corepack enable pnpm && \
corepack install --global pnpm@latest && \
mkdir -p "$HOME/.local/share/pnpm" && \
pnpm config set global-bin-dir "$HOME/.local/share/pnpm" --location=global
npm / pnpm security#
Hardening against supply chain attacks: block install scripts and avoid newly published packages.
npm: don’t run third-party scripts
npm config set ignore-scripts true --location=user
Bun: block scripts and newly published packages
cat > "$HOME/.bunfig.toml" << 'EOF'
[install]
ignoreScripts = true
minimumReleaseAge = 86400
EOF
With this, npm won’t run dependency preinstall or postinstall scripts. Bun blocks scripts and packages published less than 1 day ago (86400 seconds). pnpm 11+ already applies a built-in 1-day release-age policy in non-strict mode, so no extra global setting is needed.
Script installs#
Bun#
curl --proto '=https' --tlsv1.2 -fsSL https://bun.sh/install | bash
Rust / Cargo#
curl --proto '=https' --tlsv1.2 -fsSL https://sh.rustup.rs | sh
Apps#
Nerd Fonts#
brew install --cask font-hack-nerd-font font-ubuntu-mono-nerd-font && fc-cache -fv
Flatpak#
flatpak remote-add --if-not-exists flathub \
https://flathub.org/repo/flathub.flatpakrepo
flatpak install flathub \
com.github.wwmm.easyeffects com.github.PintaProject.Pinta \
com.github.tchx84.Flatseal com.obsproject.Studio \
com.obsproject.Studio.Plugin.OBSVkCapture//stable com.spotify.Client \
com.stremio.Stremio com.usebottles.bottles com.vysp3r.ProtonPlus \
dev.vencord.Vesktop io.github.flattool.Warehouse \
io.github.hedge_dev.hedgemodmanager io.podman_desktop.PodmanDesktop \
it.mijorus.gearlever net.lutris.Lutris net.retrodeck.retrodeck \
org.freedesktop.Platform.VulkanLayer.OBSVkCapture//25.08 org.gimp.GIMP \
org.kde.isoimagewriter org.kde.kdenlive org.kde.krita org.kde.yakuake \
org.libreoffice.LibreOffice \
org.localsend.localsend_app org.qbittorrent.qBittorrent org.signal.Signal \
org.telegram.desktop
Android Studio#
sudo snap install android-studio --classic
The Setup Wizard downloads the SDK to ~/Android/Sdk.
Zed#
curl --proto '=https' --tlsv1.2 -fsSL https://zed.dev/install.sh | sh
Codex#
curl --proto '=https' --tlsv1.2 -fsSL https://chatgpt.com/codex/install.sh | sh
Codex Desktop#
curl -fsSL -o /tmp/chatgpt.deb \
https://persistent.oaistatic.com/codex-app-prod/linux/deb/latest/chatgpt_amd64.deb && \
sudo apt install /tmp/chatgpt.deb && \
rm -- /tmp/chatgpt.deb
Trezor Suite#
Download Trezor Suite as an AppImage and manage it with Gear Lever.
Timeshift#
sudo timeshift-gtk
Config:
- Type: Btrfs
- Location: Btrfs root on the system disk
- Schedule: daily + weekly + boot
- Keep: 3 daily, 3 boot, 2 weekly
/homeand/data: not included; both are separate XFS filesystems
Shell & terminal#
Ghostty#
mkdir -p "$HOME/.config/ghostty" && \
tee "$HOME/.config/ghostty/config.ghostty" > /dev/null << 'EOF'
background-opacity = "0.9"
font-family = "UbuntuMono Nerd Font"
font-size = "14"
theme = "Dark Pastel"
window-height = "32"
window-width = "100"
EOF
profile#
~/.profile:
# path helper
path_prepend() {
[ -d "$1" ] || return 0
case ":$PATH:" in
*":$1:"*) ;;
*) export PATH="$1:$PATH" ;;
esac
}
# local bin
path_prepend "$HOME/bin"
path_prepend "$HOME/.local/bin"
# android sdk
export ANDROID_HOME="$HOME/Android/Sdk"
path_prepend "$ANDROID_HOME/cmdline-tools/latest/bin"
path_prepend "$ANDROID_HOME/emulator"
path_prepend "$ANDROID_HOME/platform-tools"
# bun
export BUN_INSTALL="$HOME/.bun"
path_prepend "$BUN_INSTALL/bin"
# homebrew
if [ -x /home/linuxbrew/.linuxbrew/bin/brew ]; then
eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
fi
# pnpm
export PNPM_HOME="$HOME/.local/share/pnpm"
path_prepend "$PNPM_HOME"
# rust/cargo
[ -r "$HOME/.cargo/env" ] && . "$HOME/.cargo/env"
# solana
path_prepend "$HOME/.local/share/solana/install/active_release/bin"
# opencode
path_prepend "$HOME/.opencode/bin"
# grok
path_prepend "$HOME/.grok/bin"
# foundry
path_prepend "$HOME/.foundry/bin"
# if running bash
if [ -n "$BASH_VERSION" ]; then
# include .bashrc if it exists
if [ -r "$HOME/.bashrc" ]; then
. "$HOME/.bashrc"
fi
fi
bashrc#
~/.bashrc:
# ble.sh - load first, attach last
[[ $- == *i* && -r /usr/share/blesh/ble.sh ]] && source -- /usr/share/blesh/ble.sh --attach=none
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return 0 ;;
esac
HISTCONTROL=ignoreboth:erasedups
shopt -s histappend
HISTSIZE=100000
HISTFILESIZE=100000
shopt -s checkwinsize
shopt -s globstar
[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"
if [ -x /usr/bin/dircolors ]; then
if [ -r "$HOME/.dircolors" ]; then
eval "$(dircolors -b "$HOME/.dircolors")"
else
eval "$(dircolors -b)"
fi
alias grep='grep --color=auto'
alias egrep='grep -E --color=auto'
alias fgrep='grep -F --color=auto'
fi
# aliases
alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'
if [ -r "$HOME/.bash_aliases" ]; then
. "$HOME/.bash_aliases"
fi
if ! shopt -oq posix; then
if [ -r /usr/share/bash-completion/bash_completion ]; then
. /usr/share/bash-completion/bash_completion
elif [ -r /etc/bash_completion ]; then
. /etc/bash_completion
fi
fi
# fnm
command -v fnm >/dev/null && eval "$(fnm env --use-on-cd --shell bash)"
# starship
command -v starship >/dev/null && eval "$(starship init bash)"
# thefuck - lazy load
if command -v thefuck >/dev/null; then
fuck() {
unset -f fuck
eval "$(thefuck --alias)"
fuck "$@"
}
fi
# fzf
command -v fzf >/dev/null && eval "$(fzf --bash)"
# zoxide
command -v zoxide >/dev/null && eval "$(zoxide init bash)"
# atuin
if command -v atuin >/dev/null; then
if [[ ${BLE_VERSION-} ]]; then
eval "$(atuin init bash --disable-up-arrow)"
ble-bind -x 'C-r' '__atuin_history'
else
eval "$(atuin init bash)"
fi
fi
# grok completion
command -v grok >/dev/null && [[ -r "$HOME/.grok/completions/bash/grok.bash" ]] && source "$HOME/.grok/completions/bash/grok.bash"
# ble.sh attach
[[ ! ${BLE_VERSION-} ]] || ble-attach
Services and networking#
Podman socket#
systemctl --user enable --now podman.socket
SSH#
sudo systemctl enable --now ssh
UFW#
sudo apt install ufw && \
sudo ufw default deny incoming && \
sudo ufw default allow outgoing && \
sudo ufw allow OpenSSH && \
sudo ufw allow kdeconnect && \
sudo ufw enable
Gaming#
Eden#
Download Eden (Nintendo Switch emulator) as an AppImage and manage it with Gear Lever. Use the amd64 PGO build for best performance.
Sonic Unleashed Recompiled#
Download the Flatpak from Unleashed Recompiled and install it. You need the Sonic Unleashed Xbox 360 game files (US or EU), title update, and optionally the DLC (recommended, includes high quality lighting).
wget -O /tmp/UnleashedRecomp-Flatpak.zip \
https://github.com/hedge-dev/UnleashedRecomp/releases/latest/download/UnleashedRecomp-Flatpak.zip && \
unzip -o /tmp/UnleashedRecomp-Flatpak.zip -d /tmp/UnleashedRecomp && \
flatpak install /tmp/UnleashedRecomp/*.flatpak && \
rm -rf -- /tmp/UnleashedRecomp /tmp/UnleashedRecomp-Flatpak.zip
Steam#
- Enable Steam Play
- Launch options per game:
gamemoderun %command%
- Install Proton-CachyOS or Proton-GE with ProtonPlus
Half-Life / Portal / Counter-Strike#
-vulkan -novid -fullscreen
Sonic Adventure#
Use Adventure Mods to configure mods for Sonic Adventure DX and Sonic Adventure 2 on Linux.
Install the Flatpak:
flatpak install https://flatpak.4st.li/io.github.astrovm.AdventureMods.flatpakref
Open Adventure Mods and follow the setup wizard.
GTA IV#
Install Grand Theft Auto IV: The Complete Edition from Steam.
Install FusionFix: download GTAIV.EFLC.FusionFix.zip and extract it to the game’s root folder, where the .exe is.
Steam launch options:
WINEDLLOVERRIDES="dinput8=n,b" %command%
Git#
git config --global user.name "astrovm" && \
git config --global user.email "[email protected]" && \
git config --global init.defaultBranch main && \
git config --global pull.rebase true && \
git config --global rebase.autoStash true && \
git config --global core.autocrlf input && \
git config --global core.pager bat && \
git config --global fetch.prune true && \
git config --global rerere.enabled true
Require an explicit push refspec:
git config --global push.default nothing
Use a global pre-push hook to prevent direct pushes to main and master:
mkdir -p "$HOME/.config/git/hooks"
git config --global core.hooksPath "$HOME/.config/git/hooks"
cat > "$HOME/.config/git/hooks/pre-push" <<'EOF'
#!/bin/sh
while read local_ref local_oid remote_ref remote_oid; do
case "$remote_ref" in
refs/heads/main|refs/heads/master)
echo "Blocked: direct pushes to ${remote_ref#refs/heads/} are not allowed." >&2
echo "Create a branch and open a pull request instead." >&2
exit 1
;;
esac
done
exit 0
EOF
chmod +x "$HOME/.config/git/hooks/pre-push"
ssh-keygen -t ed25519 -C "[email protected]" && \
eval "$(ssh-agent -s)" && \
ssh-add "$HOME/.ssh/id_ed25519" && \
cat "$HOME/.ssh/id_ed25519.pub"
Paste the public key into https://github.com/settings/ssh.