Failures went to REPORT_EMAIL, which is the media@ shared inbox the Sunday digest already uses. An alert competing with a routine weekly mail in a shared inbox is an alert that gets scrolled past, which is most of the way back to the logfile nobody read. ALERT_EMAIL is now a separate, comma-separated list for breakage only, falling back to REPORT_EMAIL so a machine whose .env predates this still alerts somewhere rather than silently not at all. Verified by sending one test alert, which arrived. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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)
- Sign in to the Google account you want to send from (your own, or a dedicated one — both work).
- Turn on 2-Step Verification at https://myaccount.google.com/security.
- Once 2-Step is on, go to https://myaccount.google.com/apppasswords.
- Create an app password called "Recurring Checklist". Google gives you a
16-character string like
abcd efgh ijkl mnop. Save it. - You'll paste that into
SMTP_PASSin.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:
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 (defaultAmerica/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
- Project name:
recurring-checklist - Path: browse to
/volume1/docker/recurring-checklist/ - Source: "Use existing docker-compose.yml"
- 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_PASSWORDfrom.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)
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_PASSWORDin.envand that you restarted the container after editing. - Port 3000 is taken. Edit
docker-compose.ymland change the left side of the port mapping (e.g."8088:3000"), then redeploy. - State got messed up. Stop the container, edit
data/checklists.jsondirectly, restart.