Files
recurring-checklist/server/README.md
T
Waters ChurchandClaude Opus 5 469db5bc60 Bring the checklist app under version control
The project has lived only as a folder on the Mac Studio and, briefly, as a
transfer tarball. This is the first commit: the Express server and its web
front end, the Capacitor iOS and Android wrappers, and the release and backup
scripts.

The repo is the source, not a backup of the machine. Left out on purpose, by
the .gitignore files that were already in the tree: node_modules, build output,
mobile/www (regenerated from server/public on every build), and server/data,
which holds the live checklists and belongs on the NAS rather than in git.

Every credential is excluded too — server/.env, the Play upload keystore and
its properties file, the App Store Connect key and ios-signing.config. The one
secret that was not in an ignored file was the NAS SSH password, hard-coded in
build-deploy.sh and grepped back out of it by backup-to-drive.sh. Both now read
it from the login keychain (service checklist-nas, account Christian), falling
back to NAS_PASS in the environment, so rotating it is one keychain entry
rather than a history rewrite.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-24 13:00:57 -04:00

162 lines
5.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Recurring Checklist — Self-hosted Web Version
A small Node.js web app that anyone on your network can hit from a browser.
Designed to run on a **Synology NAS** via Docker (Container Manager). Every
Sunday at 3:00 PM it emails you a digest of who checked off what — and what
got missed — then resets the lists for the next week.
```
Users → http://nas-ip:3000 → tick boxes → server stores state
↓
Sun 3:00 PM cron
↓
Gmail SMTP → digest email → you
```
---
## What's where
| File | Purpose |
| --- | --- |
| `server.js` | Express server, REST API, scheduler, email |
| `public/` | Static frontend (HTML/CSS/JS) served by Express |
| `data/` | Persisted state (`checklists.json`) — **must be a volume mount** |
| `.env.example` | Copy to `.env` and fill in |
| `Dockerfile` | Builds the container image |
| `docker-compose.yml` | One-command deploy |
---
## 1. Set up a Gmail App Password (for the digest email)
1. Sign in to the Google account you want to send from (your own, or a
dedicated one — both work).
2. Turn on 2-Step Verification at <https://myaccount.google.com/security>.
3. Once 2-Step is on, go to <https://myaccount.google.com/apppasswords>.
4. Create an app password called "Recurring Checklist". Google gives you a
16-character string like `abcd efgh ijkl mnop`. Save it.
5. You'll paste that into `SMTP_PASS` in `.env` (with or without spaces, both work).
> Don't want to use Gmail? Any SMTP works. Office 365, Fastmail, your own
> Postfix on the Synology — just swap the `SMTP_*` vars in `.env`.
---
## 2. Deploy on Synology with Container Manager
These steps assume **DSM 7.2+** with Container Manager installed.
### A. Copy the `server/` folder to the NAS
Drop this whole folder into something like
`/volume1/docker/recurring-checklist/` using File Station, SMB, rsync —
whatever's easiest. The folder must end up with `Dockerfile`,
`docker-compose.yml`, `server.js`, `public/`, etc.
### B. Create the `.env` file on the NAS
In that folder, copy `.env.example` to `.env` and edit it:
```bash
cp .env.example .env
nano .env
```
Fill in:
- `ADMIN_PASSWORD` — a password you'll use to manage lists in the browser.
- `REPORT_EMAIL` — your inbox.
- `SMTP_USER` — the Gmail address you set up in step 1.
- `SMTP_PASS` — the 16-character app password.
- `SMTP_FROM` — `Recurring Checklist <yourgmail@gmail.com>` is fine.
- `REPORT_TZ` — your local timezone (default `America/New_York`).
- `REPORT_CRON` — `0 15 * * 0` = Sunday at 3:00 PM. Leave alone unless you
want to change the time.
### C. Open Container Manager → Project → Create
1. **Project name:** `recurring-checklist`
2. **Path:** browse to `/volume1/docker/recurring-checklist/`
3. **Source:** "Use existing docker-compose.yml"
4. Click **Next** through the rest and **Done**. Container Manager will
build the image (takes 30–90 seconds the first time) and start it.
### D. Open it in a browser
From any device on your network:
```
http://<your-nas-ip>:3000
```
You'll be asked for a name (your name shows up in the weekly email).
That's it — start checking things off.
### E. Log in as admin to create lists
- Top-right of the page → **🔒 Admin** → enter the `ADMIN_PASSWORD` from `.env`.
- A new bar appears under the list tabs. Pull it down (click or swipe) to
reveal **+ Add List**, **Rename**, **Delete**, **Export/Import JSON**,
and **Send Digest Now** (use this to test email).
- In **Add Task**, build out your Startup and Shutdown lists.
- Click 🔓 Admin again to leave admin mode so the controls hide again.
---
## 3. Test the email before Sunday
While logged in as admin, hit **Send Digest Now** in the menu drawer.
You should get an email within a few seconds. If not, check the container
logs in Container Manager (it'll print the SMTP error).
---
## 4. Optional: HTTPS via Synology reverse proxy
In **Control Panel → Login Portal → Advanced → Reverse Proxy**:
| Source | Destination |
| --- | --- |
| `https://checklist.your-domain.com` (443) | `http://localhost:3000` |
Synology handles the Let's Encrypt cert. The app itself only listens on
plain HTTP inside the container — TLS terminates at DSM.
---
## 5. Running outside Docker (e.g. for local development)
```bash
cd server
npm install
cp .env.example .env # then edit
npm start
```
Open <http://localhost:3000>.
---
## Backups
Everything that matters lives in `data/checklists.json`. Add that path
(`/volume1/docker/recurring-checklist/data`) to your Hyper Backup task
and you're set.
---
## Troubleshooting
- **Email never arrives.** Inside Container Manager, click the container →
Log. Look for `[digest] Failed: ...`. Common causes:
- Wrong Gmail app password.
- 2-Step Verification not enabled on the Gmail account.
- Synology firewall blocking outbound port 587.
- **"Wrong password" when trying admin login.** Check `ADMIN_PASSWORD` in
`.env` and that you restarted the container after editing.
- **Port 3000 is taken.** Edit `docker-compose.yml` and change the left
side of the port mapping (e.g. `"8088:3000"`), then redeploy.
- **State got messed up.** Stop the container, edit
`data/checklists.json` directly, restart.