Files
stack/plans/mosaic-installer-plan.md
Jason Woltje af299abdaf
All checks were successful
ci/woodpecker/push/infra Pipeline was successful
ci/woodpecker/push/orchestrator Pipeline was successful
ci/woodpecker/push/api Pipeline was successful
ci/woodpecker/push/web Pipeline was successful
debug(auth): log session cookie source
2026-02-18 21:36:01 -06:00

21 KiB

Mosaic Stack Comprehensive Installer Plan

Executive Summary

This document outlines the plan for creating a comprehensive installation script for Mosaic Stack that "just works" across platforms, automatically installs all dependencies, detects the platform, and configures the system. The design is inspired by the OpenClaw installer pattern while addressing Mosaic Stack's unique requirements as a multi-tenant personal assistant platform with optional Docker deployment.


1. Current State Analysis

1.1 Existing Setup Script (scripts/setup.sh)

Strengths:

  • Interactive configuration wizard
  • Platform detection (Debian, Arch, Fedora, macOS)
  • Docker and native deployment modes
  • Port conflict detection and resolution
  • .env file management with value preservation
  • Secret generation
  • SSO/Authentik configuration
  • Ollama integration options
  • Traefik reverse proxy support

Gaps:

  • No curl-able one-liner installation
  • Missing automatic dependency installation for some platforms
  • No WSL detection/handling
  • No dry-run validation of full configuration
  • Limited post-install validation
  • No upgrade/migration path handling
  • Missing verbose/debug mode
  • No cleanup on failure
  • PATH management not comprehensive

1.2 OpenClaw Installer Features to Adopt

Feature Description Priority
curl-able one-liner curl -fsSL URL | bash pattern High
Color output Consistent colored output with ACCENT/SUCCESS/WARN/ERROR High
Platform detection macOS, Linux, WSL detection High
Auto Homebrew Automatic Homebrew installation on macOS Medium
Node.js management NodeSource integration for Linux, Homebrew for macOS High
npm permissions fix User-local npm global installs on Linux Medium
pnpm via corepack Corepack-first pnpm installation High
Git installation Automatic Git installation Medium
Multiple install methods npm vs git checkout options Low
Dry-run mode Preview changes without execution High
Verbose mode Debug output with set -x Medium
Non-interactive mode CI/CD friendly automation High
TTY detection Graceful handling of piped input High
Temp file cleanup Trap-based cleanup on exit High
Downloader detection curl/wget abstraction Medium
PATH warnings Alert user about PATH issues Medium
Post-install doctor Validation and migration High
Fun taglines User-friendly messaging Low

2. Proposed Architecture

2.1 File Structure

scripts/
├── install.sh              # Main entry point (curl-able)
├── setup.sh                # Interactive configuration wizard (enhanced)
├── lib/
│   ├── common.sh           # Shared utilities (enhanced)
│   ├── platform.sh         # Platform detection functions
│   ├── dependencies.sh     # Dependency installation functions
│   ├── docker.sh           # Docker-specific functions
│   ├── native.sh           # Native deployment functions
│   └── validation.sh       # Post-install validation
└── commands/
    ├── doctor.sh           # Diagnostic and repair tool
    └── upgrade.sh          # Upgrade/migration handler

2.2 Installer Flow Diagram

flowchart TD
    A[curl/install.sh] --> B{Parse Arguments}
    B --> C{Help?}
    C -->|Yes| D[Show Usage]
    C -->|No| E{Dry Run?}

    E --> F[Detect Platform]
    F --> G[Detect Package Manager]

    G --> H{Install Method}
    H -->|docker| I[Check Docker]
    H -->|native| J[Check Node.js/pnpm]

    I --> K{Docker OK?}
    K -->|No| L[Install Docker]
    K -->|Yes| M[Check Docker Compose]
    L --> M

    J --> N{Node.js OK?}
    N -->|No| O[Install Node.js]
    N -->|Yes| P{pnpm OK?}
    O --> P
    P -->|No| Q[Install pnpm]
    P -->|Yes| R[Check PostgreSQL]
    Q --> R

    M --> S[Check Existing Config]
    R --> S

    S --> T{Has .env?}
    T -->|Yes| U[Load Existing Values]
    T -->|No| V[Interactive Config]
    U --> V

    V --> W[Generate Secrets]
    W --> X[Resolve Port Conflicts]
    X --> Y[Write .env]

    Y --> Z{Deployment Mode}
    Z -->|docker| AA[Docker Compose Up]
    Z -->|native| AB[Run Migrations]

    AA --> AC[Run Doctor]
    AB --> AC

    AC --> AD{All Checks Pass?}
    AD -->|Yes| AE[Show Success]
    AD -->|No| AF[Show Warnings]

    AE --> AG[Print Next Steps]
    AF --> AG

