[ jd303 ]

This is the stack. Built on a Raspberry Pi 5 running Docker Compose, documented post by post as it gets built. The repo is live. Each service gets added as the corresponding post ships. I know this works because I've.. wiped out my server and had to use it.

Source: conspicuoustechnologist/ct-homelab on GitHub.

[ claude ]

The Series

PartServiceVersion
1nginx + dockerv1.1.0
2pi-hole dnsv1.2.0
3claude code on piv1.3.0
4samba file sharingv1.4.0
[ jd303 + claude ]

Nuke, Sleep, Pave, Repeat

The posts walk through every step so you understand what's happening. This is the short version, new Pi, same result, ten minutes.

All config lives in conspicuoustechnologist/ct-homelab on GitHub. Fork it, adapt .env.example to your setup, and you have your own version.

Bootstrap Script (Fresh Pi)

One command sets up a fresh Pi from scratch: installs zsh, oh-my-zsh, nvm, Node.js LTS, Claude Code, Docker, clones the repo, and drops you at the .env edit step.

curl -fsSL https://raw.githubusercontent.com/conspicuoustechnologist/ct-homelab/main/bootstrap.sh | sh

Read the script before running it. You should always do that before piping curl to sh.

Bootstrap pauses and asks you to review .env before starting the stack, edit it, then press Enter to continue. It starts the stack automatically when done.

If you need to activate the docker group in your current session without logging out:

newgrp docker

Already Have Docker?

If you're on a Pi that already has Docker and zsh set up, skip bootstrap and clone directly:

cd ~
git clone https://github.com/conspicuoustechnologist/ct-homelab.git
cd ct-homelab
cp .env.example .env
nano .env

The .env file is gitignored, your values stay local, never committed.

TZ=America/Denver
HOSTNAME=raspberrypi
DOMAIN=ct.home
MAIN_SITE_DIR=$HOME/sites/ct-site
MAIN_SITE_HOST=conspicuoustechnologist.ct.home

Bring it up:

docker compose up -d

[ launch ]