Phase 1 & 2: full-stack family dashboard scaffold
- pnpm monorepo (apps/client + apps/server) - Server: Express + node:sqlite with numbered migration runner, REST API for all 9 features (members, events, chores, shopping, meals, messages, countdowns, photos, settings) - Client: React 18 + Vite + TypeScript + Tailwind + Framer Motion + Zustand - Theme system: dark/light + 5 accent colors, CSS custom properties, anti-FOUC script, ThemeToggle on every surface - AppShell: collapsible sidebar, animated route transitions, mobile drawer - Phase 2 features: Calendar (custom month grid, event chips, add/edit modal), Chores (card grid, complete/reset, member filter, streaks), Shopping (multi-list tabs, animated check-off, quick-add bar, member assign) - Family member CRUD with avatar, color picker - Settings page: theme/accent, photo folder, slideshow, weather, date/time - Docker: multi-stage Dockerfile, docker-compose.yml, entrypoint with PUID/PGID - Unraid: CA XML template, CLI install script, UNRAID.md guide - .gitignore covering node_modules, dist, db files, secrets, build artifacts Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
325
UNRAID.md
Normal file
325
UNRAID.md
Normal file
@@ -0,0 +1,325 @@
|
||||
# Unraid Install Guide — Family Planner
|
||||
|
||||
Two installation methods are available: the **GUI** method using the Community Applications template, and the **CLI** method using the Unraid terminal. Both produce an identical container. Choose whichever you prefer.
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Unraid 6.10 or later
|
||||
- Docker service enabled (Unraid Settings → Docker → Enable Docker: Yes)
|
||||
- The Family Planner image published to a container registry (e.g. `ghcr.io/your-username/family-planner:latest`)
|
||||
- At least one share for app data (e.g. `appdata`) — created automatically by Unraid if it does not exist
|
||||
|
||||
---
|
||||
|
||||
## Paths and Variables Reference
|
||||
|
||||
Understand these before installing. Both methods use the same values.
|
||||
|
||||
### Volume Mounts
|
||||
|
||||
| Container path | Host path (default) | Access | Required | Purpose |
|
||||
|---|---|---|---|---|
|
||||
| `/data` | `/mnt/user/appdata/family-planner` | read/write | **Yes** | SQLite database, migrations state |
|
||||
| `/photos` | `/mnt/user/Photos` | read-only | No | Photo library for the slideshow screensaver |
|
||||
|
||||
**`/data` must be writable.** This is where the database file (`family.db`) lives. If this volume is lost, all data is lost — back it up like any other appdata folder.
|
||||
|
||||
**`/photos` is read-only.** The app scans this folder recursively for images (`.jpg`, `.jpeg`, `.png`, `.gif`, `.webp`, `.avif`, `.bmp`). Point it at any existing share or subfolder on your array. You can also leave it unmapped and configure the path later inside the app under Settings → Photo Slideshow.
|
||||
|
||||
### Port Mapping
|
||||
|
||||
| Host port | Container port | Protocol | Purpose |
|
||||
|---|---|---|---|
|
||||
| `3001` (configurable) | `3001` | TCP | Web UI |
|
||||
|
||||
Change the host port if `3001` is already in use on your server. The container port stays `3001`.
|
||||
|
||||
### Environment Variables
|
||||
|
||||
| Variable | Default | Required | Description |
|
||||
|---|---|---|---|
|
||||
| `TZ` | `America/New_York` | Recommended | Timezone for date/time display. Full list: [tz database](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) |
|
||||
| `PUID` | `99` | No | UID the process runs as inside the container. Unraid's `nobody` = `99`. Run `id <username>` in the terminal to find yours. |
|
||||
| `PGID` | `100` | No | GID the process runs as. Unraid's `users` group = `100`. |
|
||||
| `PORT` | `3001` | No | Internal app port. Do not change unless you have a specific reason. |
|
||||
| `DATA_DIR` | `/data` | No | Internal path to the data directory. Do not change. |
|
||||
| `PHOTOS_DIR` | `/photos` | No | Internal path to the photos directory. Do not change. |
|
||||
| `NODE_NO_WARNINGS` | `1` | No | Suppresses the Node.js experimental SQLite warning. Do not change. |
|
||||
|
||||
**Finding your PUID/PGID** — open the Unraid terminal and run:
|
||||
```bash
|
||||
id nobody
|
||||
# uid=99(nobody) gid=100(users)
|
||||
```
|
||||
If you want files written with your personal user's ownership instead:
|
||||
```bash
|
||||
id your-username
|
||||
# uid=1000(your-username) gid=100(users)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Method 1 — GUI (Community Applications Template)
|
||||
|
||||
### Step 1 — Copy the template file
|
||||
|
||||
Open the Unraid terminal (Tools → Terminal) and run:
|
||||
|
||||
```bash
|
||||
cp /path/to/family-planner/unraid/family-planner.xml \
|
||||
/boot/config/plugins/dockerMan/templates-user/family-planner.xml
|
||||
```
|
||||
|
||||
If you cloned the repo directly onto your server, the path will be wherever you placed it. Alternatively, paste the XML file content manually into a new file at that location.
|
||||
|
||||
### Step 2 — Open Docker and add the container
|
||||
|
||||
1. In the Unraid web UI, go to the **Docker** tab
|
||||
2. Click **Add Container**
|
||||
3. At the top, click the **Template** dropdown and select **Family Planner** from the user templates section
|
||||
4. The form will pre-fill with all default values
|
||||
|
||||
### Step 3 — Review and adjust each field
|
||||
|
||||
Work through the form top to bottom:
|
||||
|
||||
**Repository**
|
||||
```
|
||||
ghcr.io/your-username/family-planner:latest
|
||||
```
|
||||
Replace `your-username` with the actual GitHub username or registry path once the image is published.
|
||||
|
||||
**Network Type**
|
||||
```
|
||||
Bridge
|
||||
```
|
||||
Leave as-is unless you have a specific reason to use host or a custom network.
|
||||
|
||||
**Port Mappings**
|
||||
|
||||
| Name | Container port | Host port |
|
||||
|---|---|---|
|
||||
| Web UI Port | `3001` | `3001` (change if needed) |
|
||||
|
||||
**Path Mappings**
|
||||
|
||||
| Name | Container path | Host path | Access |
|
||||
|---|---|---|---|
|
||||
| App Data | `/data` | `/mnt/user/appdata/family-planner` | Read/Write |
|
||||
| Photos Path | `/photos` | `/mnt/user/Photos` | Read Only |
|
||||
|
||||
To change the photos path: click the field and type the full path to your photos share. Common examples:
|
||||
- `/mnt/user/Photos`
|
||||
- `/mnt/user/Media/Family Photos`
|
||||
- `/mnt/disk1/photos` (specific disk, bypasses cache)
|
||||
|
||||
Leave the Photos Path blank or point it at an empty folder if you do not want the slideshow feature yet — you can configure it later in the app.
|
||||
|
||||
**Variables**
|
||||
|
||||
| Name | Value |
|
||||
|---|---|
|
||||
| TZ | Your timezone, e.g. `America/Chicago` |
|
||||
| PUID | `99` (or your personal UID) |
|
||||
| PGID | `100` |
|
||||
| PORT | `3001` (leave as-is) |
|
||||
|
||||
### Step 4 — Apply
|
||||
|
||||
Click **Apply** at the bottom of the form. Unraid will:
|
||||
1. Pull the image
|
||||
2. Create the container
|
||||
3. Start it automatically
|
||||
|
||||
### Step 5 — Verify
|
||||
|
||||
Click the container row to expand it, then click **WebUI** (or navigate to `http://YOUR-SERVER-IP:3001` in your browser). The Family Planner dashboard should load.
|
||||
|
||||
To check container logs:
|
||||
1. Click the container icon (the colored square to the left of the container name)
|
||||
2. Select **Logs**
|
||||
3. You should see:
|
||||
```
|
||||
[db] Running 1 pending migration(s)...
|
||||
[db] ✓ Applied: 001_initial
|
||||
[db] Migrations complete.
|
||||
Family Planner running on http://0.0.0.0:3001
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Method 2 — CLI (Terminal Script)
|
||||
|
||||
This method runs a shell script from the Unraid terminal. It pulls the image, creates the container, and verifies it started correctly — all in one step.
|
||||
|
||||
### Step 1 — Open the Unraid terminal
|
||||
|
||||
Tools → Terminal (or SSH into your server).
|
||||
|
||||
### Step 2 — Run the installer
|
||||
|
||||
**Option A — If you have the repo on the server:**
|
||||
```bash
|
||||
bash /path/to/family-planner/unraid/install.sh
|
||||
```
|
||||
|
||||
**Option B — Override any defaults inline before running:**
|
||||
```bash
|
||||
HOST_PORT=3001 \
|
||||
DATA_PATH=/mnt/user/appdata/family-planner \
|
||||
PHOTOS_PATH=/mnt/user/Photos \
|
||||
PUID=99 \
|
||||
PGID=100 \
|
||||
TZ=America/New_York \
|
||||
bash /path/to/family-planner/unraid/install.sh
|
||||
```
|
||||
|
||||
**Option C — Once the image is published, pull and run in one step:**
|
||||
```bash
|
||||
curl -fsSL https://raw.githubusercontent.com/your-username/family-planner/main/unraid/install.sh | bash
|
||||
```
|
||||
Or with custom values:
|
||||
```bash
|
||||
HOST_PORT=8080 PHOTOS_PATH=/mnt/user/Media/Photos \
|
||||
curl -fsSL https://raw.githubusercontent.com/your-username/family-planner/main/unraid/install.sh | bash
|
||||
```
|
||||
|
||||
### Step 3 — Confirm the settings prompt
|
||||
|
||||
The script will display a summary of the values it will use and ask for confirmation:
|
||||
```
|
||||
[INFO] Family Planner — Unraid Installer
|
||||
|
||||
Container : family-planner
|
||||
Image : ghcr.io/your-username/family-planner:latest
|
||||
Port : 3001 → 3001
|
||||
Data path : /mnt/user/appdata/family-planner
|
||||
Photos : /mnt/user/Photos (read-only)
|
||||
PUID/PGID : 99/100
|
||||
TZ : America/New_York
|
||||
|
||||
Proceed with these settings? [Y/n]
|
||||
```
|
||||
Press **Enter** (or type `Y`) to proceed.
|
||||
|
||||
### Step 4 — Wait for completion
|
||||
|
||||
The script will:
|
||||
1. Stop and remove any existing container named `family-planner`
|
||||
2. Create the data directory if it does not exist
|
||||
3. Pull the latest image
|
||||
4. Start the container
|
||||
5. Wait up to 30 seconds for a successful health check
|
||||
|
||||
On success you will see:
|
||||
```
|
||||
[OK] Family Planner is up!
|
||||
[OK] Installation complete.
|
||||
|
||||
Open in browser : http://192.168.1.X:3001
|
||||
View logs : docker logs -f family-planner
|
||||
Stop : docker stop family-planner
|
||||
```
|
||||
|
||||
### Step 5 — Verify manually (optional)
|
||||
|
||||
```bash
|
||||
# Check the container is running
|
||||
docker ps | grep family-planner
|
||||
|
||||
# Tail live logs
|
||||
docker logs -f family-planner
|
||||
|
||||
# Hit the API to confirm the app is responding
|
||||
curl -s http://localhost:3001/api/settings | python3 -m json.tool
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Updating
|
||||
|
||||
### GUI
|
||||
|
||||
1. In the Docker tab, click the container icon and select **Check for Updates**
|
||||
2. If an update is available, click **Update** — Unraid will pull the new image and recreate the container preserving your volume mappings
|
||||
|
||||
### CLI
|
||||
|
||||
```bash
|
||||
# Pull the new image
|
||||
docker pull ghcr.io/your-username/family-planner:latest
|
||||
|
||||
# Stop and remove the old container (data is safe — it lives in /data volume)
|
||||
docker stop family-planner
|
||||
docker rm family-planner
|
||||
|
||||
# Re-run the install script with the same settings
|
||||
bash /path/to/family-planner/unraid/install.sh
|
||||
```
|
||||
|
||||
Or as a one-liner:
|
||||
```bash
|
||||
docker pull ghcr.io/your-username/family-planner:latest \
|
||||
&& docker stop family-planner \
|
||||
&& docker rm family-planner \
|
||||
&& bash /path/to/family-planner/unraid/install.sh
|
||||
```
|
||||
|
||||
> **Database migrations run automatically on startup.** When a new version adds schema changes, the migration runner applies them the first time the updated container starts. Your existing data is preserved.
|
||||
|
||||
---
|
||||
|
||||
## Backup
|
||||
|
||||
The entire application state lives in one file:
|
||||
|
||||
```
|
||||
/mnt/user/appdata/family-planner/family.db
|
||||
```
|
||||
|
||||
Back this up with Unraid's built-in **Appdata Backup** plugin, or manually:
|
||||
|
||||
```bash
|
||||
# One-time backup
|
||||
cp /mnt/user/appdata/family-planner/family.db \
|
||||
/mnt/user/Backups/family-planner-$(date +%Y%m%d).db
|
||||
|
||||
# Restore (stop the container first)
|
||||
docker stop family-planner
|
||||
cp /mnt/user/Backups/family-planner-20260101.db \
|
||||
/mnt/user/appdata/family-planner/family.db
|
||||
docker start family-planner
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Container exits immediately**
|
||||
```bash
|
||||
docker logs family-planner
|
||||
```
|
||||
Look for `[db] ✗ Failed:` — a migration failure aborts startup. This usually means the `/data` volume is not writable or the database file is corrupted.
|
||||
|
||||
**Cannot access the web UI**
|
||||
- Confirm the container is running: `docker ps | grep family-planner`
|
||||
- Check the host port is not blocked by Unraid's firewall or already in use: `ss -tlnp | grep 3001`
|
||||
- Try accessing via the server's LAN IP directly: `http://192.168.1.X:3001`
|
||||
|
||||
**Photos not showing in slideshow**
|
||||
- Verify the `/photos` volume is mapped and the path exists: `docker exec family-planner ls /photos`
|
||||
- Check the path in the app: Settings → Photo Slideshow → Photo Folder Path
|
||||
- Supported formats: `.jpg`, `.jpeg`, `.png`, `.gif`, `.webp`, `.avif`, `.bmp`
|
||||
|
||||
**Wrong timezone / dates**
|
||||
- Set `TZ` to a valid tz database name, e.g. `America/Los_Angeles`, `Europe/London`, `Asia/Tokyo`
|
||||
- Full list: `docker exec family-planner cat /usr/share/zoneinfo/tzdata.zi | head -20` or see [Wikipedia](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)
|
||||
- Recreate the container after changing `TZ` — it is read at startup
|
||||
|
||||
**File permission errors in logs**
|
||||
- The entrypoint script sets ownership of `/data` to `PUID:PGID` on every start
|
||||
- If you see permission errors, check that `PUID`/`PGID` match the owner of your appdata share
|
||||
- Run `ls -la /mnt/user/appdata/family-planner` to see current ownership
|
||||
- Run `id nobody` and `id your-username` to compare UIDs
|
||||
Reference in New Issue
Block a user