Workstation Setup
This chapter prepares your local machine for everything that follows. You'll install every CLI tool the course uses, authenticate with the services it depends on, and run a smoke test that proves each tool works. Nothing here costs money; the cluster doesn't exist yet.
Prerequisites
- The orientation read.
- A GitHub account.
- A DigitalOcean account with billing enabled.
What you will install
| Tool | Why we need it | Version this course was written against |
|---|---|---|
docker (or Podman) | Build images locally and feed them to kind. | 25.x or newer |
node / npm | Run and test the Express app. | Node.js 20 LTS |
kubectl | The Kubernetes CLI. | 1.30+ |
helm | Install kube-prometheus-stack, cert-manager, Traefik, others. | 3.14+ |
kustomize | Manage manifests with base + overlays. | 5.x |
k9s | Terminal UI for navigating the cluster fast. | 0.32+ |
kind | Run Kubernetes locally for early chapters. | 0.31+ |
doctl | Create droplets, the container registry, Spaces, Load Balancers. | 1.104+ |
gh | Drive GitHub from the terminal (workflows, branch protection, secrets). | 2.50+ |
kubeseal | Encrypt secrets so they can be committed safely. | 0.27+ |
trivy | Scan images and manifests for vulnerabilities. | 0.55+ |
jq, curl, git | Everyday helpers used by snippets in this course. | recent |
You don't need to match versions exactly. Anything newer than the listed minimum is fine; if you hit a behavior change, the chapter that uses the tool calls it out.
Step 1 — Pick your shell
Use either bash or zsh. Both are fine. The course only assumes POSIX shell features. Verify:
echo "$SHELL"
# /bin/bash or /bin/zsh
If you use fish, the commands in this course still work because each example invokes a real binary; only export syntax differs. When you see export FOO=bar, in fish write set -x FOO bar.
macOS: install GNU coreutils
A few snippets in later chapters assume GNU userland behavior, for example a sed -i form without an explicit suffix, or a date -d 'N hours ago'. The course tries hard to use portable forms (e.g. date +%s arithmetic instead of date -d), but install GNU coreutils on macOS anyway so you have gsed, gdate, gawk, etc. when a snippet does drift:
brew install coreutils gnu-sed gawk
# To make GNU versions the default (without overriding macOS defaults), prepend
# the gnubin paths only for this course's shell:
echo 'export PATH="$(brew --prefix coreutils)/libexec/gnubin:$(brew --prefix gnu-sed)/libexec/gnubin:$PATH"' >> ~/.zshrc
Linux users can skip this section.
Step 2 — Install Docker
You need a container runtime locally for kind and for building the app image. Docker is the default; Podman with a docker alias also works.
Linux (Fedora / RHEL family):
sudo dnf install -y dnf-plugins-core
sudo dnf config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo
sudo dnf install -y docker-ce docker-ce-cli containerd.io
sudo systemctl enable --now docker
sudo usermod -aG docker "$USER"
# log out and back in so the group change takes effect
Linux (Debian / Ubuntu family):
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker "$USER"
# log out and back in
macOS: install Docker Desktop from the official download page, then launch it once.
Verify:
docker version
docker run --rm hello-world
Expected: the second command prints the "Hello from Docker!" banner.
Step 3 — Install Node.js (LTS) and npm
Linux (any distro): use nvm so you can switch versions later:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
# open a new shell, then:
nvm install --lts
nvm use --lts
macOS: either brew install node@20 or use nvm as above.
Verify:
node --version # v20.x
npm --version # 10.x
Step 4 — Install the Kubernetes client tools
You can install these one at a time. The course assumes all of them are on your PATH.
kubectl
Linux:
KREL="$(curl -L -s https://dl.k8s.io/release/stable.txt)"
curl -LO "https://dl.k8s.io/release/${KREL}/bin/linux/amd64/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
rm kubectl
macOS:
brew install kubectl
Verify:
kubectl version --client
# Client Version: v1.30.x (or newer)
helm
Linux:
curl -fsSL https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
macOS:
brew install helm
Verify: helm version.
kustomize
kubectl ships an embedded Kustomize, but a few features in this course need the standalone binary.
Linux/macOS:
curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash
sudo mv kustomize /usr/local/bin/
Verify: kustomize version.
k9s
Linux: download the latest release from the releases page and unpack into /usr/local/bin. Or use Homebrew on Linux: brew install derailed/k9s/k9s.
macOS: brew install k9s.
Verify: k9s version.
kind
# Linux
go install sigs.k8s.io/kind@v0.31.0 # if you have Go
# or grab the binary:
curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.31.0/kind-linux-amd64
chmod +x ./kind && sudo mv ./kind /usr/local/bin/kind
# macOS
brew install kind
If you used go install, the binary lands in Go's bin directory ($(go env GOPATH)/bin, usually ~/go/bin). That directory isn't on PATH by default, so the shell won't find kind until you add it:
echo 'export PATH="$PATH:$(go env GOPATH)/bin"' >> ~/.bashrc # or ~/.zshrc
source ~/.bashrc # or ~/.zshrc
Verify: kind --version.
Step 5 — Install the platform CLIs
doctl
# Linux
cd /tmp
curl -sL https://github.com/digitalocean/doctl/releases/download/v1.159.0/doctl-1.159.0-linux-amd64.tar.gz | tar -xzv
sudo mv doctl /usr/local/bin
# macOS
brew install doctl
Verify: doctl version.
gh
Linux (Fedora):
sudo dnf install -y gh
Linux (Debian/Ubuntu):
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \
| sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] \
https://cli.github.com/packages stable main" \
| sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null
sudo apt update && sudo apt install -y gh
macOS: brew install gh.
Verify: gh --version.
Step 6 — Install the security and secrets tools
kubeseal
# Linux
KSV=0.36.6
curl -OL "https://github.com/bitnami-labs/sealed-secrets/releases/download/v${KSV}/kubeseal-${KSV}-linux-amd64.tar.gz"
tar -xvzf kubeseal-${KSV}-linux-amd64.tar.gz kubeseal
sudo install -m 755 kubeseal /usr/local/bin/kubeseal
rm kubeseal kubeseal-${KSV}-linux-amd64.tar.gz
# macOS
brew install kubeseal
Verify: kubeseal --version.
trivy
# Linux
sudo dnf install -y trivy # Fedora
# or, on any Linux:
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sudo sh -s -- -b /usr/local/bin
# macOS
brew install trivy
Verify: trivy --version.
Step 7 — Shell completion
Set up completion now. You'll type these commands hundreds of times.
# bash
mkdir -p ~/.local/share/bash-completion/completions
kubectl completion bash > ~/.local/share/bash-completion/completions/kubectl
helm completion bash > ~/.local/share/bash-completion/completions/helm
gh completion -s bash > ~/.local/share/bash-completion/completions/gh
# zsh
cat >> ~/.zshrc <<'EOF'
autoload -U compinit; compinit
source <(kubectl completion zsh)
source <(helm completion zsh)
source <(gh completion -s zsh)
EOF
Open a new shell and confirm kubectl <TAB> completes.
A useful alias for the rest of the course:
echo 'alias k=kubectl' >> ~/.bashrc
echo 'complete -F __start_kubectl k' >> ~/.bashrc
Step 8 — SSH key for GitHub and DigitalOcean
If you don't already have one:
ssh-keygen -t ed25519 -C "$(whoami)@$(hostname) — k8slearn"
# accept defaults; set a passphrase
Add the public key to GitHub:
gh ssh-key add ~/.ssh/id_ed25519.pub --title "k8slearn"
You'll add the same public key to DigitalOcean in Part 3 when you provision droplets.
Step 9 — Authenticate the CLIs
GitHub
gh auth login
# - GitHub.com
# - SSH protocol
# - Use your existing key
# - Login with a web browser
Verify:
gh auth status
# ✓ Logged in to github.com as <you>
DigitalOcean
In the DO control panel, go to API → Personal access tokens and create a token with full read and write scopes (you need write so doctl can create droplets, registries, Spaces, and Load Balancers later). Copy the token; you won't see it again.
doctl auth init
# paste the token at the prompt
doctl account get
Expected: your DO account email and team show up.
Step 10 — Smoke test
Save this as ~/k8slearn-smoke.sh and run it:
#!/usr/bin/env bash
set -euo pipefail
tools=(docker node npm kubectl helm kustomize k9s kind doctl gh kubeseal trivy jq curl git)
echo "=== version check ==="
for t in "${tools[@]}"; do
printf "%-10s : " "$t"
case "$t" in
docker) docker --version ;;
node) node --version ;;
npm) npm --version ;;
kubectl) kubectl version --client --output=yaml | grep gitVersion ;;
helm) helm version --short ;;
kustomize) kustomize version ;;
k9s) k9s version --short 2>/dev/null || k9s version ;;
kind) kind --version ;;
doctl) doctl version | head -n1 ;;
gh) gh --version | head -n1 ;;
kubeseal) kubeseal --version ;;
trivy) trivy --version | head -n1 ;;
jq) jq --version ;;
curl) curl --version | head -n1 ;;
git) git --version ;;
esac
done
echo
echo "=== auth check ==="
gh auth status
doctl account get
Run:
chmod +x ~/k8slearn-smoke.sh
~/k8slearn-smoke.sh
Expected: every line prints a version. gh auth status reports you're logged in. doctl account get prints your account details. If anything fails, fix that tool before moving on; the next chapter assumes all of them work.
Completion signal
~/k8slearn-smoke.sh exits 0. kubectl version --client exits cleanly. gh auth status and doctl account get both succeed without errors. You can read your DO account name and your GitHub username from the smoke test output.
You're ready to move on to 02. Fundamentals (Local).