Bootstrap an Ubuntu/Debian based system effortlessly. This script is idempotent, allowing you to re-run it at any time. Existing changes are detected and ignored, and you are only prompted for uninstalled changes.
When you first login to a new linux box, you have many default packages you typically install:
- Your dotfiles
- nodenv
- Standard utilities like
git
, midnight commander,jq
,direnv
(here's my article on it), etc
I've experimented with multiple ways to do this (and there are many). This seems to be the easiest way to maintain and expand as your preferences change.
- Fork the repo (natually)
- Install bashing
- If you want to use some/all of my defaults:
- Remove whatever packages you don't want out of
src/tasks/all.sh
(and delete those files insrc/tasks/___.sh
)
- Remove whatever packages you don't want out of
- If you would like to start from scratch:
- Setup my repo as a remote:
git remote add drmikecrowe https://github.com/drmikecrowe/linux-bootstrap.git
- Checkout the
blank
branch:git checkout -b blank drmikecrowe/blank
- Make your changes
- Push your changes back to your master:
git push origin blank:master
- If you get a
blank -> master (non-fast-forward)
message:- Force-push your update:
git push origin blank:master --force
- Force-push your update:
- Setup my repo as a remote:
NOTE: Make sure to read the Default GUI Packages section below
The genius of this system is how easy it is to add new items:
- Run the
./stub.sh abc
to addabc
assrc/tasks/abc.sh
- Edit
src/tasks/abc.sh
:- Add a test to determine if
abc
is already installed - Add the code to install it
- Add a test to determine if
- Build using
./build.sh
and push to your repo - If you use the
cat <<EOF >>somefile
in the install function, you need to useEOF
to terminate your block of lines (see How it works below)
Whenever I find a new GUI package that I always want on any system, I add it to src/tasks/default_gui_packages.sh
as follows:
- Add the package on line 11 to the end of the
sudo apt install
- Use that packages executable to in the test in line 6 so it's missing the next time you run
Download the main script and make it executable:
prefix=~/.local/bin
curl -Lo ${prefix}/bootstrap.sh https://github.com/corriander/system-bootstrap/releases/latest/download/bootstrap.sh
chmod +x ${prefix}/bootstrap.sh
bootstrap.sh all
You can see all the options as follows:
bootstrap.sh
You can also install a single item like this:
./bootstrap.sh pyenv
Assuming you want the option to install everything (bootstrap.sh all
:
./build.sh
./target/bootstrap.sh all
This script uses Bashing to create the executable.
The key things I like to install are:
- My dotfiles
- Bash-it
- Node via nodenv
- Go via goenv
- Python via pyenv
- xonsh
- docker
- AWS cli
- etckeeper
- Increase fs.inotify.max_user_watches by increasing to 524288
- Remove password prompt when executing
sudo
If it's a GUI based system:
- Install my favorite GUI packages like
glogg
meld
synaptic
kupfer
remmina
- Visual Studio Code
- Opera
- Spotify
- TerraForm
- Peek gif recorder
- google-chrome
- copyq
- wavebox
- etc.
- Each task you answer (Y)es to writes the install steps from each install function (such as
install_dotfiles
) to~/_todo.sh
- All the commands in
~/_todo.sh
are run to install your choices - This system takes advantage of the bash
type
command. Each install script has this line:
type install_goenv | sed '1,3d;$d' | sed 's/^\s*//g' >> $RUNFILE
- This line essentially prints the install function, then I use
sed
to remove the function declarations and leading spaces - I like using the
cat <<EOF >>somefile
when writing lots of lines. Unfortunately, Bashing indents the code when it builds thetarget/bootstrap-1.0.0.sh
, so my./build.sh
makes sure that anyEOF
on a line by itself has no leading spaces