diff --git a/.env.example b/.env.example index 28ef7a74..411830b0 100644 --- a/.env.example +++ b/.env.example @@ -93,8 +93,3 @@ # - No source bind mounts — code is baked into the image # - Set TIMMY_ENV=production to enforce security checks # - All secrets below MUST be set before production deployment -# -# Taskosaur secrets (change from dev defaults): -# TASKOSAUR_JWT_SECRET= -# TASKOSAUR_JWT_REFRESH_SECRET= -# TASKOSAUR_ENCRYPTION_KEY= diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 5c92fe4a..6f1a81c5 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -14,7 +14,6 @@ # # Security note: Set all secrets in .env before deploying. # Required: L402_HMAC_SECRET, L402_MACAROON_SECRET -# Recommended: TASKOSAUR_JWT_SECRET, TASKOSAUR_ENCRYPTION_KEY services: diff --git a/docker-compose.yml b/docker-compose.yml index f4106281..0b62d266 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,20 +2,17 @@ # # Services # dashboard FastAPI app (always on) -# taskosaur Taskosaur PM + AI task execution -# postgres PostgreSQL 16 (for Taskosaur) -# redis Redis 7 (for Taskosaur queues) +# celery-worker (behind 'celery' profile) +# openfang (behind 'openfang' profile) # # Usage # make docker-build build the image -# make docker-up start dashboard + taskosaur +# make docker-up start dashboard # make docker-down stop everything # make docker-logs tail logs # -# ── Security note: root user in dev ───────────────────────────────────────── -# This dev compose runs containers as root (user: "0:0") so that -# bind-mounted host files (./src, ./static) are readable regardless of -# host UID/GID — the #1 cause of 403 errors on macOS. +# ── Security note ───────────────────────────────────────────────────────── +# Override user per-environment — see docker-compose.dev.yml / docker-compose.prod.yml # # ── Ollama host access ────────────────────────────────────────────────────── # By default OLLAMA_URL points to http://host.docker.internal:11434 which @@ -31,7 +28,7 @@ services: build: . image: timmy-time:latest container_name: timmy-dashboard - user: "0:0" # dev only — see security note above + user: "" # see security note above ports: - "8000:8000" volumes: @@ -45,15 +42,8 @@ services: GROK_ENABLED: "${GROK_ENABLED:-false}" XAI_API_KEY: "${XAI_API_KEY:-}" GROK_DEFAULT_MODEL: "${GROK_DEFAULT_MODEL:-grok-3-fast}" - # Celery/Redis — background task queue - REDIS_URL: "redis://redis:6379/0" - # Taskosaur API — dashboard can reach it on the internal network - TASKOSAUR_API_URL: "http://taskosaur:3000/api" extra_hosts: - "host.docker.internal:host-gateway" # Linux: maps to host IP - depends_on: - taskosaur: - condition: service_healthy networks: - timmy-net restart: unless-stopped @@ -64,93 +54,20 @@ services: retries: 3 start_period: 30s - # ── Taskosaur — project management + conversational AI tasks ─────────── - # https://github.com/Taskosaur/Taskosaur - taskosaur: - image: ghcr.io/taskosaur/taskosaur:latest - container_name: taskosaur - ports: - - "3000:3000" # Backend API + Swagger docs at /api/docs - - "3001:3001" # Frontend UI - environment: - DATABASE_URL: "postgresql://taskosaur:taskosaur@postgres:5432/taskosaur" - REDIS_HOST: "redis" - REDIS_PORT: "6379" - JWT_SECRET: "${TASKOSAUR_JWT_SECRET:-dev-jwt-secret-change-in-prod}" - JWT_REFRESH_SECRET: "${TASKOSAUR_JWT_REFRESH_SECRET:-dev-refresh-secret-change-in-prod}" - ENCRYPTION_KEY: "${TASKOSAUR_ENCRYPTION_KEY:-dev-encryption-key-change-in-prod}" - FRONTEND_URL: "http://localhost:3001" - NEXT_PUBLIC_API_BASE_URL: "http://localhost:3000/api" - NODE_ENV: "development" - depends_on: - postgres: - condition: service_healthy - redis: - condition: service_healthy - networks: - - timmy-net - restart: unless-stopped - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:3000/api/health"] - interval: 30s - timeout: 5s - retries: 5 - start_period: 60s - - # ── PostgreSQL — Taskosaur database ──────────────────────────────────── - postgres: - image: postgres:16-alpine - container_name: taskosaur-postgres - environment: - POSTGRES_USER: taskosaur - POSTGRES_PASSWORD: taskosaur - POSTGRES_DB: taskosaur - volumes: - - postgres-data:/var/lib/postgresql/data - networks: - - timmy-net - restart: unless-stopped - healthcheck: - test: ["CMD-SHELL", "pg_isready -U taskosaur"] - interval: 10s - timeout: 5s - retries: 5 - start_period: 10s - - # ── Redis — Taskosaur queue backend ──────────────────────────────────── - redis: - image: redis:7-alpine - container_name: taskosaur-redis - volumes: - - redis-data:/data - networks: - - timmy-net - restart: unless-stopped - healthcheck: - test: ["CMD", "redis-cli", "ping"] - interval: 10s - timeout: 5s - retries: 5 - start_period: 5s - # ── Celery Worker — background task processing ────────────────────────── celery-worker: build: . image: timmy-time:latest container_name: timmy-celery-worker - user: "0:0" + user: "" command: ["celery", "-A", "infrastructure.celery.app", "worker", "--loglevel=info", "--concurrency=2"] volumes: - timmy-data:/app/data - ./src:/app/src environment: - REDIS_URL: "redis://redis:6379/0" OLLAMA_URL: "${OLLAMA_URL:-http://host.docker.internal:11434}" extra_hosts: - "host.docker.internal:host-gateway" - depends_on: - redis: - condition: service_healthy networks: - timmy-net restart: unless-stopped @@ -193,10 +110,6 @@ volumes: device: "${PWD}/data" openfang-data: driver: local - postgres-data: - driver: local - redis-data: - driver: local # ── Internal network ──────────────────────────────────────────────────────── networks: