Aktualisieren von README.md

This commit is contained in:
ulsklyc
2026-03-29 01:17:56 +01:00
committed by GitHub
parent 8e01d4c749
commit 396050e2cf
+103 -107
View File
@@ -1,90 +1,56 @@
<p align="center"> <p align="center">
<!-- Logo: Replace with your logo once created (recommended: SVG, 128×128 or 256×256) --> <!-- Replace with your logo: recommended 120160px, SVG or PNG, transparent background -->
<!-- <img src="public/logo.svg" alt="Oikos Logo" width="128"> --> <!-- <img src="docs/logo.svg" alt="Oikos" width="140"> -->
<h1>🏠 Oikos</h1> <img src="https://img.shields.io/badge/%F0%9F%8F%A0-Oikos-007AFF?style=for-the-badge&labelColor=F5F5F7" alt="Oikos" height="48">
<strong>Self-hosted family planner — private, open, no subscription.</strong> </p>
<h1 align="center">Oikos</h1>
<p align="center">
<strong>Self-hosted family planner — tasks, calendars, shopping, meals, budget.</strong><br>
Your data stays on your server. No subscriptions. No tracking. No cloud lock-in.
</p> </p>
<p align="center"> <p align="center">
<a href="https://github.com/ulsklyc/oikos/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue?style=flat-square" alt="MIT License"></a> <a href="https://github.com/ulsklyc/oikos/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue?style=flat-square" alt="MIT License"></a>
<img src="https://img.shields.io/badge/node-%3E%3D20-339933?style=flat-square&logo=node.js&logoColor=white" alt="Node.js >=20"> <a href="https://nodejs.org"><img src="https://img.shields.io/badge/node-%3E%3D20-339933?style=flat-square&logo=node.js&logoColor=white" alt="Node.js 20"></a>
<img src="https://img.shields.io/badge/docker-ready-2496ED?style=flat-square&logo=docker&logoColor=white" alt="Docker Ready"> <a href="https://www.docker.com"><img src="https://img.shields.io/badge/docker-ready-2496ED?style=flat-square&logo=docker&logoColor=white" alt="Docker Ready"></a>
<img src="https://img.shields.io/badge/SQLCipher-AES--256-003B57?style=flat-square&logo=sqlite&logoColor=white" alt="SQLCipher Encrypted"> <a href="https://www.zetetic.net/sqlcipher/"><img src="https://img.shields.io/badge/SQLCipher-AES--256-003B57?style=flat-square&logo=sqlite&logoColor=white" alt="SQLCipher Encrypted"></a>
<img src="https://img.shields.io/badge/PWA-offline--capable-5A0FC8?style=flat-square&logo=pwa&logoColor=white" alt="PWA Offline"> <a href="https://web.dev/progressive-web-apps/"><img src="https://img.shields.io/badge/PWA-offline--capable-5A0FC8?style=flat-square&logo=pwa&logoColor=white" alt="PWA Offline"></a>
<a href="https://github.com/ulsklyc/oikos/stargazers"><img src="https://img.shields.io/github/stars/ulsklyc/oikos?style=flat-square&color=f5c542" alt="GitHub Stars"></a> <a href="https://github.com/ulsklyc/oikos/stargazers"><img src="https://img.shields.io/github/stars/ulsklyc/oikos?style=flat-square&color=f5c542" alt="GitHub Stars"></a>
<a href="https://github.com/ulsklyc/oikos/commits/main"><img src="https://img.shields.io/github/last-commit/ulsklyc/oikos?style=flat-square" alt="Last Commit"></a> <a href="https://github.com/ulsklyc/oikos/commits/main"><img src="https://img.shields.io/github/last-commit/ulsklyc/oikos?style=flat-square" alt="Last Commit"></a>
</p> </p>
<p align="center">
Oikos is a self-hosted family organizer for 26 people. Tasks, calendars, shopping lists, meal plans, budget tracking, and more — all running on your own server. No cloud dependency. No data leaves your network. No tracking.
</p>
<p align="center"> <p align="center">
<a href="#features">Features</a> · <a href="#quick-start">Quick Start</a> · <a href="#configuration">Configuration</a> · <a href="#calendar-sync">Calendar Sync</a> · <a href="#security">Security</a> <a href="#features">Features</a> · <a href="#quick-start">Quick Start</a> · <a href="#configuration">Configuration</a> · <a href="#calendar-sync">Calendar Sync</a> · <a href="#security">Security</a>
</p> </p>
--- ---
Oikos is a self-hosted family organizer for 26 people. Tasks, calendars, shopping lists, meal plans, budget tracking, notes, and contacts — all running on your own server inside a single Docker container. No cloud dependency, no telemetry, no data leaves your network.
Built with Express.js, SQLite (optionally encrypted via SQLCipher), and vanilla JavaScript — no frontend framework, no build step. Works offline as a PWA on phones and tablets.
Oikos is **not** a SaaS product, not a team collaboration tool, and not designed for public multi-tenant use. It is a private tool for one family on one server.
---
## Screenshots
<p align="center"> <p align="center">
<picture> <img src="docs/screenshots/tablet-light/tablet-light-dashboard.png" alt="Dashboard" width="720">
<source media="(prefers-color-scheme: dark)" srcset="docs/screenshots/tablet-dark/tablet-dark-dashboard.png">
<source media="(prefers-color-scheme: light)" srcset="docs/screenshots/tablet-light/tablet-light-dashboard.png">
<img src="docs/screenshots/tablet-light/tablet-light-dashboard.png" alt="Dashboard" width="800">
</picture>
</p> </p>
<table> <table>
<tr> <tr>
<td align="center" width="33%"> <td align="center"><img src="docs/screenshots/mobile-light/mobile-light-tasks.png" alt="Tasks" width="220"><br><strong>Tasks</strong></td>
<picture> <td align="center"><img src="docs/screenshots/mobile-light/mobile-light-shopping.png" alt="Shopping" width="220"><br><strong>Shopping</strong></td>
<source media="(prefers-color-scheme: dark)" srcset="docs/screenshots/mobile-dark/mobile-dark-tasks.png"> <td align="center"><img src="docs/screenshots/mobile-light/mobile-light-budget.png" alt="Budget" width="220"><br><strong>Budget</strong></td>
<source media="(prefers-color-scheme: light)" srcset="docs/screenshots/mobile-light/mobile-light-tasks.png">
<img src="docs/screenshots/mobile-light/mobile-light-tasks.png" alt="Tasks" width="240">
</picture>
<br><strong>Tasks</strong>
</td>
<td align="center" width="33%">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="docs/screenshots/mobile-dark/mobile-dark-household.png">
<source media="(prefers-color-scheme: light)" srcset="docs/screenshots/mobile-light/mobile-light-household.png">
<img src="docs/screenshots/mobile-light/mobile-light-household.png" alt="Shopping" width="240">
</picture>
<br><strong>Shopping</strong>
</td>
<td align="center" width="33%">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="docs/screenshots/mobile-dark/mobile-dark-budget.png">
<source media="(prefers-color-scheme: light)" srcset="docs/screenshots/mobile-light/mobile-light-budget.png">
<img src="docs/screenshots/mobile-light/mobile-light-budget.png" alt="Budget" width="240">
</picture>
<br><strong>Budget</strong>
</td>
</tr> </tr>
<tr> <tr>
<td align="center"> <td align="center"><img src="docs/screenshots/mobile-light/mobile-light-notes.png" alt="Notes" width="220"><br><strong>Notes</strong></td>
<picture> <td align="center"><img src="docs/screenshots/mobile-light/mobile-light-contacts.png" alt="Contacts" width="220"><br><strong>Contacts</strong></td>
<source media="(prefers-color-scheme: dark)" srcset="docs/screenshots/mobile-dark/mobile-dark-notes.png"> <td align="center"><img src="docs/screenshots/tablet-light/tablet-light-calendar.png" alt="Calendar Tablet" width="220"><br><strong>Calendar — Tablet</strong></td>
<source media="(prefers-color-scheme: light)" srcset="docs/screenshots/mobile-light/mobile-light-notes.png">
<img src="docs/screenshots/mobile-light/mobile-light-notes.png" alt="Notes" width="240">
</picture>
<br><strong>Notes</strong>
</td>
<td align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="docs/screenshots/mobile-dark/mobile-dark-contacts.png">
<source media="(prefers-color-scheme: light)" srcset="docs/screenshots/mobile-light/mobile-light-contacts.png">
<img src="docs/screenshots/mobile-light/mobile-light-contacts.png" alt="Contacts" width="240">
</picture>
<br><strong>Contacts</strong>
</td>
<td align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="docs/screenshots/tablet-dark/tablet-dark-notes.png">
<source media="(prefers-color-scheme: light)" srcset="docs/screenshots/tablet-light/tablet-light-notes.png">
<img src="docs/screenshots/tablet-light/tablet-light-notes.png" alt="Tablet View" width="240">
</picture>
<br><strong>Tablet View</strong>
</td>
</tr> </tr>
</table> </table>
@@ -92,19 +58,23 @@
<sub>Screenshots adapt to your GitHub theme — switch between light and dark mode to see both variants.</sub> <sub>Screenshots adapt to your GitHub theme — switch between light and dark mode to see both variants.</sub>
</p> </p>
---
## Features ## Features
| | Module | What it does | Highlights | | | Module | What it does | Highlights |
|---|---|---|---| |---|---|---|---|
| 📋 | **Dashboard** | At-a-glance overview of your family's day | Weather widget, upcoming events, urgent tasks, today's meals, pinned notes | | 📋 | **Dashboard** | At-a-glance overview of your family's day | Weather widget · upcoming events · urgent tasks · today's meals · pinned notes |
| ✅ | **Tasks** | Shared to-do lists with accountability | List + Kanban views, subtasks, recurring tasks (RRULE), swipe gestures, priority levels | | ✅ | **Tasks** | Shared to-do lists with accountability | List + Kanban views · subtasks · recurring tasks (RRULE) · swipe gestures · priority levels |
| 🛒 | **Shopping** | Collaborative grocery lists | Multiple lists, aisle-grouped categories, auto-import from meal plan | | 🛒 | **Shopping** | Collaborative grocery lists | Multiple lists · aisle-grouped categories · auto-import from meal plan |
| 🍽️ | **Meals** | Weekly meal planning | Week view (MonSun), ingredient management, one-click export to shopping list | | 🍽️ | **Meals** | Weekly meal planning with ingredients | Week view (MonSun) · ingredient management · one-click export to shopping list |
| 📅 | **Calendar** | Family calendar with external sync | Month/week/day/agenda views, Google Calendar & Apple iCloud sync (two-way) | | 📅 | **Calendar** | Family calendar with external sync | Month/week/day/agenda views · Google Calendar & Apple iCloud two-way sync |
| 📌 | **Notes** | Shared family pinboard | Colored sticky notes, pinning, lightweight Markdown (bold, italic, lists) | | 📌 | **Notes** | Shared family pinboard | Colored sticky notes · pinning · lightweight Markdown (bold, italic, lists) |
| 👥 | **Contacts** | Important family contacts | Category filters, tap-to-call, tap-to-email, map links for addresses | | 👥 | **Contacts** | Important family contacts | Category filters · tap-to-call · tap-to-email · map links for addresses |
| 💰 | **Budget** | Income & expense tracking | Category breakdown, month-over-month comparison, CSV export | | 💰 | **Budget** | Income & expense tracking | Category breakdown · month-over-month comparison · CSV export |
| ⚙️ | **Settings** | User & sync management | Password changes, calendar sync config, family member admin | | ⚙️ | **Settings** | User & sync management | Password changes · calendar sync config · family member admin |
---
## Tech Stack ## Tech Stack
@@ -116,26 +86,29 @@
<img src="https://img.shields.io/badge/PWA-5A0FC8?style=flat-square&logo=pwa&logoColor=white" alt="PWA"> <img src="https://img.shields.io/badge/PWA-5A0FC8?style=flat-square&logo=pwa&logoColor=white" alt="PWA">
</p> </p>
**Backend:** Node.js, Express, SQLite via better-sqlite3, optional SQLCipher encryption (AES-256), bcrypt, express-session, Helmet | Layer | Technology |
|---|---|
| **Server** | Node.js ≥ 20 · Express · better-sqlite3 · bcrypt · Helmet |
| **Database** | SQLite with optional SQLCipher encryption (AES-256) |
| **Frontend** | Vanilla JavaScript ES modules — no framework, no build step. Web Components (`oikos-*`). Lucide Icons (self-hosted SVG sprite) |
| **Auth** | Session-based · httpOnly cookies · CSRF double-submit · express-session |
| **Deployment** | Docker + Docker Compose · Nginx reverse proxy · Let's Encrypt SSL |
| **Integrations** | Google Calendar API v3 (OAuth 2.0) · Apple iCloud CalDAV (tsdav) · OpenWeatherMap |
**Frontend:** Vanilla JavaScript ES modules — no framework, no build step, no bundler. Web Components for reusable UI. Lucide Icons (self-hosted SVG sprite). ---
**Deployment:** Docker + Docker Compose, Nginx reverse proxy with SSL, PWA with service worker for offline support
**Integrations:** Google Calendar API v3 (OAuth 2.0), Apple iCloud CalDAV via tsdav, OpenWeatherMap
## Quick Start ## Quick Start
**Prerequisites:** Docker + Docker Compose on a Linux server. **Prerequisites:** Docker + Docker Compose on a Linux server.
**1. Clone** ### 1. Clone
```bash ```bash
git clone https://github.com/ulsklyc/oikos.git git clone https://github.com/ulsklyc/oikos.git
cd oikos cd oikos
``` ```
**2. Configure** ### 2. Configure
```bash ```bash
cp .env.example .env cp .env.example .env
@@ -148,7 +121,7 @@ SESSION_SECRET=your-random-string-at-least-32-chars
DB_ENCRYPTION_KEY=your-sqlcipher-aes256-key DB_ENCRYPTION_KEY=your-sqlcipher-aes256-key
``` ```
**3. Start** ### 3. Start
```bash ```bash
docker compose up -d docker compose up -d
@@ -156,22 +129,24 @@ docker compose up -d
First build takes 23 minutes (compiles SQLCipher against better-sqlite3). First build takes 23 minutes (compiles SQLCipher against better-sqlite3).
**4. Create admin account** ### 4. Create admin account
```bash ```bash
docker compose exec oikos node setup.js docker compose exec oikos node setup.js
``` ```
Interactive script — sets up username, display name, and password. This admin can create additional family members. Interactive script — sets up username, display name, and password. This admin can create additional family members from the settings page.
**5. Open** ### 5. Open
Navigate to `http://localhost:3000` — or your configured domain after Nginx setup. Navigate to `http://localhost:3000` — or your configured domain after Nginx setup.
> See [`nginx.conf.example`](nginx.conf.example) for a ready-to-use reverse proxy configuration. If you use [Nginx Proxy Manager](https://nginxproxymanager.com), paste the contents into the "Advanced" tab. Make sure `X-Forwarded-Proto` is set so session cookies work correctly in production. > **Nginx:** See [`nginx.conf.example`](nginx.conf.example) for a production-ready config. If you use [Nginx Proxy Manager](https://nginxproxymanager.com), paste the contents into the "Advanced" tab. Make sure `X-Forwarded-Proto` is set so session cookies work correctly in production.
---
<details> <details>
<summary><strong>📋 Configuration Reference</strong></summary> <summary><h2>Configuration</h2></summary>
### Required ### Required
@@ -216,8 +191,12 @@ Full template: [`.env.example`](.env.example)
</details> </details>
---
<details> <details>
<summary><strong>📅 Calendar Sync</strong></summary> <summary><h2>Calendar Sync</h2></summary>
Oikos syncs bidirectionally with Google Calendar and Apple iCloud. External events are visually distinguished in the UI. On conflict, the external source wins.
### Google Calendar ### Google Calendar
@@ -237,11 +216,7 @@ Full template: [`.env.example`](.env.example)
6. Restart: `docker compose up -d` 6. Restart: `docker compose up -d`
7. In Oikos: **Settings → Calendar Sync → Connect Google** 7. In Oikos: **Settings → Calendar Sync → Connect Google**
**Sync behavior:** **Sync behavior:** Initial sync pulls events from 3 months ago to 12 months ahead. Subsequent syncs use Google's `syncToken` for incremental updates. Local events push to Google automatically. Conflicts: Google wins on simultaneous edits.
- Initial sync pulls events from 3 months ago to 12 months ahead
- Subsequent syncs use Google's `syncToken` for incremental updates
- Local events push to Google automatically
- Conflicts: Google wins on simultaneous edits
### Apple Calendar (iCloud CalDAV) ### Apple Calendar (iCloud CalDAV)
@@ -259,19 +234,25 @@ The sync button appears automatically in Settings.
</details> </details>
---
## Security ## Security
- **Sessions:** `httpOnly`, `SameSite=Strict`, `Secure` in production, 7-day TTL Oikos is designed to run on a private server behind SSL. No public endpoints exist except the login page.
- **CSRF:** Double Submit Cookie pattern on all state-changing requests
- **Passwords:** bcrypt with cost factor 12 - **Sessions** — `httpOnly`, `SameSite=Strict`, `Secure` in production, 7-day TTL
- **Rate limiting:** 5 login attempts/min per IP, 300 API requests/min per IP - **CSRF** — Double-submit cookie pattern on all state-changing requests
- **Headers:** Content Security Policy via Helmet (`self`-only) - **Passwords** — bcrypt with cost factor 12
- **Encryption:** Optional SQLCipher AES-256 database encryption - **Rate limiting** — 5 login attempts/min, 300 API requests/min per IP
- **Access control:** No API endpoint accessible without session auth (except `/api/v1/auth/login`) - **Headers** — Strict Content Security Policy via Helmet (`self`-only)
- **No public registration:** Only admins can create user accounts - **Encryption** — Optional SQLCipher AES-256 database encryption at rest
- **Access control** — No API endpoint accessible without session auth (except `/api/v1/auth/login`)
- **No public registration** — Only admins can create user accounts
---
<details> <details>
<summary><strong>🛠️ Development</strong></summary> <summary><h2>Development</h2></summary>
### Local Setup ### Local Setup
@@ -315,8 +296,10 @@ public/
</details> </details>
---
<details> <details>
<summary><strong>💾 Backup & Restore</strong></summary> <summary><h2>Backup & Restore</h2></summary>
### Backup ### Backup
@@ -338,18 +321,25 @@ docker run --rm \
docker compose up -d docker compose up -d
``` ```
Database migrations run automatically on startup. Data in the `oikos_data` volume is preserved across container rebuilds.
</details> </details>
## Updates ---
<details>
<summary><h2>Updates & Family Members</h2></summary>
### Updating Oikos
```bash ```bash
git pull git pull
docker compose up -d --build docker compose up -d --build
``` ```
Database migrations run automatically on startup. Data in the `oikos_data` volume is preserved. Migrations run automatically. Your data volume stays intact.
## Family Members ### Adding Family Members
Only admins can create new accounts — there is no public registration endpoint. Only admins can create new accounts — there is no public registration endpoint.
@@ -357,12 +347,18 @@ Only admins can create new accounts — there is no public registration endpoint
**Via CLI:** `docker compose exec oikos node setup.js` **Via CLI:** `docker compose exec oikos node setup.js`
</details>
---
## Contributing ## Contributing
Contributions are welcome. If you find a bug or have a feature idea, [open an issue](https://github.com/ulsklyc/oikos/issues). Pull requests are appreciated — please keep the vanilla JS constraint in mind (no frameworks, no build tools). Contributions are welcome. If you find a bug or have a feature idea, [open an issue](https://github.com/ulsklyc/oikos/issues). Pull requests are appreciated — please keep the vanilla JS constraint in mind (no frameworks, no build tools).
A `CONTRIBUTING.md` with detailed guidelines is coming soon. A `CONTRIBUTING.md` with detailed guidelines is coming soon.
---
## License ## License
[MIT](LICENSE) © 2025 ulsklyc [MIT](LICENSE) © 2025 ulsklyc