safeeyes
Protect your eyes from eye strain using this simple and beautiful, yet extensible break reminder
翻訳待ち
Zone-by-zone toothbrush timer PWA with a teeth diagram and audio/visual cues. Works offline. Self-hosts on a DigitalOcean droplet with Docker + Caddy, automatic HTTPS and auto-updates.
翻訳待ち
健康JavaScript · ShellGitHub @norbsmaqオンライン所有者未確認
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗A small, dependency-free web app that guides you through brushing your teeth zone by zone.
Brushing order: upper right → upper left, then lower left → lower right.
git clone https://github.com/norbsmaq/toothbrush-timer /opt/toothbrush-timer
cd /opt/toothbrush-timer
sudo ./setup-droplet.sh
The script asks for your domain name(s) and whether to enable HSTS (see below). Then it installs Docker if needed, opens ports 80 and 443 if ufw is active, turns on automatic updates, installs GoAccess for visitor stats, and starts the app. It finishes by printing the address to open.The container restarts automatically after reboots (restart: unless-stopped).
Point a DNS A record for each domain at the droplet's IP. For example, add records for both example.com and www.example.com. Then enter the domains when setup-droplet.sh asks, separated by spaces or commas:
Domains [none]: example.com www.example.com
The script warns you if a domain doesn't point at the droplet yet. Caddy gets and renews a Let's Encrypt certificate for each domain automatically, and serves the app on all of them. HTTPS is needed for the browser's keep-screen-awake feature and for installing the app on your phone. Everything else works over plain HTTP.
If you list both a domain and its www. version, the script also offers to redirect www.example.com to example.com (keeping the rest of the address). That way everyone ends up on one address, so an installed app and its saved settings always use the same one.
To change domains later, run sudo ./setup-droplet.sh again. It shows your current settings as defaults, so press Enter to keep any of them. Or edit .env directly (SITE_ADDRESS="example.com, www.example.com", REDIRECT_WWW=true) and run docker compose up -d.
By default the site sends an HSTS header. It tells browsers to always use HTTPS for your domain for the next year. Browsers ignore it over plain HTTP or an IP address, so it does no harm there.
If you're using a domain but might switch it back to plain HTTP later, answer n when the setup script asks about HSTS. Or set ENABLE_HSTS=false in .env and run docker compose up -d. Turning it off doesn't undo HSTS in browsers that have already received it; they keep it until it expires.
setup-droplet.sh turns on three kinds of automatic updates:
| What | How | When |
|---|---|---|
| Ubuntu security updates | unattended-upgrades | Daily. If an update needs a reboot, the droplet reboots at 04:00 and the app starts back up on its own. |
| Docker Engine | unattended-upgrades, from Docker's apt repository | Daily, along with the OS updates |
| The app and its Caddy web server | toothbrush-timer-update.timer runs update.sh | Daily around 03:30 |
update.sh makes the server's copy match the main branch on GitHub exactly, rebuilds on the newest Caddy image, restarts the container and removes old images. Anything pushed to main goes live on the next run. Any edits made directly to the repo's files on the server are overwritten. Your .env settings aren't part of the repo, so they're kept.
To update right away, run sudo ./update.sh. To see when the update last ran and when it runs next:
systemctl list-timers toothbrush-timer-update.timer
journalctl -u toothbrush-timer-update.service -n 50
To turn off the app auto-update: sudo systemctl disable --now toothbrush-timer-update.timer
.env is git-ignored, so your settings are kept across updates.
Caddy writes an access log for every request to logs/access.log in the app folder on the droplet. It starts a new file at 10 MB, compresses the old ones and deletes them after 90 days. setup-droplet.sh installs GoAccess, which turns the logs into a stats dashboard in your terminal. Nothing is published on the website.
To see the stats, SSH into the droplet and run:
cd /opt/toothbrush-timer
sudo ./stats.sh
It shows visitors, pages, browsers, operating systems and referrers per day, across the current and older log files. Use the arrow keys and Tab to move around, and press q to quit. Extra options are passed to GoAccess. For example, sudo ./stats.sh --ignore-crawlers hides search engine bots.
The logs include visitors' IP addresses and browser details. They stay on the droplet, readable only by root.
The app is a Progressive Web App (PWA). Once installed, it opens full-screen from your home screen and works offline.
Installing requires HTTPS, so set up a domain first (see above). Over plain http://IP it still works in the browser, but it won't install.
This is the beginning of the README. Read the rest at the original. Read the full README ↗