MyParent is a self-hosted co-parenting calendar designed for small families that need day-level notes, custody schedules, and admin-managed access. The platform ships as a full-stack monorepo with a Fastify API, a React + Tailwind web app, and Docker-first deployment tooling.
| Component | Tech | Responsibilities |
|---|---|---|
| apps/web | React 18, Vite, Tailwind v4, Zustand, React Query | Browser UI, schedule visualization, consuming /api endpoints via cookies, static assets served through nginx in production. |
| apps/api | Node.js 20, Fastify, Prisma ORM, SQLite | REST API, authentication, RBAC, Prisma migrations, custody template automation. |
| nginx | nginx:1.27-alpine | Reverse proxy, serves built frontend (/), forwards /api → api:8080, handles static caching and compression. |
| Docker Compose | docker-compose.yml |
Orchestrates api, web, nginx containers and the api_data volume that persists the SQLite database. |
Prerequisites: Node.js 20+, npm 10+, SQLite client (optional), and Docker Desktop (optional for local DB resets).
# 1. Clone and install dependencies
npm install
# 2. Copy environment defaults and adjust secrets
cp .env.example .env
# 3. Apply database migrations (creates dev SQLite at apps/api/prisma/dev.db)
npm run -w apps/api migrate:dev
# 4. Start API (Fastify on :8080) + Web (Vite on :5173) concurrently
npm run devAccess the web UI at http://localhost:5173. The API is reachable at http://localhost:8080/api when proxied through the Vite dev server. Sign in with the bootstrap admin configured via ADMIN_BOOTSTRAP_USER / ADMIN_BOOTSTRAP_PASS.
# Build production images and generate the frontend bundle into the shared volume
docker compose build
# Launch nginx (80), API (8080 internal), and web builder containers
docker compose up -d
# Tail the gateway logs for readiness
docker compose logs -f nginx
# Stop services when finished
docker compose downThe nginx reverse proxy listens on http://localhost and forwards /api requests to the Fastify service. Persistent application data is stored in the api_data volume (/app/data/db.sqlite inside the API container).
| Variable | Default | Description |
|---|---|---|
DATABASE_URL |
file:/app/data/db.sqlite (Docker) / file:../prisma/dev.db (dev) |
Prisma SQLite connection string. In production the path must point to the mounted volume. |
PORT |
8080 |
Fastify listen port inside the API container. |
API_BASE_PATH |
/api |
Prefix for all API routes. Must stay aligned with nginx proxy config and frontend VITE_API_BASE. |
JWT_SECRET |
(required) | 32+ byte secret for signing session JWTs stored in HttpOnly cookies. |
ADMIN_BOOTSTRAP_USER |
admin |
Initial admin username created on first boot when no users exist. |
ADMIN_BOOTSTRAP_PASS |
changeme |
Initial admin password; rotate immediately after first login. |
COOKIE_SECURE |
false |
Set to true in TLS deployments so cookies are marked Secure. |
API_CORS_ORIGIN |
unset | Optional override when running API and frontend on different origins in dev. |
SKIP_DB_SYNC |
false |
Skip Prisma schema synchronization on startup (used for read-only or migration-less environments). |
VITE_API_BASE |
/api |
Frontend path prefix for API calls in production builds. |
VITE_DEV_API_URL |
http://localhost:8080 |
Alternate API origin for the Vite dev server when bypassing nginx. |
# Obtain an auth cookie (replace credentials to match your bootstrap admin)
curl -i -c cookies.txt \
-H 'Content-Type: application/json' \
-X POST http://localhost/api/auth/login \
-d '{"username":"admin","password":"changeme"}'
# Fetch the active month of calendar items (requires auth cookie)
curl -b cookies.txt "http://localhost/api/items?month=$(date +%Y-%m)"
# Retrieve the computed custody schedule for the current month
curl -b cookies.txt "http://localhost/api/schedule?month=$(date +%Y-%m)"This repository is private and all rights are reserved. Access is restricted to authorized contributors under the MyParent contributor agreement.