Landing page and lead-capture system for Ashbi Design's website maintenance retainer service. Helps small teams and solo founders offload WordPress and static site upkeep.
Live site: retainer.ashbi.ca
- Landing page — Explains the maintenance service: uptime monitoring, plugin/core updates, daily backups, security scans, broken link detection, and monthly reporting.
- 3 pricing tiers — Essential ($99/mo, 1 site), Professional ($199/mo, 1 site + dev time), Agency ($499/mo, up to 5 sites).
- Lead capture form — Collects name, email, website URL, plan selection, and notes. Submits via JavaScript
fetchto the backend. - Mailgun integration — Each lead submission triggers an email notification via Mailgun API (configurable domain and recipient).
- Admin API — Authenticated endpoints to list and update leads (requires
ADMIN_KEY). - Lead storage — JSON file persistence in a Docker volume (
/data/leads.json). - Rate limiting — Max 5 submissions per IP per hour.
- Health check —
GET /api/healthreturns service status and lead count.
| Layer | Technology |
|---|---|
| Backend | Node.js + Express 4 |
| Frontend | Static HTML, CSS, vanilla JavaScript |
| Mailgun API (native HTTPS) | |
| Deployment | Docker + Coolify + Traefik |
| Storage | JSON file on Docker volume |
- Node.js 20+
- npm
npm install
MAILGUN_API_KEY=key-xxx \
MAILGUN_DOMAIN=ashbi.ca \
TO_EMAIL=cam@ashbi.ca \
ADMIN_KEY=your-secret \
node server.jsThe server starts on port 3000 (configurable via PORT). Static files (HTML, CSS, JS) are served from the project root.
| Variable | Required | Default | Description |
|---|---|---|---|
PORT |
No | 3000 |
HTTP port |
MAILGUN_API_KEY |
Yes | — | Mailgun API key |
MAILGUN_DOMAIN |
No | ashbi.ca |
Mailgun sending domain |
TO_EMAIL |
No | cam@ashbi.ca |
Notification recipient |
ADMIN_KEY |
Yes | — | Secret key for admin API access |
DATA_DIR |
No | /data |
Directory for leads.json |
| Method | Path | Auth | Description |
|---|---|---|---|
POST |
/api/lead |
None (rate-limited) | Submit lead form |
GET |
/api/leads |
x-admin-key header |
List all leads |
PATCH |
/api/leads/:id |
x-admin-key header |
Update lead status/notes |
GET |
/api/health |
None | Health check |
Build and run via Docker:
docker build -t maintenance-retainer:latest .
# See deploy.sh for the full Coolify/Traefik deployment commandThe container exposes port 3000 with a health check on /api/health. Mount a volume at /data for lead persistence. Pass environment variables via --env-file.
├── index.html # Landing page (hero, features, pricing, FAQ, signup form)
├── thanks.html # Post-submission thank-you page
├── privacy.html # Privacy policy
├── admin.html # Admin dashboard (lists leads)
├── style.css # All styling
├── script.js # Form submission, plan selection, admin UI
├── server.js # Express backend (API routes, Mailgun, rate limiting)
├── Dockerfile # Production Docker image
├── deploy.sh # Coolify deployment script
└── package.json # Node dependencies (express only)
See LICENSE.