Family OS is a private, self-hosted family archive — a single place for a family's history, documents, photos, stories, and day-to-day conversation, built for families who want to keep their own records under their own control rather than scattered across social media accounts they don't own.
It runs on ordinary shared hosting (the kind most cPanel providers sell) with no special server access required: no SSH, no Composer, no Node build step, no background job workers beyond what cPanel's own Cron Manager already provides. Everything is plain PHP, MySQL/MariaDB, and vanilla JavaScript.
| Requirement | Details |
|---|---|
| PHP | 8.1 or newer (built and tested on 8.3) |
| Database | MySQL 5.7+ or MariaDB 10.3+ |
| PHP extensions | pdo_mysql, mbstring, curl, dom/libxml, gd or imagick (image uploads), json, openssl — all standard on cPanel hosting and enabled by default on almost every shared host |
| Disk space | Minimal for the application itself (a few MB); plan for growth based on how many photos/documents/audio files the family uploads |
| Cron access | cPanel Cron Manager (or equivalent) for scheduled tasks — see Setting up cron jobs |
| Outbound connections | Needed only if using email (SMTP) or payment gateways (Paystack/M-Pesa/PayPal) — the core app works fully offline-capable otherwise |
public_html/familyos/) if you'd rather it live at a sub-path.uploads/ directory (and its subfolders) are writable by the web
server — typically permission 755 is sufficient on shared hosting;
if uploads fail, try 775.schema_v1.sql first.migrations/, strictly in numeric order
(002, 003, 004, and so on) — each one builds on the last, and importing out of order will
fail. See the full migrations appendix for exactly what each one
adds.Open config.php in a text editor and fill in:
define('DB_HOST', 'localhost');
define('DB_NAME', 'your_database_name');
define('DB_USER', 'your_database_user');
define('DB_PASS', 'your_database_password');
define('SITE_URL', 'https://yourdomain.com/familyos'); // no trailing slash
define('SITE_NAME', 'Family OS'); // shown until changed in Settings
define('SITE_TIMEZONE', 'Africa/Nairobi'); // see note below
define('SMTP_HOST', ''); // optional — can also be set later in Settings
define('SMTP_PORT', 587);
define('SMTP_USER', '');
define('SMTP_PASS', '');
define('SMTP_FROM_EMAIL', '');
define('SMTP_FROM_NAME', '');
Africa/Nairobi, America/New_York, Europe/London). The
application uses this single setting to keep PHP and the database's internal clocks in
agreement, so that "posted 2 minutes ago" is actually accurate rather than off by however many
hours your hosting server's own default timezone happens to differ from the family's. This is
handled automatically as long as this one value is set correctly — see
Troubleshooting if timestamps still look wrong after installation.
In cPanel's Cron Manager, add these three jobs (adjust the path to match your actual install location):
# Every 5-10 minutes — sends queued emails
*/10 * * * * php /home/youruser/public_html/familyos/cron/send-queued-emails.php
# Once daily — checks for upcoming birthdays
0 6 * * * php /home/youruser/public_html/familyos/cron/check-birthdays.php
# Once daily — compiles daily/weekly digest emails
0 7 * * * php /home/youruser/public_html/familyos/cron/send-digests.php
None of these are required for the core application to work — they only power email notifications and digests. Skip them entirely if the family doesn't want email notifications.
A default administrator account is created by schema_v1.sql:
admin@family.local | |
| Password | ChangeMe123! |
Recommended order for setting up a new family archive:
The landing screen after login. Shows live counts (family members, documents, photos, upcoming events, storage used) and a recent activity feed drawn from every action taken across the whole system. Repeated identical actions (like saving the same settings form twice in a row) collapse into a single line with a count, rather than cluttering the feed.
The core record for each person: name, gender, birth/death dates, birthplace, current location, a biography, contact details, and a profile photo. Each member also has a visibility setting:
| Visibility | Who can see this person's profile |
|---|---|
| Public to family | Any logged-in family member |
| Lineage only | Only their direct ancestors and descendants |
| Private | Only admins and the person themselves (if they have an account) |
Birth and death certificates can be attached directly from the member's edit page; they're stored as regular documents with the same privacy protection as anything else in Documents.
An interactive, pannable/zoomable tree view, plus a plain list view grouped by generation for anyone who'd rather not use the visual version. Relationships are entered directly (parent, child, spouse, sibling) and the system automatically works out everything else that follows logically — grandparents, grandchildren, aunts/uncles, nieces/nephews, cousins, step-relations — without anyone having to enter those by hand.
These inferred relationships appear on Relationship Review (Admin) for a human to confirm or reject before they're treated as settled fact — the system suggests, but a person always has the final say.
Upload birth certificates, land deeds, letters, or any other family paperwork (PDF, JPG, PNG, WEBP). Every document has its own privacy level (private / lineage / family), and can also be individually shared with specific people beyond what that level would normally allow. Documents are never served directly from a public folder — every single request is checked against the viewer's actual permissions first.
A photo gallery with person-tagging — click to tag anyone in the family in any photo, and their name links back to their profile (or shows as "Private profile" if their visibility doesn't allow it). Photo privacy follows the same private/lineage/family model as documents.
Upload recorded voices and audio stories (MP3, M4A, OGG, WAV) with the same privacy controls as documents and photos. Playback supports seeking within long recordings without downloading the whole file first.
Long-form written stories with a lightweight formatting toolbar (bold, italic, headings, lists, quotes) built in — or, if a TinyMCE key is configured in Settings, a full rich-text editor instead. Stories support comments, so more than one person can add their own memory of the same event.
Threaded discussion boards for topics that deserve more permanence than a chat message — reunion planning, ongoing decisions, shared documents. Posts support pinning, likes, and file attachments. A forum can be marked private, restricting it to adult members only.
One shared, always-on family chat room for everyday conversation, refreshed automatically every few seconds. Supports @mentioning someone by the first word of their display name to notify them directly.
Private one-on-one conversations between two people, separate from the group Forum and Chat. An inbox lists every conversation with an unread count, and starting a new conversation is as simple as picking anyone from the family directory. New messages trigger a notification exactly like everything else in the system.
A monthly calendar combining manually-added events (birthdays, anniversaries, reunions,
meetings) with birthdays computed automatically from each member's birth date —
nobody has to create a birthday event for every person by hand. Recurring events (like an
anniversary) reappear every year without duplicating rows. Every event can be downloaded as a
standard .ics calendar file or added directly to Google Calendar with one click.
A single chronological view combining events, dated stories, document upload dates, and birth/death dates — the closest thing to a running history of the whole family in one place, respecting the same privacy rules as everywhere else.
One combined map showing where everyone in the family lives or comes from. Adding a location to a member's profile is as simple as pasting a Google Maps link — either the share link from the Google Maps app ("Share" button), or the embed code from "Share > Embed a map." Coordinates are extracted automatically from whichever is pasted; nobody needs to look up or enter latitude/longitude by hand.
No Google API key is required for this — it uses Google's own free, keyless embed and map-link formats, plus free OpenStreetMap map tiles for the combined view.
Lets the family raise money for shared projects and causes — a new roof, a reunion, a medical need — with a goal amount and a visible progress bar. Donations are accepted through whichever payment gateways have been configured in Settings:
| Gateway | Good for |
|---|---|
| Paystack | Card and bank payments (strong in Africa) |
| M-Pesa | Mobile money (Kenya/East Africa) — an STK push prompt appears directly on the donor's phone |
| PayPal | International card and PayPal-balance payments |
All three are entirely optional — a fundraiser only offers the ones that are actually configured. None of them ever puts card details or M-Pesa PINs through this server: each uses its own secure, hosted checkout. Every payment is independently verified with the payment provider directly before being counted, so a donation can never be faked by simply visiting a "success" URL.
A bell icon in the top bar shows an unread count, checked automatically every few seconds. Notifications cover forum replies, photo tags, new documents, new family members, story comments, chat mentions, direct messages, and upcoming birthdays. Each person controls, per category, whether they want in-app notifications, email, both, or neither — and can choose to receive a single daily or weekly email digest instead of one email per event, from My Account.
There are three account roles:
| Role | Typical use |
|---|---|
| Admin | Full access to everything, including Settings and user management. Always has full access to every module — an admin account can never accidentally be locked out. |
| Adult Member | A regular adult family member — can add content, but not manage settings or other accounts |
| Child View | A more restricted account, typically for younger family members |
Under Settings > Roles & Permissions, an admin can control which modules (Forum, Photos, Fundraising, and so on) each of the two non-admin roles can see in their sidebar at all. This sits on top of — and doesn't replace — the individual privacy level set on each document, photo, or profile.
| Section | Covers |
|---|---|
| Site Information | Site name, tagline (shown on the public landing page), contact email |
| Appearance | Theme (4 built-in color palettes) and an optional logo upload — when a logo is set, it replaces the text site name wherever it would normally appear |
| Email (SMTP) | Mail server details for notification emails, with a "send test email" button |
| Payment Gateways | Paystack, M-Pesa, and PayPal credentials for Fundraising |
| API Keys | An optional TinyMCE key for richer text editing |
Generates a complete, downloadable .sql backup of the entire database on demand —
every table's structure and data, ready to restore into a fresh database if ever needed. Also
offers a lighter export of just the family member/relationship data, as CSV or JSON, useful for
keeping a portable copy outside the system entirely.
Seeds a realistic three-generation sample family with documents, stories, an event, a forum post, and a sample fundraiser — useful for demonstrating the system, or just for seeing what a populated family tree looks like before adding real data. Every row it creates is tracked internally, so "Remove demo data" deletes exactly what the seeder added and nothing else — any real family data already present is left completely untouched.
New registrations appear as pending requests under Admin Tools for an admin to approve or decline. Repeated failed login attempts are automatically throttled, both per-account and per-location, to slow down guessing attacks.
Almost always a stale browser cache serving an old copy of the stylesheet. The application automatically busts the cache on every update, so re-uploading the latest files and doing one hard refresh (Ctrl+Shift+R / Cmd+Shift+R) resolves this. If a setting genuinely didn't save, check for an error message at the top of the Settings page — it usually means a database migration hasn't been imported yet.
This is a timezone mismatch between the web server and the database server — extremely common on
shared hosting, where the two can silently disagree. Check that SITE_TIMEZONE in
config.php is set correctly (see Configuring config.php)
— the application uses this single value to keep both sides of the system in agreement
automatically. If timestamps were wrong before this was set correctly, only newly-created records
from that point onward will show correctly; existing historical timestamps may need a one-time
manual correction if the discrepancy is significant.
Logos are sized to fit their space without cropping (using their full width or height, whichever fits), so any reasonably-sized logo image should display cleanly. If it still looks wrong, confirm the uploaded file isn't corrupted and try a different image format (PNG or JPG both work well).
Payments only count once verified directly with the gateway — for Paystack and PayPal this happens automatically when the donor returns to the site; for M-Pesa it depends on Safaricom's servers successfully reaching this site's callback URL (see Fundraising & Payments). If a donation seems stuck, check that the M-Pesa callback URL shown in Settings is correctly registered with the Daraja app, and that the hosting account allows incoming connections to that URL.
Use the "Send a test email" button in Settings > Email — it will report the specific error
(wrong credentials, wrong port, host unreachable) rather than failing silently. Also confirm the
cron/send-queued-emails.php job is actually scheduled and running (see
Cron Jobs Reference).
| Script | Suggested schedule | Purpose |
|---|---|---|
cron/send-queued-emails.php | Every 5–10 minutes | Sends any emails waiting in the queue, so a page request never has to wait on a slow mail server |
cron/check-birthdays.php | Once daily | Notifies the family about birthdays coming up in the next 7 days |
cron/send-digests.php | Once daily | Compiles daily/weekly digest emails for anyone who has chosen that option in My Account |
None of these are required for the core application — only for email notifications specifically.
Import schema_v1.sql first, then every file below in this exact order:
| File | Adds |
|---|---|
schema_v1.sql | Base schema — all core tables |
002_phase2_member_photo_filename.sql | Original filename tracking for member photos |
003_phase3_documents_and_relationships.sql | Document categories and relationship-sharing tables |
004_phase7_settings_and_forum.sql | Site settings store, discussion forum tables |
005_phase9_permissions_and_notifications.sql | Role-based module permissions, per-user digest frequency |
006_fundraising_and_payments.sql | Fundraisers and donations tables |
007_phase11_demo_data.sql | Demo data tracking table |
008_direct_messages_and_maps_link.sql | Direct messaging, Google Maps link field, extended notification categories |
Family OS is built and sold by MoJamoza Technologies, Namanga, Kenya.
For support, customization requests, or questions about this documentation, please contact the team through the channel provided at the time of purchase.