# CertRemind CertRemind monitors the TLS/SSL certificate expiry dates of registered HTTPS sites and sends reminders through in-app alerts, webhooks, and browser push notifications. ## Requirements - Node.js v22 - pnpm - Docker Compose - PostgreSQL - OpenSSL ## Development Setup ```text pnpm install docker compose up -d postgres pnpm dev ``` Development URLs: ```text Frontend: http://127.0.0.1:5173/ API: http://127.0.0.1:3000 ``` ## Docker Compose Production-like startup: ```text docker compose up -d --build ``` If your Docker CLI does not provide the Compose v2 subcommand, use `docker-compose` with the same arguments. Production URL: ```text App: http://127.0.0.1:3000/ ``` This starts PostgreSQL, the Web/API application, and the hourly certificate monitor worker. The application container serves the built React assets from `dist` through the Hono server. Docker-based development startup: ```text docker compose -f docker-compose.yml -f docker-compose.dev.yml up --build ``` Development URLs: ```text Frontend: http://127.0.0.1:5173/ API: http://127.0.0.1:3000 ``` The Compose application port mappings bind to `127.0.0.1` only, so the application ports are not published on external network interfaces. PostgreSQL is not published to the host; only the `app` and `monitor-worker` services can reach it through the internal Compose network. Inside containers, the application binds to `0.0.0.0` through `HOST=0.0.0.0`; host exposure is controlled by Compose. Run the one-shot certificate monitor: ```text pnpm monitor:once ``` Run the certificate monitor worker every hour: ```text pnpm monitor:worker ``` Run quality checks: ```text pnpm lint pnpm test pnpm exec vite build ``` ## Database The initial schema is in `db/schema.sql`. Docker Compose loads it when the PostgreSQL volume is first created. If an existing database volume is already present, schema changes are not reapplied automatically. Apply the relevant `ALTER TABLE` statements from `db/schema.sql`, or recreate the development volume when data loss is acceptable. ## Environment Variables Copy `.env.example` to `.env` for local development. | Name | Required | Default | Purpose | | --- | --- | --- | --- | | `NODE_ENV` | No | `development` | Runtime mode. `production` enables secure cookies. | | `HOST` | No | `127.0.0.1` | Server listen host. Compose sets this to `0.0.0.0` inside containers. | | `PORT` | No | `3000` | API server port. | | `DATABASE_URL` | No | `postgres://certremind:certremind@localhost:5432/certremind` | PostgreSQL connection string. | | `COOKIE_SECRET` | Reserved | none | Reserved for future signed-cookie support. | | `VAPID_PUBLIC_KEY` | For Push | empty | Browser Push public key. | | `VAPID_PRIVATE_KEY` | For Push | empty | Browser Push private key. Push delivery fails gracefully if missing. | | `VAPID_SUBJECT` | For Push | `mailto:admin@example.com` | VAPID contact subject. | | `OPENSSL_PATH` | No | `openssl` | OpenSSL executable path. On Windows, the app can also detect Git's bundled `openssl.exe`. | | `CAPTCHA_PROVIDER` | No | `off` | Auth CAPTCHA provider. Use `turnstile`, `hcaptcha`, or `off`. | | `CAPTCHA_SITE_KEY` | When CAPTCHA enabled | empty | Public site key used by the login/register widget. | | `CAPTCHA_SECRET_KEY` | When CAPTCHA enabled | empty | Server-side secret key used to verify CAPTCHA tokens. | | `CAPTCHA_VERIFY_TIMEOUT_MS` | No | `3000` | Timeout for provider verification requests. | For local host execution, `DATABASE_URL` normally points to `localhost:5432`. For Docker Compose services, it points to the internal service name: `postgres://certremind:certremind@postgres:5432/certremind`. CAPTCHA is disabled by default. To enable it, set `CAPTCHA_PROVIDER` to `turnstile` or `hcaptcha` and provide both keys. Login and registration then require a provider token, and TOTP logins require a fresh token for each POST. ## Operational Notes - Run `pnpm monitor:worker` as a long-lived Node process for hourly certificate checks. - `docker compose up -d --build` runs the monitor worker as the `monitor-worker` service. - `pnpm monitor:once` remains available for manual checks or external schedulers. - The monitor limits concurrent external certificate checks and records per-site failures without stopping the whole run. - Webhook URLs and monitored site URLs must be HTTPS and reject localhost/private IPv4 targets. - The account profile timezone is used when formatting user-facing dates such as webhook alert expiry times. Webhook alert messages can be customized per user from the notification methods screen; if unset, CertRemind uses the default template. - Existing browser Push subscriptions require valid VAPID keys to deliver successfully.