- 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>
326 lines
11 KiB
Markdown
326 lines
11 KiB
Markdown
# 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
|