- Admin account bootstrapped from ADMIN_EMAIL/ADMIN_PASSWORD env vars on startup - Admin panel: list users, view content, reset passwords, disable/delete accounts - is_admin and is_disabled columns on users table - Disabled accounts blocked at login - README updated with admin setup instructions and panel docs Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sproutly 🌱
A self-hosted plant growth tracking web app designed to help home gardeners manage their seed starting schedules, growing cycles, and garden transitions — all anchored to their local last frost date.
Overview
Sproutly takes the guesswork out of seed starting. Enter your plant varieties once with their frost-relative timing (e.g. "start 8 weeks before last frost"), set your last frost date, and Sproutly calculates exactly when to start seeds, move to the greenhouse, and transplant to the garden. A daily push notification via ntfy keeps you on track without having to check the app.
Features
- Multi-user — each user has their own account with fully isolated data
- Admin panel — manage all user accounts: view content, reset passwords, disable, or delete
- Dashboard — at-a-glance view of overdue, today's, and upcoming tasks with a full year planting timeline
- Seed Library — manage plant varieties with frost-relative timing, germination days, sun/water requirements
- Garden Tracker — log growing batches and track status from
planned→germinating→seedling→potted up→hardening off→garden→harvested - Year Timeline — visual calendar showing when each variety's stages fall across the year
- Ntfy Notifications — per-user daily summary push notifications to your phone, configurable time, topic, and authentication
- Settings — set your last frost date, fall frost date, location, timezone, and notification preferences
Stack
| Layer | Technology |
|---|---|
| Frontend | Nginx (static HTML/CSS/JS SPA) |
| Backend | FastAPI (Python) |
| Database | MySQL 8.0 |
| Auth | JWT (python-jose + bcrypt) |
| Notifications | Ntfy |
| Runtime | Docker Compose |
Getting Started
Prerequisites
- Docker and Docker Compose
Run
git clone https://git.chns.tech/CooperandGoodman/sproutly.git
cd sproutly
cp .env.example .env # set a strong SECRET_KEY and DB credentials
docker compose up --build -d
Access the app at http://localhost:8053 — create an account to get started.
First Steps
- Register an account on the login screen
- Go to Settings and enter your last frost date — this anchors all planting schedule calculations
- Optionally configure an ntfy topic for push notifications
- Add varieties to your Seed Library and start logging batches in My Garden
Environment Variables
Copy .env.example to .env and fill in all values:
MYSQL_ROOT_PASSWORD=sproutly_root_secret
MYSQL_USER=sproutly
MYSQL_PASSWORD=sproutly_secret
SECRET_KEY=your-secret-key-change-this
ADMIN_EMAIL=admin@example.com
ADMIN_PASSWORD=change-this-password
SECRET_KEY is used to sign JWT tokens. Generate a secure value with:
python3 -c "import secrets; print(secrets.token_hex(32))"
ADMIN_EMAIL and ADMIN_PASSWORD define the super admin account. This account is created (or updated) automatically every time the backend starts — changing these values in .env and restarting is all that's needed to update the credentials.
Project Structure
sproutly/
├── docker-compose.yml
├── .env
├── mysql/
│ └── init.sql # Schema (multi-user)
├── backend/ # FastAPI application
│ ├── main.py
│ ├── auth.py # JWT + bcrypt utilities
│ ├── models.py
│ ├── schemas.py
│ ├── database.py
│ └── routers/
│ ├── auth.py # /auth/register, /auth/login, /auth/me
│ ├── admin.py # /admin/users — admin-only user management
│ ├── varieties.py
│ ├── batches.py
│ ├── dashboard.py
│ ├── settings.py
│ └── notifications.py
└── nginx/
├── nginx.conf
└── html/ # Static frontend SPA
├── index.html
├── css/style.css
└── js/app.js
API
The FastAPI backend is available at /api/ and includes automatic docs at http://localhost:8053/api/docs
All endpoints except /auth/register and /auth/login require a Authorization: Bearer <token> header.
Key endpoints:
POST /api/auth/register— create accountPOST /api/auth/login— get JWT tokenGET /api/auth/me— current user infoGET /api/dashboard/— dashboard data, tasks, and timelineGET/POST/PUT/DELETE /api/varieties/— seed variety managementGET/POST/PUT/DELETE /api/batches/— growing batch managementGET/PUT /api/settings/— app settingsPOST /api/notifications/test— send test ntfy notificationPOST /api/notifications/daily— trigger daily summaryGET /api/notifications/log— recent notification historyGET /api/admin/users— list all users with stats (admin only)GET /api/admin/users/{id}/varieties— view a user's seed library (admin only)GET /api/admin/users/{id}/batches— view a user's batches (admin only)POST /api/admin/users/{id}/reset-password— reset a user's password (admin only)POST /api/admin/users/{id}/disable— toggle account disabled state (admin only)DELETE /api/admin/users/{id}— delete a user and all their data (admin only)
Admin Panel
Log in with the ADMIN_EMAIL / ADMIN_PASSWORD credentials from your .env. Once logged in, an Admin link appears in the sidebar. From there you can:
- View all registered users with their variety and batch counts
- Browse any user's seed library and growing batches
- Reset a user's password
- Disable or re-enable an account
- Permanently delete an account and all associated data
The admin account itself cannot be disabled or deleted through the panel.
Ntfy Authentication
For private ntfy servers or access-controlled topics, the Settings page supports three auth modes:
| Mode | When to use |
|---|---|
| None | Public ntfy.sh topics |
| Username & Password | ntfy server with basic auth enabled |
| API Key / Token | ntfy account access token (generate in ntfy account settings) |
Status
Core infrastructure is functional. UI design and feature set are evolving based on user feedback.