streamline README

This commit is contained in:
2026-04-29 13:14:23 -04:00
parent 233122d433
commit 37faf252dc
+19 -51
View File
@@ -20,6 +20,7 @@ docker/ Docker app configs (compose files, nginx confs)
minecraft/ MCSManager
immich/ Immich photo server + PostgreSQL
beszel-agent/ System monitoring agent (reports to beszel.hantim.net)
diun/ Daily image-digest watcher (emails when updates available)
smb/ Samba share (ZFS mountpoint, not in git)
system/ System config snapshots (smb.conf, sanoid.conf, firewalld, etc.)
```
@@ -38,13 +39,12 @@ system/ System config snapshots (smb.conf, sanoid.conf, firewalld, et
## Workflows
**Compose files** -- edit in `/opt/argento/`, apply, commit:
**Compose files** -- edit in `/opt/argento/`, apply:
```bash
cd /opt/argento/docker/<app>
vim compose.yaml
docker compose up -d
git add . && git commit && git push
```
**System configs** -- edit in place, auto-synced daily:
@@ -61,55 +61,24 @@ systemctl restart smb
vim /opt/argento/docker/nginx/conf.d/<domain>.conf
docker exec nginx nginx -t
docker exec nginx nginx -s reload
git add . && git commit && git push
```
**Updating an app (Diun notification received):**
Diun emails when a watched image has a new digest on the registry. The email
names the image (e.g. `postgres:17-alpine`), not the container. To find which
container uses it:
Diun emails name the image (e.g. `postgres:17-alpine`), not the container. Find it:
```bash
docker ps --filter "ancestor=<image>:<tag>" --format '{{.Names}}'
```
Then apply the update from that app's directory:
Then update:
```bash
cd /opt/argento/docker/<app>
docker compose pull
docker compose pull --ignore-buildable
docker compose build --pull # if repo contains dockerfile
docker compose up -d
docker ps # verify container is healthy
```
Then smoke-test the app (open the UI, or `curl -I https://<domain>`).
Caveats before pulling:
- Diun only reports that a digest changed -- it does not say the update is safe. For apps with schema migrations (Nextcloud, Immich, Gitea, Postgres), skim the release notes first.
- For major version bumps, run `./scripts/backup.sh` manually before pulling so the USB has a fresh snapshot.
- Postgres major version bumps (e.g. 17 -> 18) cannot reuse the old data dir -- a plain `compose up -d` will fail to start. See [RUNBOOK.md](RUNBOOK.md#maintenance-postgres-major-version-upgrade).
- After several updates, reclaim disk with `docker image prune -f`.
**Apps with a local Dockerfile:**
Some compose files build their image locally instead of pulling a tagged one:
| App | Service | Base image | Why |
|-----|---------|-----------|-----|
| `nextcloud` | `nextcloud` | `nextcloud:latest` | Adds smbclient + ffmpeg |
| `minecraft` | `daemon` | `githubyumao/mcsmanager-daemon:latest` | Adds Temurin 25 JRE |
For these, plain `docker compose pull` fails on the buildable service ("pull access denied"). Use one of:
```bash
docker compose pull --ignore-buildable # pull only registry-backed services
docker compose build --pull # rebuild, refreshing the FROM base
docker compose up -d --build # build + pull + recreate, one shot
```
Diun caveat: Diun watches the running container's image reference. Since these run as local images (e.g. `mcsmanager-daemon-java25`), the registry lookup has nothing to compare against -- **Diun will not notify when the base image updates**. Refresh these manually on your own cadence with `docker compose build --pull && docker compose up -d`.
Postgres major version bumps (e.g. 17 -> 18) need extra steps -- see [RUNBOOK.md](RUNBOOK.md#maintenance-postgres-major-version-upgrade).
**Adding a new app:**
@@ -118,7 +87,6 @@ Diun caveat: Diun watches the running container's image reference. Since these r
3. `./scripts/issue-cert.sh <domain>`
4. `cp docker/nginx/conf.d/_template.conf.example docker/nginx/conf.d/<domain>.conf` and fill in placeholders
5. `docker exec nginx nginx -t && docker exec nginx nginx -s reload`
6. Commit and push
## Recovery
@@ -126,15 +94,15 @@ See [RUNBOOK.md](RUNBOOK.md) for full disaster recovery steps.
## What's protected where
| Data | Protection | Recovery |
|------|-----------|----------|
| Configs (compose, nginx, system) | Git (Gitea bare repo on USB backup) | `git clone` from USB |
| Nextcloud files | ZFS mirror + sanoid snapshots + USB | `rsync` from USB |
| Media library | ZFS raidz2 + sanoid snapshots + USB | `rsync` from USB |
| Nextcloud DB (PostgreSQL) | ZFS dataset + `pg_dumpall` + USB | `rsync` from USB |
| Immich library (photos/videos) | ZFS raidz2 + sanoid snapshots + USB | `rsync` from USB |
| Immich DB (PostgreSQL) | `pg_dumpall` + USB | `rsync` from USB |
| Garage S3 data | 2-node replication + USB | Replication or USB |
| Gitea repos + DB | SQLite `.backup` + USB | `rsync` from USB |
| Secrets (.env files) | USB backup + Bitwarden | `rsync` from USB, or recreate from Bitwarden |
| SSL certificates | Re-issued from Let's Encrypt | `./scripts/issue-cert.sh` |
| Data | Protection |
|------|-----------|
| Configs (compose, nginx, system) | Git (Gitea bare repo on USB backup) |
| Nextcloud files | ZFS mirror + sanoid snapshots + USB |
| Media library | ZFS raidz2 + sanoid snapshots + USB |
| Nextcloud DB (PostgreSQL) | ZFS dataset + `pg_dumpall` + USB |
| Immich library (photos/videos) | ZFS raidz2 + sanoid snapshots + USB |
| Immich DB (PostgreSQL) | `pg_dumpall` + USB |
| Garage S3 data | 2-node replication + USB |
| Gitea repos + DB | SQLite `.backup` + USB |
| Secrets (.env files) | USB backup + Bitwarden |
| SSL certificates | Re-issued from Let's Encrypt |