- 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>
11 KiB
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 |
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:
id nobody
# uid=99(nobody) gid=100(users)
If you want files written with your personal user's ownership instead:
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:
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
- In the Unraid web UI, go to the Docker tab
- Click Add Container
- At the top, click the Template dropdown and select Family Planner from the user templates section
- 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:
- Pull the image
- Create the container
- 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:
- Click the container icon (the colored square to the left of the container name)
- Select Logs
- 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 /path/to/family-planner/unraid/install.sh
Option B — Override any defaults inline before running:
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:
curl -fsSL https://raw.githubusercontent.com/your-username/family-planner/main/unraid/install.sh | bash
Or with custom values:
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:
- Stop and remove any existing container named
family-planner - Create the data directory if it does not exist
- Pull the latest image
- Start the container
- 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)
# 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
- In the Docker tab, click the container icon and select Check for Updates
- If an update is available, click Update — Unraid will pull the new image and recreate the container preserving your volume mappings
CLI
# 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:
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:
# 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
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
/photosvolume 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
TZto 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 -20or see Wikipedia - Recreate the container after changing
TZ— it is read at startup
File permission errors in logs
- The entrypoint script sets ownership of
/datatoPUID:PGIDon every start - If you see permission errors, check that
PUID/PGIDmatch the owner of your appdata share - Run
ls -la /mnt/user/appdata/family-plannerto see current ownership - Run
id nobodyandid your-usernameto compare UIDs