3. Detailed Component Design

3.1 Entry Point: install.sh

The main installer should support both quick-start and advanced usage:

# Usage patterns:
# Quick start (interactive):
curl -fsSL https://get.mosaicstack.dev | bash

# Non-interactive Docker deployment:
curl -fsSL https://get.mosaicstack.dev | bash -s -- --non-interactive --mode docker

# Dry run to preview:
curl -fsSL https://get.mosaicstack.dev | bash -s -- --dry-run --mode docker

# With all options:
curl -fsSL https://get.mosaicstack.dev | bash -s -- \
  --mode docker \
  --enable-sso \
  --bundled-authentik \
  --ollama-mode local \
  --base-url https://mosaic.example.com

Command-line Options:

Option Description Default
--mode Deployment mode: docker, native interactive
--non-interactive Skip all prompts false
--dry-run Preview without changes false
--verbose Enable debug output false
--enable-sso Enable Authentik SSO false
--bundled-authentik Use bundled Authentik false
--external-authentik URL External Authentik URL -
--ollama-mode Ollama: local, remote, disabled disabled
--ollama-url URL Remote Ollama URL -
--base-url URL Mosaic base URL http://localhost:3000
--profiles Compose profiles to enable full
--no-port-check Skip port conflict detection false
--skip-deps Skip dependency installation false
--help Show usage -

3.2 Platform Detection: lib/platform.sh

# Functions to implement:

detect_os()           # Returns: macos, debian, arch, fedora, linux, unknown
detect_package_manager()  # Returns: brew, apt, pacman, dnf, unknown
detect_wsl()          # Returns: WSL_DISTRO_NAME or empty
detect_init_system()  # Returns: systemd, openrc, launchd, unknown
get_os_name()         # Human-readable OS name
get_arch()            # Returns: x86_64, aarch64, armv7l
is_root()             # Check if running as root
maybe_sudo()          # Run with sudo only if needed

Platform Support Matrix:

Platform Package Manager Init System Node.js Source
macOS Homebrew launchd Homebrew
Ubuntu/Debian apt systemd NodeSource
Arch/Manjaro pacman systemd pacman
Fedora/RHEL dnf systemd NodeSource
WSL (host-dependent) systemd* (host-dependent)

3.3 Dependency Management: lib/dependencies.sh

Dependencies by Mode:

Docker Mode:

  • Docker Engine 24+
  • Docker Compose (plugin or standalone)
  • Git (for cloning if needed)

Native Mode:

  • Node.js 22+
  • pnpm 10+
  • PostgreSQL 17+ (with pgvector)
  • Valkey/Redis (optional)
  • Git

Optional Dependencies:

  • Ollama (for local LLM)
  • OpenSSL (for secret generation)

Installation Strategy:

# macOS
install_homebrew()      # Auto-install Homebrew if missing
install_docker_macos()  # via Homebrew
install_node_macos()    # via Homebrew
install_pnpm()          # via corepack or npm

# Debian/Ubuntu
install_docker_debian() # via docker.com apt repo
install_node_debian()   # via NodeSource
install_postgres_debian() # via apt with pgvector

# Arch Linux
install_docker_arch()   # via pacman
install_node_arch()     # via pacman
install_postgres_arch() # via pacman with pgvector

# Fedora/RHEL
install_docker_fedora() # via dnf
install_node_fedora()   # via NodeSource
install_postgres_fedora() # via dnf

3.4 Docker Functions: lib/docker.sh

check_docker()           # Verify Docker is installed and accessible
check_docker_compose()   # Verify Docker Compose is available
check_docker_buildx()    # Verify buildx is available
fix_docker_permissions() # Add user to docker group
start_docker()           # Start Docker daemon if not running
docker_pull_images()     # Pre-pull all required images
docker_compose_up()      # Start services with health checks
docker_compose_down()    # Stop services
docker_logs()            # Tail logs for debugging

3.5 Configuration Generation

Environment File Structure:

The installer should generate a complete .env file based on:

  1. Existing values (if .env exists)
  2. Command-line arguments
  3. Interactive prompts (if TTY available)
  4. Auto-detected defaults

Secret Generation:

Secret Length Method
POSTGRES_PASSWORD 32 openssl rand -base64
JWT_SECRET 32 openssl rand -base64
BETTER_AUTH_SECRET 32 openssl rand -base64
ENCRYPTION_KEY 32 openssl rand -hex 32
AUTHENTIK_SECRET_KEY 50 openssl rand -base64
AUTHENTIK_BOOTSTRAP_PASSWORD 16 openssl rand -base64
COORDINATOR_API_KEY 32 openssl rand -base64
ORCHESTRATOR_API_KEY 32 openssl rand -base64
GITEA_WEBHOOK_SECRET 32 openssl rand -hex 32

