From 5c2fde0c867c9d187ce8c08faf4f87962f95b29b Mon Sep 17 00:00:00 2001 From: ort Date: Sat, 15 Aug 2026 13:54:28 -0400 Subject: [PATCH] Add Unraid deployment setup docker-compose.unraid.yml bind-mounts data to /mnt/user/appdata/kids-calendar instead of a named volume, matching Unraid's appdata convention so backup plugins pick it up. UNRAID.md covers getting the code onto the array, running via Compose Manager or terminal, reverse-proxy/HTTPS notes, and updating. Linked from README. --- README.md | 5 ++ UNRAID.md | 138 ++++++++++++++++++++++++++++++++++++++ docker-compose.unraid.yml | 16 +++++ 3 files changed, 159 insertions(+) create mode 100644 UNRAID.md create mode 100644 docker-compose.unraid.yml diff --git a/README.md b/README.md index ea5b3ce..8e9487c 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,11 @@ Data lives in a named volume (`kids-calendar-data`), so it survives container rebuilds. To back it up, back up that volume (or bind-mount `./data:/app/data` in `docker-compose.yml` instead and back up that folder). +**Running on Unraid specifically?** See [UNRAID.md](UNRAID.md) — it uses +`docker-compose.unraid.yml`, which bind-mounts to +`/mnt/user/appdata/kids-calendar` instead of a named volume, matching +Unraid's usual appdata convention. + ### Environment variables | Variable | Default | Notes | diff --git a/UNRAID.md b/UNRAID.md new file mode 100644 index 0000000..729379b --- /dev/null +++ b/UNRAID.md @@ -0,0 +1,138 @@ +# Running on Unraid + +This app has no native/compiled dependencies (it uses Node's built-in +`node:sqlite`), so it builds and runs on Unraid's stock Docker exactly like +anywhere else. This file covers the Unraid-specific parts: getting the +code onto the array, where data lives, and how to run it via either the +Compose Manager plugin or the terminal. + +## 1. Get the code onto Unraid + +Pick whichever is easier for you — both end up with the project folder +somewhere under `/mnt/user/`. + +**Option A — copy via network share (no git needed on Unraid):** +Unraid shares `/mnt/user/appdata` over SMB by default. From your Mac: + +```bash +mkdir -p /Volumes/appdata/kids-calendar-src # after connecting to \\TOWER\appdata +rsync -av --exclude node_modules --exclude data --exclude .git \ + "/Users/ort84/kids calendar/kids-calendar/" /Volumes/appdata/kids-calendar-src/ +``` + +(Connect to the share first via Finder → Go → Connect to Server → +`smb://TOWER/appdata`, adjust the mount path/share name to match your +server.) + +**Option B — git clone directly on Unraid:** +Unraid's base OS doesn't ship git. Install the **NerdTools** plugin from +Community Applications, enable `git` in it, then from the Unraid terminal +(Tools → Terminal, or SSH in): + +```bash +mkdir -p /mnt/user/appdata/kids-calendar-src +cd /mnt/user/appdata/kids-calendar-src +git clone ssh://git@git.oservr.com:23/ort/KCal.git . +``` + +This needs the deploy key available on Unraid too (copy `GitOServr/` over +via the same SMB share, then `chmod 600` the private key file — SSH will +refuse a world-readable key just like it did on the Mac). Only do this if +you're comfortable having a copy of that key on the server; Option A avoids +that entirely. + +## 2. Create the appdata folder + +```bash +mkdir -p /mnt/user/appdata/kids-calendar +``` + +This is where the SQLite database will live — `docker-compose.unraid.yml` +bind-mounts it in, instead of using a Docker-managed named volume, so it +shows up normally in Unraid's Docker tab and gets picked up by appdata +backup plugins (e.g. CA Backup/Restore) like any other app's data. + +## 3. Set up `.env` + +In the project folder on Unraid (`kids-calendar-src` from step 1): + +```bash +cp .env.example .env +``` + +Edit `.env` and set: + +``` +SESSION_SECRET= +``` + +Generate one with: + +```bash +openssl rand -hex 32 +``` + +(Unraid ships `openssl`. If for some reason it's not available, `docker +run --rm node:22-alpine node -e "console.log(require('node:crypto').randomBytes(32).toString('hex'))"` +works too.) + +Leave `COOKIE_SECURE=false` unless you're putting this behind HTTPS (see +"Reverse proxy" below). + +## 4. Run it + +**Via the Compose Manager plugin (recommended):** install "Docker Compose +Manager" from Community Applications, add a new stack pointing at the +`kids-calendar-src` folder, and have it use `docker-compose.unraid.yml` +(the plugin lets you pick which compose file in the folder to use — if it +only supports a file literally named `docker-compose.yml`, either rename +`docker-compose.unraid.yml` to that inside your Unraid copy, or symlink +it: `ln -s docker-compose.unraid.yml docker-compose.yml`). Start the +stack from the plugin's UI. + +**Via terminal:** + +```bash +cd /mnt/user/appdata/kids-calendar-src +docker compose -f docker-compose.unraid.yml up -d --build +``` + +Either way, first boot builds the image (a minute or so), then the +container starts and listens on port 3007. + +## 5. Use it + +Open `http://:3007/signup.html`, create the first parent +account, invite your spouse, add your kids, build out calendars, and grab +each child's kiosk link from the dashboard for their tablet. + +## Updating + +After pulling/copying new code: + +```bash +cd /mnt/user/appdata/kids-calendar-src +docker compose -f docker-compose.unraid.yml up -d --build +``` + +This rebuilds the image and recreates the container; your data in +`/mnt/user/appdata/kids-calendar` is untouched. + +## Reverse proxy / access from outside your LAN + +If you're exposing this beyond your home network (e.g. via Swag or Nginx +Proxy Manager, both common on Unraid) with a real HTTPS certificate: + +- Point the proxy at `http://:3007` internally. +- Set `COOKIE_SECURE=true` in `.env` and re-run the `up -d --build` command + above — otherwise login cookies won't be marked secure and some + browsers/proxies will refuse to send them back over HTTPS. +- Once your household(s) exist, consider setting + `DISABLE_PUBLIC_SIGNUP=true` so `/signup.html` stops accepting new + households. + +## Backups + +Since data lives at `/mnt/user/appdata/kids-calendar` (a plain file, the +SQLite database), it's covered by whatever you already use to back up +`/mnt/user/appdata` — no special-casing needed. diff --git a/docker-compose.unraid.yml b/docker-compose.unraid.yml new file mode 100644 index 0000000..971ebcd --- /dev/null +++ b/docker-compose.unraid.yml @@ -0,0 +1,16 @@ +services: + kids-calendar: + build: . + container_name: kids-calendar + ports: + - "3007:3007" + volumes: + # Unraid convention: bind-mount to /mnt/user/appdata so it shows up + # in the Docker tab, gets picked up by appdata backup plugins, etc. + # Create this folder before first run (see UNRAID.md). + - /mnt/user/appdata/kids-calendar:/app/data + environment: + - SESSION_SECRET=${SESSION_SECRET:?set a long random value in .env} + - COOKIE_SECURE=${COOKIE_SECURE:-false} + - DISABLE_PUBLIC_SIGNUP=${DISABLE_PUBLIC_SIGNUP:-false} + restart: unless-stopped