Linux Development Environment Setup
Categories:
This guide documents the maintained Linux contributor workflow for Indexly.
Use it when your goal is: “I want an Ubuntu/Linux workstation that can develop Project-Indexly, build the Hugo/Docsy docs, and use the same shell/editor conventions as the maintained dotfiles workflow.”
Supported Setup Modes
There are two supported ways to run the Linux bootstrap.
| Mode | Best for | Command shape |
|---|---|---|
| Standalone bundle | New machines, machines without the full dotfiles repo, or your normal Linux runtime flow | cd ~/dotfiles-linux && ./bootstrap.sh |
| Full repo mode | Maintaining the dotfiles repo itself or testing shared repo changes | cd ~/dev/configs/dotfiles && ./bootstrap |
The standard/default Linux workflow is the standalone bundle:
cp -a ~/dev/configs/dotfiles/dotfiles-linux ~/dotfiles-linux
cd ~/dotfiles-linux
./bootstrap.sh
If a new machine does not have the full dotfiles repo, copy or download the dotfiles-linux directory to ~/dotfiles-linux first, then run the same bootstrap command.
What The Linux Bootstrap Sets Up
The Linux suite is Bash-first and keeps Homebrew for Linux as the shared package layer.
It manages:
~/.bashrc~/.gitconfig~/.tmux.conf~/.config/nvim~/.config/starship/starship.toml~/dev/tools/indexly-docs~/bin/dev~/bin/dev-new
It backs up existing non-symlink targets before replacing them. Backup files use names such as:
~/.bashrc.backup.20260424-213000
Fresh Ubuntu Flow
On a clean Ubuntu machine, install the minimum bootstrap prerequisites first:
sudo apt-get update
sudo apt-get install -y git curl ca-certificates
Then get the Linux bundle onto the machine and run it:
cd ~
# Copy dotfiles-linux here by git checkout, archive, scp, rsync, or your preferred transfer method.
cd ~/dotfiles-linux
./bootstrap.sh
After bootstrap, restart the terminal or run:
source ~/.bashrc
Then inspect the available helper commands:
show-help
Full Dotfiles Repo Flow
If the full dotfiles repo is present:
mkdir -p ~/dev/configs
cd ~/dev/configs
git clone git@github.com:kimsgent/dotfiles.git
cd dotfiles
./bootstrap
This mode is useful when you are editing shared dotfiles files such as the Neovim config, Starship config, or project helper scripts.
How Symlink Priority Works
The symlink script is designed for both workflows.
The active local profile normally points at the standalone bundle:
~/.bashrc -> ~/dotfiles-linux/.bashrc
~/.config/starship/starship.toml -> ~/dotfiles-linux/config/starship/starship.toml
~/.config/nvim -> ~/dotfiles-linux/config/nvim
That keeps day-to-day shells stable even while the source repo is being edited.
When run from ~/dotfiles-linux, the symlink script prefers bundled files inside:
~/dotfiles-linux/config/
~/dotfiles-linux/tools/
When run from the full dotfiles repo, it can prefer shared repo files such as:
~/dev/configs/dotfiles/nvim
~/dev/configs/dotfiles/.config/starship/starship.toml
~/dev/configs/dotfiles/git/.gitconfig
To force shared repo mode from a standalone location, set DOTFILES_ROOT explicitly:
DOTFILES_ROOT=~/dev/configs/dotfiles ~/dotfiles-linux/bootstrap.sh
For normal Linux use, keep the live profile linked to ~/dotfiles-linux and use update-lp when repo changes need to be copied into that local bundle.
Installed Tooling
The bootstrap installs apt prerequisites, Homebrew for Linux when needed, and Homebrew packages from dotfiles-linux/Brewfile.
Core CLI/global tooling includes:
gitghneovimtmuxfzfzoxideripgrepbatezafddirenvstarshipjqshellcheckshfmtpyenvnvmrbenvruby-build
Project-Indexly docs tooling includes:
- Hugo Extended
- Go
- Node LTS through
nvm - npm
- local PostCSS/Pagefind dependencies from
docs/package.json - Pandoc/ImageMagick-related utilities for docs and asset workflows
Project-Indexly Docs Helper
After bootstrap, use idxdocs from any shell where the managed .bashrc is loaded:
idxdocs verify
idxdocs serve
idxdocs build-local
idxdocs build-prod
idxdocs smoke
idxdocs update-modules
idxdocs brew-test
The commands do the following:
| Command | Purpose |
|---|---|
idxdocs verify |
Checks Hugo Extended, Go, Node, npm, local PostCSS, and local Pagefind |
idxdocs serve |
Runs the local Hugo docs server through npm run dev |
idxdocs build-local |
Runs the existing docs build script |
idxdocs build-prod |
Runs a production-style Hugo build plus local Pagefind |
idxdocs smoke |
Confirms docs/public and Pagefind output exist after a build |
idxdocs update-modules |
Runs Hugo module update, tidy, and vendor flow |
idxdocs brew-test |
Tests brew tap kimsgent/indexly, installs/reinstalls indexly, and runs indexly --version |
Direct path equivalent:
~/dev/tools/indexly-docs verify
Project-Indexly Repo Setup
Once the workstation is ready:
mkdir -p ~/dev/projects
cd ~/dev/projects
git clone git@github.com:kimsgent/project-indexly.git
cd project-indexly
python -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -e ".[documents,analysis,visualization,pdf_export]"
python -m pip install pytest pytest-cov flake8 black isort mypy build twine hatch
Verify:
indexly --help
indexly show-help
indexly doctor
pytest -q
Updating The Linux Environment
There are three update paths, and they intentionally do different jobs.
Sync Repo Changes Into The Local Profile
On a development machine, the full repo is the source of truth and ~/dotfiles-linux is the live local profile bundle. After changing files in:
~/dev/configs/dotfiles/dotfiles-linux
run:
update-lp
update-lp copies the repo bundle into ~/dotfiles-linux, then relinks managed files from the local bundle. This is the command to use after editing the repo version of Bash, Starship, Neovim, Git, tmux, or helper scripts.
Dry run:
update-lp --dry-run
On a non-development machine where ~/dev/configs/dotfiles is absent, update-lp exits with a friendly “nothing changed” message.
Relink The Already-Synced Local Bundle
Use this when the local bundle is already correct and you only need to recreate symlinks:
update-profile
This relinks from ~/dotfiles-linux. It does not copy from the source repo.
Update Packages And Tooling
Use the managed package update helper:
update-system
Dry run:
update-system --dry-run
Reload Current Shells
Existing terminal sessions do not automatically reload a changed .bashrc. After update-lp or update-profile, run:
reload-profile
New terminal windows pick up the updated profile automatically.
Useful Shell Commands
The Linux profile exposes a small discoverable command surface:
show-help
Common helpers include:
idxdocsfor Project-Indexly documentation tasksupdate-lpto sync repodotfiles-linuxchanges into the live~/dotfiles-linuxbundleupdate-profileto relink managed files from the already-synced local bundlegstatus/gstfor Git statusgbranch/gbrfor Git branches without opening a pagergcheckout/gcofor branch checkoutgpull/gplfor fast-forward pullsreload-profileto reload~/.bashrcbootstrap-linuxto call the Linux bootstrap directly
The profile intentionally leaves gs available for Ghostscript on Linux.
Ubuntu Support Notes
Validated environment:
- Ubuntu 24.04.4 LTS
- Bash
- GNOME on Wayland
- Homebrew for Linux
Expected support:
- Ubuntu 22.04 or newer
- closely related Debian-based systems with
apt-get, Bash, sudo, and network access to GitHub, Homebrew, and npm registries
Wayland note: the shell setup does not force Wayland-only environment variables. It should also work from SSH, TTY, and X11 sessions.
Known Limits
- GUI app installation is documented in the dotfiles README but is not forced by bootstrap.
- SSH config is not bundled into standalone
dotfiles-linux; this avoids copying machine-specific credentials or host policy. update-lpis mainly for development machines with~/dev/configs/dotfiles; standalone machines can keep usingupdate-profileandupdate-system.- Netlify still runs its configured production command.
idxdocs build-produses local Pagefind for repeatable local validation. project-indexly/setup.ps1remains Windows-specific. Linux contributors should use the Bash/bootstrap and Python virtual environment flow above.
Rollback
For any replaced file, find the timestamped backup next to it:
ls -la ~ | grep backup
Restore example:
rm ~/.bashrc
mv ~/.bashrc.backup.YYYYMMDD-HHMMSS ~/.bashrc
For symlinked config directories, remove the symlink and restore the backup directory if one was created:
rm ~/.config/nvim
mv ~/.config/nvim.backup.YYYYMMDD-HHMMSS ~/.config/nvim