URL Derivation:

# Localhost mode
MOSAIC_BASE_URL=http://localhost:${WEB_PORT}
NEXT_PUBLIC_API_URL=http://localhost:${API_PORT}

# Domain mode (with Traefik)
MOSAIC_BASE_URL=https://${MOSAIC_WEB_DOMAIN}
NEXT_PUBLIC_API_URL=https://${MOSAIC_API_DOMAIN}

# IP mode (local network)
MOSAIC_BASE_URL=http://${LOCAL_IP}:${WEB_PORT}
NEXT_PUBLIC_API_URL=http://${LOCAL_IP}:${API_PORT}

3.6 Port Conflict Resolution

# Default ports
declare -A DEFAULT_PORTS=(
    [WEB_PORT]=3000
    [API_PORT]=3001
    [POSTGRES_PORT]=5432
    [VALKEY_PORT]=6379
    [AUTHENTIK_PORT_HTTP]=9000
    [AUTHENTIK_PORT_HTTPS]=9443
    [OLLAMA_PORT]=11434
    [TRAEFIK_HTTP_PORT]=80
    [TRAEFIK_HTTPS_PORT]=443
    [TRAEFIK_DASHBOARD_PORT]=8080
)

# Check if port is in use
check_port_in_use() {
    local port=$1
    # Try ss first, fall back to netstat, then lsof
}

# Suggest alternative port
suggest_alternative_port() {
    local base_port=$1
    # Try base_port+1, base_port+100, etc.
}

3.7 Post-Install Validation: lib/validation.sh

Doctor Checks:

# Docker mode checks
doctor_docker_running()      # Docker daemon is running
doctor_containers_healthy()  # All containers are healthy
doctor_database_connected()  # PostgreSQL is accessible
doctor_cache_connected()     # Valkey is accessible
doctor_api_responding()      # API health check passes
doctor_web_responding()      # Web frontend is accessible

# Native mode checks
doctor_node_version()        # Node.js version is sufficient
doctor_pnpm_version()        # pnpm is installed
doctor_postgres_running()    # PostgreSQL is running
doctor_migrations_applied()  # Database migrations are up to date
doctor_dependencies_installed()  # node_modules is complete

# General checks
doctor_env_complete()        # All required env vars are set
doctor_secrets_valid()       # Secrets are not placeholders
doctor_ports_available()     # Configured ports are available
doctor_disk_space()          # Sufficient disk space

3.8 Doctor Command: scripts/commands/doctor.sh

A standalone diagnostic tool that can be run after installation:

# Usage
./scripts/commands/doctor.sh              # Run all checks
./scripts/commands/doctor.sh --fix        # Attempt automatic fixes
./scripts/commands/doctor.sh --verbose    # Detailed output
./scripts/commands/doctor.sh --json       # JSON output for CI

# Exit codes
# 0: All checks passed
# 1: Some checks failed
# 2: Critical failure

4. User Experience Design

