Files
oikos/docs/installation.md
T
2026-04-29 14:04:04 -03:00

17 KiB

Quick Install

Three ways to get Oikos running from scratch:

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

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:

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.

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.


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 .env file
  • 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
  • --build compiles the Docker image locally (SQLCipher dependencies, npm packages).
  • -d runs 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 .env file 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
  1. Check the container status:

    docker compose ps
    

    The state should show "Up" and "healthy".

  2. Check the logs for errors:

    docker compose logs
    
  3. Verify the port mapping:

    docker port oikos
    
  4. 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:

  1. Is the container running?

    docker compose ps
    
  2. Is the proxy_pass port in your Nginx config correct? It should match the host port in docker-compose.yml (default: 3000).

  3. 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 -v permanently deletes all data including the database. Create a backup first if needed.