Three Configurations to Preserve Your Existing Development Environment Before Installing Omarchy
Omarchy, an opinionated Arch Linux-based distribution released under the leadership of Basecamp, bundles the Hyprland tiling compositor and Quickshell desktop toolkit to present a sophisticated working interface right out of the box. While it is an appealing system for engineers fatigued by manual dotfiles management, simply overwriting your existing home directory will instantly break everything from your session manager.
To install Omarchy without breaking your existing Neovim, Docker containers, and custom shell environment, you must first isolate three specific points of conflict.
Isolating Configuration Files and Configuring a Git Bare Repository
Most boot failures during a distribution transition stem from conflicts between older runtime files outside the XDG specification and default system configurations. Omarchy places system configurations in /usr/share/omarchy and forces user override settings into ~/.config. If your previous hyprland.conf or Waybar stylesheet remains, it will clash with the Quickshell native modules (~/.config/omarchy/shell.json) and parameters, causing the screen to freeze during the Wayland handshake phase. Non-standard PATH or LD_LIBRARY_PATH variables left in shell scripts can also cause the default terminal to fail to capture graphics drivers and crash.
To preserve your setup's shape without disturbing your existing environment, you should use the Git bare repository pattern, which maps the working tree to your home directory. Approaches like GNU Stow that manually create symbolic links will halt operations if existing files are present, making rollbacks cumbersome.
`bash
git init --bare "HOME/.dotfiles.git"aliasdotfiles=′/usr/bin/git−−git−dir=HOME/.dotfiles.git/ --work-tree=HOME′dotfilesconfig−−localstatus.showUntrackedFilesnodotfilesadd /.config/nvim /.config/tmux /.zshrc /.gitconfigdotfilescommit−m"chore:snapshotpre−omarchy"dotfilesarchive−−format=tar.gz−o"HOME/pre_omarchy_backup_$(date +%Y%m%d).tar.gz" HEAD
`
After creating the backup archive, move conflicting desktop directories out of your home directory into an isolated folder:
`bash
mkdir -p "HOME/.configquarantine"fordirinhyprwaybarfootalacrittyrofi;do[−d"HOME/.config/dir" ] && mv "HOME/.config/dir""HOME/.config_quarantine/"
done
`
By tucking away the desktop configurations, the default Omarchy Quickshell will launch properly while keeping your code editor and terminal shell settings in their original state.
Kernel Isolation of AI Agents Using Bubblewrap
Omarchy deeply integrates AI coding tools like Claude Code and OpenCode into the desktop workflow. The problem is that these tools inherit the permissions of the host terminal directly. Since many runtimes only restrict subprocess execution without monitoring file I/O system calls, a prompt injection or unexpected script execution leaves folders like ~/.ssh, ~/.aws, ~/.gnupg, and Docker sockets completely exposed.
You need to construct a least-privilege execution environment using Bubblewrap, which handles unprivileged user namespaces in the Linux kernel. Overwriting sensitive authentication key folders with empty memory mounts can block read operations entirely.
`bash
#!/usr/bin/env bash
/usr/local/bin/agent-jail: Bubblewrap-based AI agent isolation runner
set -euo pipefail
WORKSPACE="{1:-(pwd)}"
DUMMY_DIR=(mktemp−d/tmp/jail−empty−XXXXXX)trap′rm−rf"{DUMMY_DIR}"' EXIT
exec bwrap
--ro-bind /usr /usr
--ro-bind /lib /lib
--ro-bind /lib64 /lib64
--ro-bind /bin /bin
--ro-bind /etc/resolv.conf /etc/resolv.conf
--ro-bind /etc/ssl /etc/ssl
--ro-bind /etc/ca-certificates /etc/ca-certificates
--proc /proc
--dev /dev
--tmpfs /tmp
--tmpfs "$HOME"
--bind "WORKSPACE""WORKSPACE"
--ro-bind "DUMMYDIR""HOME/.ssh"
--ro-bind "DUMMYDIR""HOME/.aws"
--ro-bind "DUMMYDIR""HOME/.gnupg"
--unshare-all
--share-net
--unshare-pid
--new-session
--die-with-parent
--setenv PATH "/usr/local/bin:/usr/bin:/bin"
--setenv HOME "$HOME"
--chdir "$WORKSPACE"
-- /usr/bin/opencode "$@"
`
You should also avoid hardcoding API keys in plain text within global environment variables. Create an ai.env file inside a ~/.config/secure-vault directory secured with chmod 700 permissions, set its permissions to chmod 600, and load it into a subshell only at the moment of script execution to prevent token leakage via /proc/$PID/environ inspection.
Neovim Native LSP Transition and Rootless Docker Mount Permission Correction
When porting an existing Neovim configuration to Omarchy, the Mason plugin breaks most frequently. Precompiled binaries downloaded by Mason from GitHub often conflict with the latest glibc symbols in a rolling release environment, throwing execution errors.
This issue disappears if you disable Mason's automated binary downloads and route LSP paths through native packages from the official Arch repositories. Omitting network download steps and wrapper layers also reduces initial editor loading times to under 30ms.
`lua
-- ~/.config/nvim/lua/plugins/lsp-native.lua
return {
{
"williamboman/mason.nvim",
opts = { auto_install = false },
},
{
"neovim/nvim-lspconfig",
opts = {
servers = {
gopls = { cmd = { "/usr/bin/gopls" } },
pyright = { cmd = { "/usr/bin/pyright-langserver", "--stdio" } },
rust_analyzer = { cmd = { "/usr/bin/rust-analyzer" } },
lua_ls = { cmd = { "/usr/bin/lua-language-server" } },
},
},
},
}
`
After configuring, install the binaries directly from the terminal:
`bash
sudo pacman -S --needed gopls pyright rust-analyzer lua-language-server ripgrep fd
`
The final hurdle is Docker. Omarchy uses rootless Docker by default. Because of the kernel's sub-UID mapping rules, an offset is created between the host's file ownership and the container's internal user permissions.
If the starting number assigned in the host's /etc/subuid is 100000, a standard user inside the container (UID 1000) is recognized from the host perspective as UID 100999 (100000+1000−1). This is why bind-mounting source code (-v $(pwd):/workspace) blocks write permissions and throws errors. Specifying POSIX Access Control List (ACL) inheritance rules on the project directory allows you to grant write permissions to container processes without cluttering host ownership.
`bash
#!/usr/bin/env bash
docker-rootless-align: Auto-correct rootless Docker sub-UID volume mount permissions
set -euo pipefail
TARGET_PATH="{1:-(pwd)}"
CURRENT_USER=$(whoami)
SUBUID_START=(grep "^{CURRENT_USER}:" /etc/subuid | cut -d: -f2 || true)
if [[ -z "SUBUIDSTART"]];thensudousermod−−add−subuids100000−165535−−add−subgids100000−165535"{CURRENT_USER}"
SUBUID_START=100000
fi
HOST_MAPPED_UID=$(( SUBUID_START + 1000 - 1 ))
setfacl -R -m "u:HOSTMAPPEDUID:rwx""TARGET_PATH"
setfacl -R -d -m "u:HOSTMAPPEDUID:rwx""TARGET_PATH"
sudo loginctl enable-linger "${CURRENT_USER}"
systemctl --user enable --now docker.service
`
Once configurations are complete, check active window instances with hyprctl instances in the terminal and verify LSP operation with nvim --headless "+checkhealth" +qa. Once the docker run --rm alpine ping -c 1 1.1.1.1 command successfully passes through the sub-namespace network, you are fully prepared to resume your daily development tasks.