Tribu
Self-hosted family organizer for calendar, tasks, shopping, and more
Alternative to: cozi, familywall, ourhome
Tribu is a self-hosted family organizer that brings calendar, tasks, shopping lists, contacts, birthdays, routines, meals, and rewards into one shared home base. It syncs calendars and contacts to phones over CalDAV and CardDAV, offers a read-only Shared Home Display for a kitchen tablet or wall screen, and connects to Home Assistant and webhooks for automations.
Tribu Docker Compose example
Self-host Tribu on your own server, homelab, or VPS starting from this Docker Compose example.
It runs Tribu in Docker containers using the official postgres:16-alpine, valkey/valkey:8-alpine, ghcr.io/itsdnns/tribu-backend:latest, ghcr.io/itsdnns/tribu-frontend:latest images, with persistent volumes and automatic restarts preconfigured.
Review the environment variables and adjust them to your setup, save the file as compose.yml (or docker-compose.yml), and start the stack with docker compose up -d.
services:
postgres:
image: postgres:16-alpine
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -U tribu -d tribu"]
interval: 10s
timeout: 5s
retries: 5
environment:
POSTGRES_DB: "tribu"
POSTGRES_USER: "tribu"
# Password for the internal PostgreSQL database.
POSTGRES_PASSWORD: "changeme"
volumes:
- tribu_pg_data:/var/lib/postgresql/data
valkey:
image: valkey/valkey:8-alpine
restart: unless-stopped
healthcheck:
test: ["CMD", "valkey-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
backend:
image: ghcr.io/itsdnns/tribu-backend:latest
restart: unless-stopped
environment:
# PostgreSQL connection string (user:password@host:port/db).
DATABASE_URL: "postgresql://tribu:changeme@postgres:5432/tribu"
REDIS_URL: "redis://valkey:6379/0"
# Secret used to sign JWT auth tokens. Use a random 64-character hex string.
JWT_SECRET: "changeme"
# Set to true when serving over HTTPS so session cookies are marked Secure.
SECURE_COOKIES: "false"
# Public URL of this instance, e.g. https://tribu.example.com. Used for absolute links and web push.
BASE_URL: ""
# VAPID public key for web push notifications (optional).
VAPID_PUBLIC_KEY: ""
# VAPID private key for web push notifications (optional).
VAPID_PRIVATE_KEY: ""
# Contact email registered with the push service, e.g. mailto:admin@example.com (optional).
VAPID_CLAIMS_EMAIL: ""
# Lifetime of an access token, in hours.
JWT_EXPIRE_HOURS: "24"
# Lifetime of a refresh token, in days.
REFRESH_TOKEN_EXPIRE_DAYS: "30"
# IANA timezone for calendar and task times.
TZ: "UTC"
# Comma-separated list of extra browser origins allowed to call the API (optional).
CORS_ALLOWED_ORIGINS: ""
# Allow browser origins on private LAN ranges.
CORS_ALLOW_LAN_ORIGINS: "false"
# Comma-separated trusted reverse-proxy CIDRs, for correct client IPs (optional).
TRUSTED_PROXY_CIDRS: ""
# Allow calendar/contact subscription URLs that point at private networks.
SUBSCRIPTIONS_ALLOW_PRIVATE_NETWORKS: "false"
# Allow anyone to register an account without an invite.
ALLOW_OPEN_REGISTRATION: "false"
# One-time token that authorizes restoring a backup during setup (optional).
SETUP_RESTORE_TOKEN: ""
# Maximum size, in bytes, of a backup archive accepted during restore.
SETUP_RESTORE_MAX_BYTES: "104857600"
depends_on:
postgres:
condition: service_healthy
valkey:
condition: service_healthy
expose:
- "8000"
healthcheck:
test:
- CMD-SHELL
- >-
python -c "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8000/health', timeout=3).read()"
interval: 10s
timeout: 5s
retries: 12
start_period: 20s
volumes:
- tribu_backups:/backups
frontend:
image: ghcr.io/itsdnns/tribu-frontend:latest
restart: unless-stopped
environment:
# Internal URL of the backend API, reached over the Docker network.
BACKEND_URL: "http://backend:8000"
depends_on:
backend:
condition: service_healthy
volumes:
tribu_pg_data:
tribu_backups:
Values set to changeme are required — replace them with your own
values before starting Tribu.
Prefer a managed setup? WinterFlow installs, configures, and updates Tribu for you using this same Docker Compose configuration.