learning_ai_common_plat/docker-compose.ecosystem.yml
Saravana Kumar c0db29014b fix(infra): bind caddy to public eth0 IP only
Caddy was binding 0.0.0.0:443, which prevented tailscaled from claiming
100.87.53.10:443 for `tailscale serve --https=443`. Restricting Caddy to
the public eth0 IP (187.124.159.82) keeps the public api.bytelyst.com /
devops.bytelyst.com routing intact while freeing the Tailscale IP so the
tailnet-only dashboard URL (https://srv1491630.tailf85608.ts.net) is
reachable again.

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-05-30 16:37:09 +00:00

1054 lines
30 KiB
YAML

# docker-compose.ecosystem.yml — Full ByteLyst Ecosystem
#
# Brings up all infrastructure, platform services, dashboards, and product
# backends + web apps in a single Docker Compose stack.
#
# Prerequisites:
# 1. Copy .env.ecosystem.example → .env.ecosystem and fill in values
# 2. All product repos must be sibling directories of this repo
#
# Usage:
# GITEA_NPM_TOKEN=<token> docker compose -f docker-compose.ecosystem.yml --env-file .env.ecosystem up --build
#
# The GITEA_NPM_TOKEN env var is required for product Docker builds that install
# @bytelyst/* packages from the local Gitea npm registry via BuildKit secrets.
#
# Port Map:
# Infrastructure: cosmos-emulator 8081, azurite 10000, mailpit 1025/8025,
# loki 3100, grafana 3000, traefik 80/8080
# Phase 2 (opt-in): prometheus 9090, valkey 6379
# Platform: platform-service 4003, extraction-service 4005, mcp-server 4007
# Dashboards: admin-web 3001, tracker-web 3003
# Products: peakpulse 4010, chronomind 4011, jarvisjr 4012,
# nomgap 4013, mindlyst 4014, lysnrai 4015,
# notelett 4016, flowmonk 4017, actiontrail 4018,
# localmemgpt 4019, efforise 4020
# Product webs: chronomind 3030, jarvisjr 3035, flowmonk 3040,
# notelett 3045, mindlyst 3050, nomgap on Vercel,
# actiontrail 3060, localmemgpt 3070, lysnrai 3002,
# efforise 3080
# Product Dockerfiles require BuildKit secrets for Gitea npm registry access.
# GITEA_NPM_HOST defaults to host.docker.internal (Mac local dev).
x-product-build: &product-build
args:
GITEA_NPM_HOST: ${GITEA_NPM_HOST:-host.docker.internal}
secrets:
- gitea_npm_token
secrets:
gitea_npm_token:
environment: GITEA_NPM_TOKEN
services:
# ═════════════════════════════════════════════════════════════════
# INFRASTRUCTURE
# ═════════════════════════════════════════════════════════════════
cosmos-emulator:
image: mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator:vnext-preview
ports:
- '127.0.0.1:8081:8081'
- '127.0.0.1:1234:1234'
environment:
- PROTOCOL=http
- ENABLE_EXPLORER=true
- GATEWAY_PUBLIC_ENDPOINT=cosmos-emulator
healthcheck:
test: ['CMD-SHELL', 'curl -sf http://127.0.0.1:8080/ready || exit 1']
interval: 10s
timeout: 5s
retries: 12
start_period: 20s
restart: unless-stopped
deploy:
resources:
limits:
memory: 1g
azurite:
image: mcr.microsoft.com/azure-storage/azurite:3.35.0
command: azurite-blob --blobHost 0.0.0.0 --blobPort 10000 --location /data --skipApiVersionCheck
ports:
- '127.0.0.1:10000:10000'
volumes:
- azurite-data:/data
healthcheck:
test: ['CMD', 'nc', '-z', '127.0.0.1', '10000']
interval: 10s
timeout: 5s
retries: 6
restart: unless-stopped
deploy:
resources:
limits:
memory: 256m
mailpit:
image: axllent/mailpit:v1.27.5
ports:
- '127.0.0.1:1025:1025'
- '127.0.0.1:8025:8025'
healthcheck:
test: ['CMD', 'wget', '-q', '--spider', 'http://127.0.0.1:8025']
interval: 10s
timeout: 5s
retries: 6
restart: unless-stopped
deploy:
resources:
limits:
memory: 128m
loki:
image: grafana/loki:3.3.2
ports:
- '127.0.0.1:3100:3100'
volumes:
- ./services/monitoring/loki/loki-config.yml:/etc/loki/local-config.yaml
- loki-data:/loki
command: -config.file=/etc/loki/local-config.yaml
healthcheck:
test: ['CMD', 'wget', '-q', '--spider', 'http://127.0.0.1:3100/ready']
interval: 15s
timeout: 5s
retries: 3
restart: unless-stopped
deploy:
resources:
limits:
memory: 384m
grafana:
image: grafana/grafana:11.4.0
ports:
- '127.0.0.1:3000:3000'
environment:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=bytelyst
- GF_USERS_ALLOW_SIGN_UP=false
volumes:
- ./services/monitoring/grafana/provisioning:/etc/grafana/provisioning
- ./services/monitoring/grafana/dashboards:/var/lib/grafana/dashboards
- grafana-data:/var/lib/grafana
depends_on:
loki:
condition: service_started
healthcheck:
test: ['CMD', 'wget', '-q', '--spider', 'http://127.0.0.1:3000/api/health']
interval: 15s
timeout: 5s
retries: 3
restart: unless-stopped
deploy:
resources:
limits:
memory: 384m
prometheus:
image: prom/prometheus:v3.5.0
profiles:
- phase2-observability
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.enable-lifecycle'
volumes:
- ./services/monitoring/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
- prometheus-data:/prometheus
depends_on:
node-exporter:
condition: service_started
cadvisor:
condition: service_started
healthcheck:
test: ['CMD', 'wget', '-q', '--spider', 'http://127.0.0.1:9090/-/healthy']
interval: 15s
timeout: 5s
retries: 3
restart: unless-stopped
deploy:
resources:
limits:
memory: 384m
node-exporter:
image: prom/node-exporter:v1.9.1
profiles:
- phase2-observability
command:
- '--path.rootfs=/host'
- '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($|/)'
volumes:
- /:/host:ro,rslave
healthcheck:
test: ['CMD', 'wget', '-q', '--spider', 'http://127.0.0.1:9100/metrics']
interval: 15s
timeout: 5s
retries: 3
restart: unless-stopped
deploy:
resources:
limits:
memory: 128m
cadvisor:
image: gcr.io/cadvisor/cadvisor:v0.49.1
profiles:
- phase2-observability
privileged: true
command:
- '--housekeeping_interval=30s'
- '--docker_only=true'
volumes:
- /:/rootfs:ro
- /var/run:/var/run:rw
- /sys:/sys:ro
- /var/lib/docker:/var/lib/docker:ro
- /dev/disk:/dev/disk:ro
healthcheck:
test: ['CMD', 'wget', '-q', '--spider', 'http://127.0.0.1:8080/healthz']
interval: 15s
timeout: 5s
retries: 3
restart: unless-stopped
deploy:
resources:
limits:
memory: 256m
valkey:
image: valkey/valkey:8-alpine
profiles:
- phase2-shared
command:
- valkey-server
- --save
- '60'
- '1'
- --loglevel
- warning
volumes:
- valkey-data:/data
healthcheck:
test: ['CMD', 'valkey-cli', 'ping']
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
deploy:
resources:
limits:
memory: 128m
gateway:
image: traefik:v3.3
profiles:
- legacy-gateway
command:
- '--api.insecure=true'
- '--providers.docker=true'
- '--providers.docker.exposedbydefault=false'
- '--entrypoints.web.address=:80'
- '--accesslog=true'
- '--accesslog.format=json'
ports:
- '80:80'
- '127.0.0.1:8080:8080'
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
depends_on:
loki:
condition: service_started
restart: unless-stopped
deploy:
resources:
limits:
memory: 128m
caddy:
image: caddy:2-alpine
container_name: caddy
ports:
# Bind to public eth0 IP only (not 0.0.0.0) so tailscaled can claim
# 100.87.53.10:443 for `tailscale serve` on the tailnet.
- '187.124.159.82:80:80'
- '187.124.159.82:443:443'
volumes:
- ../Caddyfile:/etc/caddy/Caddyfile:ro
- caddy-data:/data
- caddy-config:/config
depends_on:
platform-service:
condition: service_healthy
extraction-service:
condition: service_healthy
mcp-server:
condition: service_healthy
restart: unless-stopped
deploy:
resources:
limits:
memory: 256m
# ═════════════════════════════════════════════════════════════════
# PLATFORM SERVICES (from this repo)
# ═════════════════════════════════════════════════════════════════
platform-service:
build:
context: .
dockerfile: services/platform-service/Dockerfile
env_file:
- .env.ecosystem
environment:
- PORT=4003
- COSMOS_AUTO_INIT=true
- PLATFORM_SERVICE_URL=http://platform-service:4003
- EXTRACTION_SERVICE_URL=http://extraction-service:4005
- MCP_SERVER_URL=http://mcp-server:4007
- MAILPIT_UI_URL=http://mailpit:8025
depends_on:
mailpit:
condition: service_healthy
azurite:
condition: service_healthy
cosmos-emulator:
condition: service_healthy
labels:
- 'traefik.enable=true'
- 'traefik.http.routers.platform.rule=PathPrefix(`/platform`)'
- 'traefik.http.services.platform.loadbalancer.server.port=4003'
healthcheck:
test: ['CMD', 'wget', '-q', '--spider', 'http://127.0.0.1:4003/health']
interval: 30s
timeout: 10s
retries: 3
restart: unless-stopped
deploy:
resources:
limits:
memory: 512m
extraction-service:
build:
context: .
dockerfile: services/extraction-service/Dockerfile
env_file:
- .env.ecosystem
environment:
- PORT=4005
- PYTHON_SIDECAR_URL=http://localhost:4006
- PRODUCT_RATE_LIMIT_STORE=${PRODUCT_RATE_LIMIT_STORE:-valkey}
- VALKEY_URL=${VALKEY_URL:-redis://valkey:6379}
depends_on:
cosmos-emulator:
condition: service_healthy
labels:
- 'traefik.enable=true'
- 'traefik.http.routers.extraction.rule=PathPrefix(`/extraction`)'
- 'traefik.http.services.extraction.loadbalancer.server.port=4005'
healthcheck:
test: ['CMD', 'wget', '-q', '--spider', 'http://127.0.0.1:4005/health']
interval: 30s
timeout: 10s
retries: 3
restart: unless-stopped
deploy:
resources:
limits:
memory: 512m
mcp-server:
build:
context: .
dockerfile: services/mcp-server/Dockerfile
env_file:
- .env.ecosystem
environment:
- PORT=4007
- PLATFORM_SERVICE_URL=http://platform-service:4003
- EXTRACTION_SERVICE_URL=http://extraction-service:4005
depends_on:
platform-service:
condition: service_healthy
extraction-service:
condition: service_healthy
labels:
- 'traefik.enable=true'
- 'traefik.http.routers.mcp.rule=PathPrefix(`/mcp`)'
- 'traefik.http.services.mcp.loadbalancer.server.port=4007'
healthcheck:
test: ['CMD', 'wget', '-q', '--spider', 'http://127.0.0.1:4007/health']
interval: 30s
timeout: 10s
retries: 3
restart: unless-stopped
deploy:
resources:
limits:
memory: 384m
# ═════════════════════════════════════════════════════════════════
# PLATFORM DASHBOARDS (from this repo)
# ═════════════════════════════════════════════════════════════════
admin-web:
build:
context: .
dockerfile: dashboards/admin-web/Dockerfile
ports:
- '127.0.0.1:3001:3001'
env_file:
- .env.ecosystem
environment:
- PORT=3001
- PLATFORM_SERVICE_URL=http://platform-service:4003
- EXTRACTION_SERVICE_URL=http://extraction-service:4005
- SEED_SECRET=${SEED_SECRET:-dev-seed-secret}
volumes:
- /var/run/docker.sock:/var/run/docker.sock
depends_on:
platform-service:
condition: service_healthy
healthcheck:
test: ['CMD', 'wget', '-q', '--spider', 'http://127.0.0.1:3001']
interval: 30s
timeout: 10s
retries: 3
restart: unless-stopped
deploy:
resources:
limits:
memory: 512m
tracker-web:
build:
context: .
dockerfile: dashboards/tracker-web/Dockerfile
ports:
- '127.0.0.1:3003:3003'
env_file:
- .env.ecosystem
environment:
- PORT=3003
- PLATFORM_SERVICE_URL=http://platform-service:4003
- PLATFORM_API_URL=http://platform-service:4003
depends_on:
platform-service:
condition: service_healthy
healthcheck:
test: ['CMD', 'wget', '-q', '--spider', 'http://127.0.0.1:3003']
interval: 30s
timeout: 10s
retries: 3
restart: unless-stopped
deploy:
resources:
limits:
memory: 512m
# ═════════════════════════════════════════════════════════════════
# PRODUCT BACKENDS (from sibling repos)
# ═════════════════════════════════════════════════════════════════
peakpulse-backend:
build:
<<: *product-build
context: ../learning_ai_peakpulse
dockerfile: backend/Dockerfile
env_file:
- .env.ecosystem
environment:
- PORT=4010
- HOST=0.0.0.0
- PLATFORM_SERVICE_URL=http://platform-service:4003
depends_on:
platform-service:
condition: service_healthy
healthcheck:
test: ['CMD', 'wget', '-q', '--spider', 'http://127.0.0.1:4010/health']
interval: 30s
timeout: 10s
retries: 3
restart: unless-stopped
deploy:
resources:
limits:
memory: 512m
chronomind-backend:
build:
<<: *product-build
context: ../learning_ai_clock
dockerfile: backend/Dockerfile
env_file:
- .env.ecosystem
environment:
- PORT=4011
- HOST=0.0.0.0
- PLATFORM_SERVICE_URL=http://platform-service:4003
depends_on:
platform-service:
condition: service_healthy
healthcheck:
test: ['CMD', 'wget', '-q', '--spider', 'http://127.0.0.1:4011/health']
interval: 30s
timeout: 10s
retries: 3
restart: unless-stopped
deploy:
resources:
limits:
memory: 512m
jarvisjr-backend:
build:
<<: *product-build
context: ../learning_ai_jarvis_jr
dockerfile: backend/Dockerfile
env_file:
- .env.ecosystem
environment:
- PORT=4012
- HOST=0.0.0.0
- PLATFORM_SERVICE_URL=http://platform-service:4003
depends_on:
platform-service:
condition: service_healthy
healthcheck:
test: ['CMD', 'wget', '-q', '--spider', 'http://127.0.0.1:4012/health']
interval: 30s
timeout: 10s
retries: 3
restart: unless-stopped
deploy:
resources:
limits:
memory: 512m
nomgap-backend:
build:
<<: *product-build
context: ../learning_ai_fastgap
dockerfile: backend/Dockerfile
env_file:
- .env.ecosystem
environment:
- PORT=4013
- HOST=0.0.0.0
- PLATFORM_SERVICE_URL=http://platform-service:4003
depends_on:
platform-service:
condition: service_healthy
healthcheck:
test: ['CMD', 'wget', '-q', '--spider', 'http://127.0.0.1:4013/health']
interval: 30s
timeout: 10s
retries: 3
restart: unless-stopped
deploy:
resources:
limits:
memory: 512m
mindlyst-backend:
build:
<<: *product-build
context: ../learning_multimodal_memory_agents
dockerfile: backend/Dockerfile
env_file:
- .env.ecosystem
environment:
- PORT=4014
- HOST=0.0.0.0
- PLATFORM_SERVICE_URL=http://platform-service:4003
depends_on:
platform-service:
condition: service_healthy
healthcheck:
test: ['CMD', 'wget', '-q', '--spider', 'http://127.0.0.1:4014/health']
interval: 30s
timeout: 10s
retries: 3
restart: unless-stopped
deploy:
resources:
limits:
memory: 512m
lysnrai-backend:
build:
<<: *product-build
context: ../learning_voice_ai_agent
dockerfile: backend/Dockerfile
env_file:
- .env.ecosystem
environment:
- PORT=4015
- HOST=0.0.0.0
- PLATFORM_SERVICE_URL=http://platform-service:4003
depends_on:
platform-service:
condition: service_healthy
healthcheck:
test: ['CMD', 'wget', '-q', '--spider', 'http://127.0.0.1:4015/health']
interval: 30s
timeout: 10s
retries: 3
restart: unless-stopped
deploy:
resources:
limits:
memory: 512m
notelett-backend:
build:
<<: *product-build
context: ../learning_ai_notes
dockerfile: backend/Dockerfile
env_file:
- .env.ecosystem
environment:
- PORT=4016
- HOST=0.0.0.0
- PLATFORM_SERVICE_URL=http://platform-service:4003
- EXTRACTION_SERVICE_URL=http://extraction-service:4005
depends_on:
platform-service:
condition: service_healthy
healthcheck:
test: ['CMD', 'wget', '-q', '--spider', 'http://127.0.0.1:4016/health']
interval: 30s
timeout: 10s
retries: 3
restart: unless-stopped
deploy:
resources:
limits:
memory: 512m
flowmonk-backend:
build:
<<: *product-build
context: ../learning_ai_flowmonk
dockerfile: backend/Dockerfile
env_file:
- .env.ecosystem
environment:
- PORT=4017
- HOST=0.0.0.0
- PLATFORM_SERVICE_URL=http://platform-service:4003
depends_on:
platform-service:
condition: service_healthy
healthcheck:
test: ['CMD', 'wget', '-q', '--spider', 'http://127.0.0.1:4017/health']
interval: 30s
timeout: 10s
retries: 3
restart: unless-stopped
deploy:
resources:
limits:
memory: 512m
actiontrail-backend:
build:
<<: *product-build
context: ../learning_ai_trails
dockerfile: backend/Dockerfile
env_file:
- .env.ecosystem
environment:
- PORT=4018
- HOST=0.0.0.0
- PLATFORM_SERVICE_URL=http://platform-service:4003
depends_on:
platform-service:
condition: service_healthy
healthcheck:
test: ['CMD', 'wget', '-q', '--spider', 'http://127.0.0.1:4018/health']
interval: 30s
timeout: 10s
retries: 3
restart: unless-stopped
deploy:
resources:
limits:
memory: 512m
localmemgpt-backend:
build:
<<: *product-build
context: ../learning_ai_local_memory_gpt
dockerfile: backend/Dockerfile
extra_hosts:
- 'host.docker.internal:host-gateway'
env_file:
- .env.ecosystem
environment:
- PORT=4019
- HOST=0.0.0.0
- OLLAMA_URL=http://host.docker.internal:11434
- PLATFORM_SERVICE_URL=http://platform-service:4003
volumes:
- localmemgpt-data:/app/db
depends_on:
platform-service:
condition: service_healthy
healthcheck:
test: ['CMD', 'wget', '-q', '--spider', 'http://127.0.0.1:4019/health']
interval: 30s
timeout: 10s
retries: 3
restart: unless-stopped
deploy:
resources:
limits:
memory: 512m
efforise-backend:
build:
<<: *product-build
context: ../learning_ai_efforise
dockerfile: backend/Dockerfile
ports:
- '127.0.0.1:4020:4020'
env_file:
- .env.ecosystem
environment:
- PORT=4020
- HOST=0.0.0.0
- PLATFORM_SERVICE_URL=http://platform-service:4003
depends_on:
platform-service:
condition: service_healthy
healthcheck:
test: ['CMD', 'wget', '-q', '--spider', 'http://127.0.0.1:4020/health']
interval: 30s
timeout: 10s
retries: 3
restart: unless-stopped
deploy:
resources:
limits:
memory: 512m
# ═════════════════════════════════════════════════════════════════
# PRODUCT WEB APPS (from sibling repos)
# ═════════════════════════════════════════════════════════════════
lysnrai-dashboard:
build:
<<: *product-build
context: ../learning_voice_ai_agent
dockerfile: user-dashboard-web/Dockerfile
args:
GITEA_NPM_HOST: ${GITEA_NPM_HOST:-host.docker.internal}
# NEXT_PUBLIC_* args are baked at build time for browser-side code
NEXT_PUBLIC_PLATFORM_SERVICE_URL: http://localhost:4003
NEXT_PUBLIC_PRODUCT_ID: lysnrai
ports:
- '127.0.0.1:3002:3002'
environment:
- NODE_ENV=production
- PORT=3002
# Non-prefixed vars are used by server-side code (API routes, SSR)
- PLATFORM_SERVICE_URL=http://platform-service:4003
- ACTIONTRAIL_SERVICE_URL=http://actiontrail-backend:4018
depends_on:
lysnrai-backend:
condition: service_healthy
healthcheck:
test: ['CMD', 'wget', '-q', '--spider', 'http://127.0.0.1:3002']
interval: 30s
timeout: 10s
retries: 3
restart: unless-stopped
deploy:
resources:
limits:
memory: 512m
chronomind-web:
build:
<<: *product-build
context: ../learning_ai_clock
dockerfile: web/Dockerfile
args:
GITEA_NPM_HOST: ${GITEA_NPM_HOST:-host.docker.internal}
NEXT_PUBLIC_BACKEND_URL: http://localhost:4011
NEXT_PUBLIC_PLATFORM_SERVICE_URL: http://localhost:4003
ports:
- '127.0.0.1:3030:3030'
environment:
- NODE_ENV=production
- PORT=3030
- BACKEND_URL=http://chronomind-backend:4011
- PLATFORM_SERVICE_URL=http://platform-service:4003
depends_on:
chronomind-backend:
condition: service_healthy
healthcheck:
test: ['CMD', 'wget', '-q', '--spider', 'http://127.0.0.1:3030']
interval: 30s
timeout: 10s
retries: 3
restart: unless-stopped
deploy:
resources:
limits:
memory: 512m
jarvisjr-web:
build:
<<: *product-build
context: ../learning_ai_jarvis_jr
dockerfile: web/Dockerfile
args:
GITEA_NPM_HOST: ${GITEA_NPM_HOST:-host.docker.internal}
NEXT_PUBLIC_PLATFORM_SERVICE_URL: http://localhost:4003
ports:
- '127.0.0.1:3035:3035'
environment:
- NODE_ENV=production
- PORT=3035
- HOSTNAME=0.0.0.0
- PLATFORM_SERVICE_URL=http://platform-service:4003
depends_on:
jarvisjr-backend:
condition: service_healthy
healthcheck:
test: ['CMD', 'wget', '-q', '--spider', 'http://127.0.0.1:3035']
interval: 30s
timeout: 10s
retries: 3
restart: unless-stopped
deploy:
resources:
limits:
memory: 512m
flowmonk-web:
build:
<<: *product-build
context: ../learning_ai_flowmonk
dockerfile: web/Dockerfile
args:
GITEA_NPM_HOST: ${GITEA_NPM_HOST:-host.docker.internal}
NEXT_PUBLIC_API_URL: http://localhost:4017
NEXT_PUBLIC_PLATFORM_URL: http://localhost:4003/api
ports:
- '127.0.0.1:3040:3040'
environment:
- NODE_ENV=production
- PORT=3040
- HOSTNAME=0.0.0.0
- API_URL=http://flowmonk-backend:4017
- PLATFORM_URL=http://platform-service:4003/api
depends_on:
flowmonk-backend:
condition: service_healthy
healthcheck:
test: ['CMD', 'wget', '-q', '--spider', 'http://127.0.0.1:3040']
interval: 30s
timeout: 10s
retries: 3
restart: unless-stopped
deploy:
resources:
limits:
memory: 512m
notelett-web:
build:
<<: *product-build
context: ../learning_ai_notes
dockerfile: web/Dockerfile
args:
GITEA_NPM_HOST: ${GITEA_NPM_HOST:-host.docker.internal}
NEXT_PUBLIC_NOTES_API_URL: http://localhost:4016/api
NEXT_PUBLIC_PLATFORM_SERVICE_URL: http://localhost:4003/api
ports:
- '127.0.0.1:3045:3045'
environment:
- NODE_ENV=production
- PORT=3045
- NOTES_API_URL=http://notelett-backend:4016/api
- PLATFORM_SERVICE_URL=http://platform-service:4003/api
depends_on:
notelett-backend:
condition: service_healthy
healthcheck:
test: ['CMD', 'wget', '-q', '--spider', 'http://127.0.0.1:3045']
interval: 30s
timeout: 10s
retries: 3
restart: unless-stopped
deploy:
resources:
limits:
memory: 512m
mindlyst-web:
build:
<<: *product-build
context: ../learning_multimodal_memory_agents
dockerfile: mindlyst-native/web/Dockerfile
args:
GITEA_NPM_HOST: ${GITEA_NPM_HOST:-host.docker.internal}
NEXT_PUBLIC_PLATFORM_SERVICE_URL: http://localhost:4003
ports:
- '127.0.0.1:3050:3050'
environment:
- NODE_ENV=production
- PORT=3050
- HOSTNAME=0.0.0.0
- PLATFORM_SERVICE_URL=http://platform-service:4003
depends_on:
mindlyst-backend:
condition: service_healthy
healthcheck:
test: ['CMD', 'wget', '-q', '--spider', 'http://127.0.0.1:3050']
interval: 30s
timeout: 10s
retries: 3
restart: unless-stopped
deploy:
resources:
limits:
memory: 512m
# TODO(nomgap): Decide whether local Docker smoke tests still need a web
# service once the Vercel deployment path is fully documented.
# nomgap-web: deployed to Vercel; not part of this Docker stack.
actiontrail-web:
build:
<<: *product-build
context: ../learning_ai_trails
dockerfile: web/Dockerfile
args:
GITEA_NPM_HOST: ${GITEA_NPM_HOST:-host.docker.internal}
NEXT_PUBLIC_API_URL: http://localhost:4018
NEXT_PUBLIC_PLATFORM_URL: http://localhost:4003
ports:
- '127.0.0.1:3060:3060'
environment:
- NODE_ENV=production
- PORT=3060
- HOSTNAME=0.0.0.0
- API_URL=http://actiontrail-backend:4018
- PLATFORM_URL=http://platform-service:4003
depends_on:
actiontrail-backend:
condition: service_healthy
healthcheck:
test: ['CMD', 'wget', '-q', '--spider', 'http://127.0.0.1:3060']
interval: 30s
timeout: 10s
retries: 3
restart: unless-stopped
deploy:
resources:
limits:
memory: 512m
localmemgpt-web:
build:
<<: *product-build
context: ../learning_ai_local_memory_gpt
dockerfile: web/Dockerfile
args:
GITEA_NPM_HOST: ${GITEA_NPM_HOST:-host.docker.internal}
NEXT_PUBLIC_BACKEND_URL: http://localhost:4019
NEXT_PUBLIC_PLATFORM_URL: http://localhost:4003
ports:
- '127.0.0.1:3070:3070'
environment:
- NODE_ENV=production
- PORT=3070
- HOSTNAME=0.0.0.0
- BACKEND_URL=http://localmemgpt-backend:4019
- PLATFORM_URL=http://platform-service:4003
depends_on:
localmemgpt-backend:
condition: service_healthy
healthcheck:
test: ['CMD', 'wget', '-q', '--spider', 'http://127.0.0.1:3070']
interval: 30s
timeout: 10s
retries: 3
restart: unless-stopped
deploy:
resources:
limits:
memory: 512m
efforise-web:
build:
<<: *product-build
context: ../learning_ai_efforise
dockerfile: client/Dockerfile
ports:
- '127.0.0.1:3080:3080'
depends_on:
efforise-backend:
condition: service_healthy
healthcheck:
test: ['CMD', 'wget', '-q', '--spider', 'http://127.0.0.1:3080']
interval: 30s
timeout: 10s
retries: 3
restart: unless-stopped
deploy:
resources:
limits:
memory: 512m
# ── Local LLM Lab (no backend — dashboard talks directly to Ollama) ──
llmlab-dashboard:
build:
<<: *product-build
context: ../learning_ai_local_llms
dockerfile: dashboard/Dockerfile
args:
GITEA_NPM_HOST: ${GITEA_NPM_HOST:-host.docker.internal}
OLLAMA_URL: http://host.docker.internal:11434
ports:
- '127.0.0.1:3075:3075'
environment:
- NODE_ENV=production
- PORT=3075
- HOSTNAME=0.0.0.0
- OLLAMA_URL=http://host.docker.internal:11434
- OLLAMA_HOST=http://host.docker.internal:11434
extra_hosts:
- 'host.docker.internal:host-gateway'
healthcheck:
test: ['CMD', 'wget', '-q', '--spider', 'http://127.0.0.1:3075']
interval: 15s
timeout: 5s
retries: 3
restart: unless-stopped
deploy:
resources:
limits:
memory: 512m
# ═════════════════════════════════════════════════════════════════
# VOLUMES
# ═════════════════════════════════════════════════════════════════
volumes:
azurite-data:
loki-data:
grafana-data:
prometheus-data:
valkey-data:
localmemgpt-data:
caddy-data:
caddy-config: