Files
Waters ChurchandClaude Opus 5 b03fb252d8
Build apps / build (push) Failing after 35s
Deploy web to NAS / deploy (push) Successful in 1m21s
Note in index.html how a change here reaches the web and the apps
This directory feeds both targets by different routes, and the difference is the
thing people get wrong: the website serves it directly, while the apps carry a
copy frozen at build time. Someone editing here reasonably assumes a deploy is
enough, and for the website it is.

Written at the top of the file rather than in a README because this is where the
assumption gets made.

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

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:

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)

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.