4.1 Banner and Branding

  __  __                 _       ____ _             _
 |  \/  | ___  ___  __ _(_) ___ / ___| |_ __ _  ___| | __
 | |\/| |/ _ \/ __|/ _` | |/ __|\___ | __/ _` |/ __| |/ /
 | |  | | (_) \__ \ (_| | | (__ ___/ | || (_| | (__|   <
 |_|  |_|\___/|___/\__,_|_|\___|____/ \__\__,_|\___|_|\_\

  Multi-Tenant Personal Assistant Platform

  Claws out, configs in — let's ship a calm, clean stack.

4.2 Progress Indicators

✓ Detected: macOS (brew)
✓ Docker: OK (version 27.0.0)
✓ Docker Compose: OK (version 2.28.0)
✓ Node.js: OK (v22.5.0)
⚠ Port 3000 is in use, using 3001
→ Generating secrets...
→ Writing .env file...
→ Starting services...
✓ All services healthy

4.3 Error Messages

✗ Docker is not running
  Start with: open -a Docker (macOS)
  Start with: sudo systemctl start docker (Linux)

✗ Port conflicts detected:
  - Web UI (3000): In use by process 12345 (node)
  - API (3001): In use by process 12346 (python)
  Run with --auto-ports to use alternative ports

4.4 Success Message

════════════════════════════════════════════════════════════
  Mosaic Stack is ready!
════════════════════════════════════════════════════════════

  Web UI:     http://localhost:3000
  API:        http://localhost:3001
  Database:   localhost:5432

  Next steps:
    1. Open http://localhost:3000 in your browser
    2. Create your first workspace
    3. Configure AI providers in Settings

  To stop:    docker compose down
  To restart: docker compose restart
  To view logs: docker compose logs -f

  Documentation: https://docs.mosaicstack.dev
  Support:       https://github.com/mosaicstack/stack/issues

5. Implementation Phases

Phase 1: Core Infrastructure

  • Create install.sh entry point with argument parsing
  • Implement platform detection in lib/platform.sh
  • Create dependency checking functions
  • Add temp file cleanup and error handling
  • Implement colored output system

Phase 2: Dependency Installation

  • Implement Homebrew auto-installation for macOS
  • Implement Docker installation for all platforms
  • Implement Node.js installation via NodeSource (Debian/Fedora)
  • Implement pnpm installation via corepack
  • Implement PostgreSQL installation with pgvector

Phase 3: Configuration

  • Enhance .env file generation
  • Implement secret generation with proper entropy
  • Add URL derivation logic for all access modes
  • Implement port conflict detection and resolution
  • Add configuration validation

Phase 4: Service Management

  • Implement Docker Compose service orchestration
  • Add health check polling
  • Implement database migration running
  • Add service status reporting

Phase 5: Validation and Doctor

  • Create scripts/commands/doctor.sh
  • Implement all diagnostic checks
  • Add automatic fix capabilities
  • Create JSON output mode for CI

Phase 6: Polish and Testing

  • Add comprehensive logging
  • Test on all supported platforms
  • Test upgrade scenarios
  • Write documentation
  • Create CI/CD integration examples

6. Testing Strategy

6.1 Platform Testing Matrix

Platform Version Docker Native CI
macOS 14 (Sonoma) Manual
macOS 13 (Ventura) Manual
Ubuntu 24.04 LTS GitHub Actions
Ubuntu 22.04 LTS GitHub Actions
Debian 12 (Bookworm) GitHub Actions
Arch Rolling Manual
Fedora 40 Manual
WSL2 Ubuntu Manual

6.2 Test Scenarios

  1. Fresh Installation

    • No dependencies installed
    • Clean system
  2. Partial Dependencies

    • Some dependencies already installed
    • Different versions
  3. Upgrade Scenario

    • Existing .env file
    • Running containers
  4. Port Conflicts

    • Common ports in use
    • All ports in use
  5. Error Recovery

    • Network failures
    • Permission issues
    • Disk space issues

7. Security Considerations

7.1 Secret Handling

  • Never log secrets to console or file
  • Generate secrets with cryptographically secure random
  • Validate secrets are not placeholders before starting
  • Warn if default/weak secrets are detected

7.2 Network Security

  • Download scripts over HTTPS only
  • Verify TLS certificates
  • Use specific version tags for Docker images
  • Pin NodeSource repository version

7.3 File Permissions

  • Set restrictive permissions on .env (600)
  • Ensure secrets are not world-readable
  • Validate file ownership

8. Documentation Requirements

8.1 README Updates

  • Add installation section with curl command
  • Document all command-line options
  • Add troubleshooting section
  • Include platform-specific notes

8.2 Inline Documentation

  • Comment all functions with usage examples
  • Document expected return values
  • Include error codes

8.3 User Guide

  • Step-by-step installation guide
  • Configuration options explained
  • Common issues and solutions
  • Upgrade procedures

9. Open Questions

  1. Should we support Windows native installation?

    • Current recommendation: WSL2 only
    • PowerShell version could be a future addition
  2. Should we support ARM platforms (Raspberry Pi)?

    • Docker images would need ARM builds
    • Could be community-supported
  3. What is the upgrade strategy?

    • In-place upgrade vs. migrate data
    • Database migration handling
    • Configuration file changes
  4. Should we provide an uninstaller?

    • Clean up Docker volumes
    • Remove configuration files
    • Uninstall dependencies (optional)

10. Success Criteria

The installer is considered successful when:

  1. A user can run curl -fsSL https://get.mosaicstack.dev | bash and have a working installation
  2. All dependencies are automatically installed on supported platforms
  3. Port conflicts are automatically detected and resolved
  4. Secrets are automatically generated with proper entropy
  5. The installation completes in under 5 minutes on a fresh system
  6. Post-install validation confirms all services are healthy
  7. Clear next steps are provided to the user
  8. Non-interactive mode works for CI/CD pipelines
  9. The doctor command can diagnose and fix common issues
  10. Upgrade from previous versions preserves data and configuration

Appendix A: Environment Variables Reference

See .env.example for the complete list of configuration options.

Appendix B: Docker Compose Profiles

Profile Services Use Case
full All services Development/Trial
database PostgreSQL External cache/auth
cache Valkey External database
authentik Authentik SSO enabled
ollama Ollama Local LLM
traefik-bundled Traefik Reverse proxy
openbao OpenBao Secrets management