Files
family_home_lab/deploy/DEPLOYMENT.md

112 lines
4.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Deployment notes — Family Home Lab
## Domains
- Public zone `lab.audasmedia.com.au` → `144.6.86.11` (router) → `.35` Caddy.
- **No Pi-hole local records needed.** `*.home.lab` is deprecated (not a registered TLD).
## Caddy (.35)
1. SSH: `ssh sam@192.168.20.35`
2. Locate the running Caddy config (Docker container on .35).
3. Append `deploy/caddy/Caddyfile.snippet` contents to the Caddyfile.
4. Reload: `docker exec <caddy> caddy reload --config /etc/caddy/Caddyfile`
5. Verify Caddy can obtain Let's Encrypt certs (ports 80/443 forwarded on router — already working for omniroute/gitea domains).
## Host (.13)
1. Compose project: `/home/sam/Docker/Containers/family-home-lab/` (created during build).
2. Data: `/mnt/data/family-home-lab/` (garage-data, garage-meta, shared-media, dsh/).
3. Backup: add `/mnt/data/family-home-lab/` to Borg sources in `/etc/nixos/backup.nix`.
## Ports (on .13)
| Port | Service |
|---|---|
| 8500 | Portal (FastAPI) |
| 8487 | Photopea (→ container 8887) |
| 8083 | Video editor (kdenlive) — 8081 was taken by airflow-webserver |
| 8084 | Audio editor (audacity) — 3000 was taken by a NixOS service |
| 3900/3902 | Garage (S3/admin) |
| 3081–3084 | dsh instances (other agent) |
## Order of operations
1. Build portal + compose stack (this repo) → `docker compose up -d` on .13
2. Apply Caddy snippet on .35
3. Test `https://console.lab.audasmedia.com.au`
4. Deploy tool containers one at a time, verifying each URL
5. dsh agent deploys its instances and coordinates token handoff
## First run (portal)
Portal auto-creates the DB tables and, if the users table is empty, seeds the
admin from `ADMIN_USERNAME`/`ADMIN_PASSWORD` in `.env` (Sam, by default).
```bash
cd /home/sam/Docker/Containers/family-home-lab
docker compose up -d
# first admin already created on startup; create the rest in the UI at /admin
```
## Garage provisioning (S3 buckets + access keys)
After Garage is up, create buckets/keys from inside the container:
```bash
# env for the garage CLI
G=('docker compose exec -T garage garage --config /etc/garage.toml')
# main service key for the portal
KEY_ID=$($G key import --name portal - <<< "$(cat .env | grep S3_ACCESS | cut -d= -f2)")
# buckets
for b in sam jo harry finn shared-media; do $G bucket create "$b"; done
# allow the portal key to access every bucket
for b in sam jo harry finn shared-media; do $G bucket allow --read --write "$b" --key portal; done
```
> Symmetry: ensure S3_ACCESS_KEY/S3_SECRET_KEY in `.env` match what `key import`
> registers, else portal uploads will 403.
## ON/OFF service-controller (ON_OFF.md)
Host-side on/off API on `.13`, port **8443** (chosen because it is already in the
NixOS `networking.firewall.allowedTCPPorts` allowlist — 8091/8092 were taken by
langgraph-service / photo-dashboard, and 8099 was blocked by the firewall).
Files live in `deploy/service-controller/` and copy to `/home/sam/service-controller/` on .13.
Install / update:
```bash
# on .27 (this repo), then:
scp -q deploy/service-controller/service_controller.py \
deploy/service-controller/services.toml \
deploy/service-controller/run.sh \
deploy/service-controller/family-service-controller.service \
sam@192.168.20.13:/home/sam/service-controller/
# on .13:
cd /home/sam/service-controller
python3 -m venv .venv # first time only
./.venv/bin/pip install -q -r requirements.txt # first time only
cp family-service-controller.service ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user enable --now family-service-controller.service
```
Secrets:
- `SC_TOKEN` lives in `/home/sam/.config/environment.d/10-secrets.conf` (git-ignored; run.sh sources it).
- The portal gets `SC_TOKEN` from its `.env` on .13 (injected at deploy; never committed).
Firewall note: the controller binds `0.0.0.0:8443` and is protected by the token.
Binding only to the docker bridge gateway was dropped because this NixOS box drops
INPUT from containers to non-allowlisted host listeners; `0.0.0.0` on the already-
allowed port 8443 is the workable, token-gated compromise.
Portal wiring: `docker-compose.yml` sets `SC_URL=http://host.docker.internal:8443`
and `SC_TOKEN=${SC_TOKEN:-}` on the portal service, with
`extra_hosts: ["host.docker.internal:192.168.144.1"]` (host-gateway resolves to the
DOWN docker0 bridge on this box; pinning to the fhl-net gateway works).
Verify:
```bash
curl -s http://127.0.0.1:8443/health # {"ok":true,...}
curl -s -H "X-Controller-Token: $SC_TOKEN" http://127.0.0.1:8443/services
curl -s -X POST -H "X-Controller-Token: $SC_TOKEN" http://127.0.0.1:8443/services/lmms/stop
```