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>
162 lines
5.2 KiB
Markdown
162 lines
5.2 KiB
Markdown
# 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.
|