add navidrome and music share

This commit is contained in:
2026-08-29 19:15:20 -04:00
parent 747a0208e7
commit 32b1f095fe
5 changed files with 62 additions and 2 deletions
+2
View File
@@ -16,6 +16,7 @@ docker/ Docker app configs (compose files, nginx confs)
nextcloud/ Nextcloud + PostgreSQL
gitea/ Gitea + CI runner
jellyfin/ Media server
navidrome/ Music server (Subsonic API), reads the [music] SMB share
garage/ S3-compatible storage
minecraft/ MCSManager
immich/ Immich photo server + PostgreSQL
@@ -104,5 +105,6 @@ See [RUNBOOK.md](RUNBOOK.md) for full disaster recovery steps.
| Immich DB (PostgreSQL) | `pg_dumpall` + USB |
| Garage S3 data | 2-node replication + USB |
| Gitea repos + DB | SQLite `.backup` + USB |
| Navidrome DB (ratings, playlists) | SQLite `.backup` + USB |
| Secrets (.env files) | USB backup + Bitwarden |
| SSL certificates | Re-issued from Let's Encrypt |
+11 -2
View File
@@ -128,6 +128,12 @@ for u in yireh isaac; do
chmod 2770 "/opt/argento/smb/$u"
done
# Shared music dir. Lives inside the media dataset (so it rides the media
# snapshot policy) but is exported as its own writable [music] share.
# setgid so files dropped in over SMB inherit sambagroup and stay readable
# by the Navidrome container.
install -d -o timothykim -g sambagroup -m 2775 /opt/argento/smb/media/Music
# SELinux contexts for samba — fresh ZFS datasets get unlabeled_t and samba
# refuses to serve them. Persistent rules (semanage) survive full relabels;
# restorecon applies them now.
@@ -232,7 +238,8 @@ docker compose up -d
# Issue certs (add any new domains that have been added since this was written)
/opt/argento/scripts/issue-cert.sh \
nextcloud.timothykim.net git.timothykim.net jellyfin.timothykim.net \
argento.timothykim.net garage.timothykim.net photos.thekims.family
argento.timothykim.net garage.timothykim.net photos.thekims.family \
music.thekims.family
# Restore SSL confs now that certs exist
mv conf.d/.hold/*.conf conf.d/
@@ -258,7 +265,7 @@ Deploy each app (nginx is already running and will return 502 until they start):
```bash
# Add any new apps that have been added since this was written
for app in nextcloud gitea jellyfin garage minecraft immich beszel-agent; do
for app in nextcloud gitea jellyfin navidrome garage minecraft immich beszel-agent; do
cd /opt/argento/docker/$app
docker compose pull
docker compose build
@@ -291,6 +298,7 @@ CNAME records pointing to the DDNS hostname. These don't need updating when the
| `garage.timothykim.net` | CNAME | `argento.ddns.net` |
| `minecraft.thekims.family` | CNAME | `argento.ddns.net` |
| `photos.thekims.family` | CNAME | `argento.ddns.net` |
| `music.thekims.family` | CNAME | `argento.ddns.net` |
## 14. Verify
@@ -301,6 +309,7 @@ curl -I https://jellyfin.timothykim.net
curl -I https://argento.timothykim.net
curl -I https://garage.timothykim.net
curl -I https://photos.thekims.family
curl -I https://music.thekims.family
curl -I http://minecraft.thekims.family
# Verify SMART, ZFS, and disk space are healthy
+1
View File
@@ -0,0 +1 @@
data/
@@ -0,0 +1,43 @@
server {
listen 80;
listen [::]:80;
server_name music.thekims.family;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
server_name music.thekims.family;
ssl_certificate /etc/letsencrypt/live/music.thekims.family/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/music.thekims.family/privkey.pem;
include /etc/nginx/conf.d/security-headers.inc;
# Use a variable so nginx starts even if the upstream is down
set $upstream_navidrome http://navidrome:4533;
location / {
proxy_pass $upstream_navidrome;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Navidrome streams scan progress and now-playing state over
# Server-Sent Events on /api/events. Buffering holds those messages
# until the response ends (it never does), and HTTP/1.0 to the upstream
# can't carry the chunked response the stream needs.
proxy_http_version 1.1;
proxy_buffering off;
}
}
+5
View File
@@ -40,6 +40,11 @@ for db in jellyfin library; do
|| FAILURES+=("jellyfin ${db} sqlite backup")
done
# Dump Navidrome SQLite for consistency
sqlite3 /opt/argento/docker/navidrome/data/navidrome.db \
".backup /opt/argento/docker/navidrome/data/navidrome.db.bak" \
|| FAILURES+=("navidrome sqlite backup")
# Single rsync covers everything: configs, app data, media, DB dumps,
# and the samba passdb (mirrored into /opt/argento/system/samba-private/
# by sync-system.sh, gitignored)