17 KiB
Quick Install
Three ways to get Oikos running from scratch:
Option A — Web Installer (recommended, all platforms)
git clone https://github.com/ulsklyc/oikos.git && cd oikos
node tools/installer/install-server.js
# Open http://localhost:8090
Requires Node.js 18+ on the host. The browser-based wizard configures your .env, starts Docker, and creates your admin account. Docker still runs the app itself.
Option B — CLI Installer (Linux / macOS)
git clone https://github.com/ulsklyc/oikos.git && cd oikos
bash install.sh
The script checks prerequisites, generates security keys, configures optional integrations, starts Docker, and creates your admin account.
Non-interactive mode (CI/provisioning — provide your own .env):
bash install.sh --env-file /path/to/.env
Option C — Manual (Docker only, no clone required)
curl -O https://raw.githubusercontent.com/ulsklyc/oikos/main/docker-compose.yml
curl -O https://raw.githubusercontent.com/ulsklyc/oikos/main/.env.example
cp .env.example .env # set SESSION_SECRET and DB_ENCRYPTION_KEY
docker compose up -d
docker compose exec oikos node setup.js
Installation Guide
Complete setup instructions for Oikos - from Docker installation to your first login.
Table of Contents
- Architecture Overview
- Prerequisites
- Step-by-Step Installation
- Environment Variables
- HTTPS / Reverse Proxy (Nginx)
- Updates
- Backup & Restore
- Troubleshooting
- Uninstall
Architecture Overview
Oikos is a self-hosted family planner that runs as a single Docker container. The Express.js backend serves both the API and the static frontend files. All data is stored in a SQLCipher-encrypted SQLite database inside a Docker volume.
Browser ──HTTP──▶ Docker Container (Express.js :3000) ──▶ SQLite/SQLCipher (/data/oikos.db)
With HTTPS (recommended for network access):
Browser ──HTTPS──▶ Nginx (Reverse Proxy) ──HTTP──▶ Docker Container (Express.js :3000) ──▶ SQLite/SQLCipher
For local-only access, the Docker container is all you need. If you want to access Oikos from other devices on your network or the internet, add Nginx as a reverse proxy with SSL.
Prerequisites
Docker & Docker Compose
Docker packages your application and all its dependencies into a container, so you don't need to install Node.js, SQLCipher, or anything else on your host system. Docker Compose orchestrates the container using a simple configuration file.
Install Docker for your platform:
- Linux: docs.docker.com/engine/install
- macOS: docs.docker.com/desktop/install/mac-install
- Windows: docs.docker.com/desktop/install/windows-install
Verify your installation:
docker --version # Docker version 27.x.x or later
docker compose version # Docker Compose version v2.x.x
Git
You need Git to clone the repository and pull updates later.
- All platforms: git-scm.com/downloads
git --version # git version 2.x.x
System Requirements
- RAM: 256 MB minimum (the container is lightweight)
- Disk: ~500 MB for the Docker image, plus space for your database
Step-by-Step Installation
There are three ways to get Oikos running. Option A (web installer) is recommended for most users — it walks you through every step in your browser. Option B (pre-built image) is a quick manual alternative. Option C (build from source) is for contributors or custom builds.
Option A — Web Installer (Recommended)
Requires Node.js 18+ and Docker on the host.
1. Clone the Repository
git clone https://github.com/ulsklyc/oikos.git
cd oikos
2. Start the Installer
node tools/installer/install-server.js
3. Open the Wizard
Open your browser and navigate to http://localhost:8090. The wizard guides you through:
- Basic configuration (host, port, timezone)
- Security key generation
- Optional integrations (weather, Google Calendar, Apple CalDAV)
- Writing your
.envfile - Starting the Docker container
- Creating your admin account
The installer server shuts down automatically after setup completes (or after 30 minutes of inactivity).
Option B — Pre-built Image
A ready-to-use Docker image is published to the GitHub Container Registry on every release. You only need two files.
1. Download the Compose File and Example Config
curl -O https://raw.githubusercontent.com/ulsklyc/oikos/main/docker-compose.yml
curl -O https://raw.githubusercontent.com/ulsklyc/oikos/main/.env.example
2. Configure Environment Variables
cp .env.example .env
Open .env and set at minimum the two required secrets:
SESSION_SECRET=<YOUR-SECRET>
DB_ENCRYPTION_KEY=<YOUR-SECRET>
Generate a secure value for each:
openssl rand -hex 32
Run this command twice and paste each result. See Environment Variables for all options.
3. Start the Container
docker compose up -d
Docker pulls ghcr.io/ulsklyc/oikos:latest automatically. No build step, no Node.js installation needed.
Continue with Step 4 — Verify.
Option C — Build from Source
1. Clone the Repository
git clone https://github.com/ulsklyc/oikos.git
cd oikos
2. Configure Environment Variables
cp .env.example .env
Open .env and set the two required secrets (see above). Generate them with openssl rand -hex 32.
3. Build and Start the Container
docker compose up -d --build
--buildcompiles the Docker image locally (SQLCipher dependencies, npm packages).-druns the container in the background.
The first build takes a few minutes. Subsequent starts are much faster.
4. Verify the Container is Running
Check the logs to confirm a successful start:
docker compose logs -f
You should see output like:
oikos | [Oikos] Server läuft auf Port 3000
oikos | [Oikos] Umgebung: production
oikos | [Sync] Auto-Sync alle 15 Minuten aktiv.
Press Ctrl+C to stop following the logs (the container keeps running).
5. Run the Initial Setup
Create the first admin account:
docker compose exec oikos node setup.js
The interactive setup asks you for:
- Username (minimum 3 characters)
- Display name (e.g. "Jane Doe")
- Password (minimum 8 characters, entered with masked input)
6. Open Oikos
Open your browser and navigate to:
http://localhost:3000
Log in with the admin credentials you just created. You can add family members from the Settings page.
Environment Variables
All configuration happens in the .env file. The container reads these values on startup.
Server
| Variable | Description | Default | Required |
|---|---|---|---|
PORT |
Port the Express server listens on | 3000 |
No |
NODE_ENV |
Runtime environment | production |
No |
Security
| Variable | Description | Default | Required |
|---|---|---|---|
SESSION_SECRET |
Secret key for signing session cookies. Change this! | - | Yes |
SESSION_SECURE |
Set to false if accessing without HTTPS (e.g. direct localhost). Set in docker-compose.yml by default. |
true |
No |
RATE_LIMIT_WINDOW_MS |
Time window for rate limiting (ms) | 60000 |
No |
RATE_LIMIT_MAX_ATTEMPTS |
Max login attempts per window | 5 |
No |
RATE_LIMIT_BLOCK_DURATION_MS |
Block duration after exceeding limit (ms) | 900000 |
No |
Generate a secure SESSION_SECRET:
openssl rand -hex 32
Database
| Variable | Description | Default | Required |
|---|---|---|---|
DB_PATH |
Path to the SQLite database file inside the container | /data/oikos.db |
No |
DB_ENCRYPTION_KEY |
Encryption key for SQLCipher AES-256. Change this! | - | Yes |
Generate a secure DB_ENCRYPTION_KEY:
openssl rand -hex 32
Warning
: If you lose this key, you cannot access your database. Keep a backup of your
.envfile in a safe place.
Weather (Optional)
| Variable | Description | Default | Required |
|---|---|---|---|
OPENWEATHER_API_KEY |
API key from openweathermap.org | - | No |
OPENWEATHER_CITY |
City name for weather display | Berlin |
No |
OPENWEATHER_UNITS |
Unit system (metric or imperial) |
metric |
No |
OPENWEATHER_LANG |
Language for weather descriptions | de |
No |
Google Calendar Sync (Optional)
| Variable | Description | Default | Required |
|---|---|---|---|
GOOGLE_CLIENT_ID |
OAuth 2.0 Client ID from Google Cloud Console | - | No |
GOOGLE_CLIENT_SECRET |
OAuth 2.0 Client Secret | - | No |
GOOGLE_REDIRECT_URI |
OAuth callback URL | https://<YOUR-DOMAIN>/api/v1/calendar/google/callback |
No |
Apple Calendar Sync (Optional)
| Variable | Description | Default | Required |
|---|---|---|---|
APPLE_CALDAV_URL |
CalDAV server URL | https://caldav.icloud.com |
No |
APPLE_USERNAME |
Apple ID email | - | No |
APPLE_APP_SPECIFIC_PASSWORD |
App-specific password (generate at appleid.apple.com) | - | No |
Sync
| Variable | Description | Default | Required |
|---|---|---|---|
SYNC_INTERVAL_MINUTES |
Calendar sync interval in minutes | 15 |
No |
HTTPS / Reverse Proxy (Nginx)
Optional for local access, required for network/internet access. If you only access Oikos on the same machine (localhost), you can skip this section.
When exposing Oikos to your local network or the internet, you need HTTPS for security. Nginx acts as a reverse proxy that handles SSL termination and forwards requests to the Docker container.
Install Nginx
On Debian/Ubuntu:
sudo apt install nginx
Configure Nginx
Oikos ships with an example configuration. Copy it to Nginx:
sudo cp nginx.conf.example /etc/nginx/sites-available/oikos
sudo ln -s /etc/nginx/sites-available/oikos /etc/nginx/sites-enabled/
Edit the file and replace deine-domain.de with your actual domain:
sudo nano /etc/nginx/sites-available/oikos
The configuration includes:
- HTTP-to-HTTPS redirect
- Proxy pass to the Docker container on port 3000
- WebSocket upgrade headers (for connection upgrades)
- Security headers (HSTS, X-Frame-Options, etc.)
- Static asset caching
Enable HTTPS with Let's Encrypt
Install Certbot and obtain a free SSL certificate:
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d <YOUR-DOMAIN>
Certbot automatically modifies the Nginx configuration to include your certificates.
Verify auto-renewal is active:
sudo certbot renew --dry-run
Update Oikos for HTTPS
When using HTTPS through a reverse proxy, remove or comment out the SESSION_SECURE=false line in docker-compose.yml:
environment:
- NODE_ENV=production
- DB_PATH=/data/oikos.db
# - SESSION_SECURE=false # Remove this for HTTPS
Then restart the container:
docker compose up -d
Updates
Option B — Pre-built Image
Pull the latest published image and restart:
docker compose pull
docker compose up -d
No rebuild needed. The database volume persists across updates.
Option C — Build from Source
cd oikos
git pull
docker compose up -d --build
When to Stop First
If the CHANGELOG mentions database migrations or breaking changes, stop the container before updating:
# Option B (pre-built)
docker compose pull
docker compose down
docker compose up -d
# Option C (build from source)
docker compose down
git pull
docker compose up -d --build
Recommendation: Read the CHANGELOG before every update. Back up your database beforehand (see next section).
Backup & Restore
Where is the Data?
The SQLite database lives in a Docker named volume called oikos_data, mounted at /data inside the container. The database file is /data/oikos.db.
Backup
Use the built-in backup helper to create a consistent SQLite backup from the running container, then copy it to your host:
docker compose exec oikos node -e "import('./server/db.js').then(async db => { await db.backupToFile('/data/oikos-backup.db'); process.exit(0); })"
docker cp oikos:/data/oikos-backup.db ./oikos-backup-$(date +%Y%m%d).db
Admins can also download a backup from Settings → Backup Management.
Restore
Admins can restore a backup from Settings → Backup Management. For operational restores via Docker Compose, stop the running app, mount the backup into a temporary container that uses the same Docker volume, and run the restore helper:
docker compose stop oikos
docker compose run --rm -v "$PWD/oikos-backup-20260401.db:/tmp/oikos-restore.db:ro" --entrypoint node oikos scripts/restore-backup.js /tmp/oikos-restore.db
docker compose up -d
For a local CLI restore outside Docker, set the same environment variables used by the app and run:
DB_PATH=/path/to/oikos.db node --import dotenv/config scripts/restore-backup.js ./oikos-backup-20260401.db
The restore helper validates that the file is an Oikos database before replacing the active database. It also keeps a pre-restore copy next to the database file for emergency rollback.
Automated Backups
Add a cron job to back up daily (adjust the path to your preference):
crontab -e
Add this line:
0 3 * * * docker compose exec -T oikos node -e "import('./server/db.js').then(async db => { await db.backupToFile('/data/oikos-cron-backup.db'); process.exit(0); })" && docker cp oikos:/data/oikos-cron-backup.db /path/to/backups/oikos-$(date +\%Y\%m\%d).db
This creates a backup at 3:00 AM every day.
Troubleshooting
Port already in use
If port 3000 is already occupied by another application:
lsof -i :3000
Either stop the conflicting process, or change the port in your .env file and docker-compose.yml:
ports:
- "0.0.0.0:8080:3000"
Permission denied (Docker)
If Docker commands fail with "permission denied":
sudo usermod -aG docker $USER
Log out and back in (or reboot) for the group change to take effect.
Container starts but page is not reachable
-
Check the container status:
docker compose psThe state should show "Up" and "healthy".
-
Check the logs for errors:
docker compose logs -
Verify the port mapping:
docker port oikos -
Check your firewall rules if accessing from another device.
Database encryption error
If the logs show SQLCipher errors, the DB_ENCRYPTION_KEY in your .env file is either missing or does not match the key used when the database was created.
If this is a fresh install, delete the volume and start over:
docker compose down -v
docker compose up -d --build
If you have existing data, you need the original encryption key. There is no way to recover data without it.
SQLCipher build fails during Docker build
Tip
: If you hit build issues, switch to the pre-built image (Option B above) — it ships with SQLCipher already compiled and requires no local build step.
The Dockerfile installs these build dependencies: python3, make, g++, libsqlcipher-dev. If the build fails, ensure your Docker installation is up to date and has internet access to pull packages.
On resource-constrained systems, the native compilation may run out of memory. Ensure at least 1 GB of RAM is available during the build.
Nginx 502 Bad Gateway
This means Nginx cannot reach the Docker container. Check:
-
Is the container running?
docker compose ps -
Is the
proxy_passport in your Nginx config correct? It should match the host port indocker-compose.yml(default:3000). -
Is the container listening on the expected port?
docker compose logs | grep "Server läuft"
Uninstall
Remove the container, volumes, and all data:
docker compose down -v
Remove the repository:
cd .. && rm -rf oikos
Warning
:
docker compose down -vpermanently deletes all data including the database. Create a backup first if needed.