chore: initial homelab stack config and sync tooling

Mirror the three production files (docker-compose.yml, .env, Caddyfile) that live on valhalla, plus the push/pull PowerShell scripts, CLAUDE.md, .gitignore/.gitattributes, and .claude/skills for ssh/apply/sync.
This commit is contained in:
ginnoir
2026-06-02 22:12:07 -05:00
commit 56d834ede9
11 changed files with 1426 additions and 0 deletions
+37
View File
@@ -0,0 +1,37 @@
---
name: homelab-apply
description: Push local config changes (docker-compose.yml, .env, Caddyfile) to the valhalla server and apply them to the live Docker stack. Use after editing homelab config to deploy it. This mutates the running production stack.
---
# homelab-apply
Deploys local repo changes to the live stack on valhalla. **This mutates production** — sync and review your diff first (see the `homelab-sync` skill).
## Run it
```powershell
powershell -File apply-compose.ps1 # push .env + Caddyfile + compose, then apply
powershell -File apply-compose.ps1 -EnvFile # .env only
powershell -File apply-compose.ps1 -Caddy # Caddyfile only + hot-reload Caddy
powershell -File apply-compose.ps1 -Compose # docker-compose.yml only + dc pull + dc up -d
```
Flags combine (e.g. `-Caddy -Compose`); no flags pushes & applies all three.
## What each step does
- **`.env` / compose** → `scp` to `~/htpc-download-box/`, then `dc pull` (latest images) + `dc up -d` (recreates only containers whose resolved config changed).
- **Caddyfile** → `scp` to `/config/caddy/Caddyfile`, then `dc exec caddy caddy reload …` — a hot reload with no downtime. If the new Caddyfile is invalid the reload fails and the old config keeps running; read the output.
## After applying, verify
```powershell
ssh ginnoir@valhalla "bash -ic 'dc ps'"
ssh ginnoir@valhalla "bash -ic 'dc logs --tail=50 <service>'"
```
## Notes
- Compose is **v1.27.4** (`docker-compose`, hyphenated); `dc` runs over `bash -ic` to load the alias.
- Editing config without applying does nothing — the server only sees pushed files.
- Cosmetic/whitespace-only compose edits are no-ops to running containers; `dc up -d` won't recreate them.
+51
View File
@@ -0,0 +1,51 @@
---
name: homelab-ssh
description: Connect to and run commands on the valhalla homelab server (ginnoir@valhalla) over SSH, including docker-compose operations through the `dc` alias. Use when inspecting the live stack, tailing logs, restarting a service, reloading Caddy, or checking container/file state on the server.
---
# homelab-ssh
The production homelab runs on a headless Ubuntu host reachable at `ssh ginnoir@valhalla` (key-based auth; resolves and works from this Windows host directly).
## Connect (non-interactive / safe for automation)
Always pass `-o BatchMode=yes` so a missing key or password prompt fails fast instead of hanging:
```powershell
ssh -o BatchMode=yes -o ConnectTimeout=8 ginnoir@valhalla "<command>"
```
The first `Bash` command of a session is gated by a GateGuard hook — state the user request + what the command does, then retry.
## docker-compose via the `dc` alias
The stack is Docker Compose **v1.27.4** (`docker-compose`, hyphenated — `docker compose` v2 is not installed). On the server, `dc` is aliased in `~/.bashrc` to:
```
docker-compose -f ~/htpc-download-box/docker-compose.yml --env-file ~/htpc-download-box/.env
```
It's a shell alias, so it only exists in an interactive shell. Invoke it with `bash -ic`:
```powershell
ssh ginnoir@valhalla "bash -ic 'dc ps'"
ssh ginnoir@valhalla "bash -ic 'dc logs -f --tail=200 <service>'"
ssh ginnoir@valhalla "bash -ic 'dc restart <service>'"
ssh ginnoir@valhalla "bash -ic 'dc up -d'"
ssh ginnoir@valhalla "bash -ic 'dc exec caddy caddy reload --config /etc/caddy/Caddyfile'"
```
Use the compose **service name** (`sonarr`, `caddy`, `app`, …). Without `bash -ic`, `dc` is "command not found".
## Key paths on the server
- `~/htpc-download-box/docker-compose.yml`, `~/htpc-download-box/.env` — stack definition
- `/config/caddy/Caddyfile` — Caddy config (mounted into the `caddy` container at `/etc/caddy/Caddyfile`)
- `/config/<service>/` — per-service persisted config; `/storage1/` — media & data; plus named Docker volumes
- `~/htpc-download-box/` also holds unrelated legacy files (`*.bak`, old `.git`, `README.md`, `Vagrantfile`) — don't modify them
## Notes
- Read-only exploration of `/config`, `/storage1`, and container state is fine for answering questions.
- Avoid destructive commands against the live stack without explicit confirmation.
- To push config changes and apply them, use the `homelab-apply` skill; to pull prod config into the repo, use `homelab-sync`.
+38
View File
@@ -0,0 +1,38 @@
---
name: homelab-sync
description: Pull the live production configs (docker-compose.yml, .env, Caddyfile) from the valhalla server into this repo so local matches what's deployed. Use at the start of any session that will edit homelab deployment config, or to check for drift between repo and production.
---
# homelab-sync
Production (valhalla) is the source of truth. Pull before editing so you never edit a stale copy.
## Run it
```powershell
powershell -File sync-prod.ps1
```
This `scp`s three files from valhalla, **overwriting** the local copies:
| From valhalla | Into repo |
|---------------|-----------|
| `~/htpc-download-box/docker-compose.yml` | `docker-compose.yml` |
| `~/htpc-download-box/.env` | `.env` |
| `/config/caddy/Caddyfile` | `Caddyfile` |
It overwrites local working copies — commit or stash anything you want to keep first.
## Check drift without overwriting
To see how local differs from prod before deciding direction (git is installed):
```powershell
$tmp = Join-Path $env:TEMP 'valhalla-compose.yml'
scp -o BatchMode=yes "ginnoir@valhalla:~/htpc-download-box/docker-compose.yml" $tmp
git --no-pager diff --no-index -- $tmp .\docker-compose.yml
```
(`.env` and `Caddyfile` can be compared the same way.)
After syncing, review `git status` / `git diff` to see what changed on the server since your last sync. To push local changes the other direction, use the `homelab-apply` skill.