Meet Good Boy: My Zero-Dependency FreeBSD Bootstrapper
I built a little tool that I’ve lovingly named Good Boy.
It is a tiny, zero-dependency bootstrapper for fresh FreeBSD installs, written as one plain sh script.
I made it over the last two days for my homelab, where I spin up jails often. I wanted a faster, simpler way to get these environments up and running.
Why’d I make this?
I’ve written provisioning scripts before, but they were always a little more complicated than I wanted.
In the name of being DRY, I had split things into multiple function files. Each playbook lived in its own file. Everything lived in a Git repo. That was clean, sure… but before you could do anything useful, you had to do lots of steps:
- Install and configure Git
- Generate SSH keys and add them to your Git account
- Clone the repo
- Install Bash
- Then, you could get started
I wanted to make a simpler version. Something that could run on a baseline FreeBSD install with no extra dependencies. No Bash, no Git, no cloned repo. Just the native sh shell and the tools already available on the system.
The idea
Good Boy is one self-contained script.
All the playbooks live inside that one file. Supporting source files, like dotfiles or config files, can live somewhere remote… but only the script itself needs to be downloaded to kick things off.
That makes the script a little bigger and a little more obtuse initially, but it reduces the overall complexity dramatically.
All you need to get started (after customizing your script, of course…)
fetch https://example.com/good-boy.sh
chmod +x good-boy.sh
./good-boy.sh base
./good-boy.sh user
./good-boy.sh famp
One file, one command. Multiple playbooks. Good boy!
What it does
Right now, Good Boy is mostly built around the things I tend to do on fresh FreeBSD systems. It has playbooks for baseline setup, user setup, and initializing a FAMP stack.
The base playbook handles things like package updates, installing my usual utilities, configuring doas, enabling the locate database, and cleaning up some junk leftover from some installs. Some VPS snapshots leave a lot of debugging files laying around, and disk space is valuable there.
The user playbook handles my user-specific setup: shell aliases, dotfiles, SSH authorized keys, hushlogin, and SSH key generation.
The FAMP playbook installs and configures MariaDB, Apache, PHP and php-fpm… then ties everything together with a demo virtualhost.
Good Boy is not trying to be Ansible, or Salt. It is not trying to be a full configuration management system. It’s not built to manage fleets of servers from a single pane of glass. It is just a smol bootstrapper that does the tedious early setup work for you… and does it fast!
Partially idempotent, in a “good-enough” way
Good Boy aims to be partially idempotent.
Some commands are safe to run again. There’s some built-in sanity checks, like whether files or directories already exist. Changed config files get backed up with a timestamp before being replaced.
However… some commands may be destructive if run repeatedly. So, use Good Boy with care.
Why not just use Ansible?
Good Boy is not meant to replace serious configuration management. It’s meant to solve a smaller problem: Getting a fresh FreeBSD system from “brand new” to “ready enough.”
Closing thoughts
Good Boy started as an experiment to see if I could make a useful FreeBSD bootstrapper with zero dependencies, staying within the limitations of the built-in sh shell. It was a little fun labor of love for the last two days. And now I’m happy and proud to release it into the wild!
So far, Good Boy does exactly what I wanted: Makes fresh systems much faster and much less tedious.
Is it perfect? …No.
Is it production-grade enterprise configuration management? …Also no.
Does it sit, stay, and bootstrap a fresh jail without needing Git first? …Yes.
What a Good Boy!