| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- services:
- qdrant:
- image: qdrant/qdrant:latest
- container_name: modulos-qdrant
- ports:
- - "6333:6333"
- - "6334:6334"
- volumes:
- - ./qdrant_storage:/qdrant/storage
- restart: unless-stopped
- healthcheck:
- test:
- [
- "CMD-SHELL",
- "if command -v curl >/dev/null 2>&1; then curl -fsS http://localhost:6333/readyz >/dev/null; \
- elif command -v wget >/dev/null 2>&1; then wget -qO- http://localhost:6333/readyz >/dev/null; \
- else bash -lc \"exec 3<>/dev/tcp/127.0.0.1/6333; printf 'GET /readyz HTTP/1.0\\r\\n\\r\\n' >&3; head -n1 <&3 | grep -q '200'\"; fi"
- ]
- interval: 20s
- timeout: 5s
- retries: 5
- backend:
- build: ./backend
- container_name: modulos-backend
- ports:
- - "2281:8000"
- command: >
- bash -lc '
- set -euo pipefail;
- exec uvicorn app:app --host 0.0.0.0 --port 8000
- '
- user: "10001:10001" # run as appuser at runtime
- environment:
- # point to your Windows Ollama box
- - OLLAMA_URL=http://192.168.8.73:11434
- # talk to qdrant inside this compose
- - QDRANT_URL=http://qdrant:6333
- # defaults for collection/models (override if you like)
- - QDRANT_COLLECTION=planning_docs
- - EMBED_MODEL=nomic-embed-text
- - CHAT_MODEL=llama3.1:8b-instruct-q5_K_M
- #- CHAT_MODEL=llama3.1:8b
- # optional CORS, comma-separated list
- - CORS_ORIGINS=http://localhost:3000,http://192.168.8.69:2380,https://llm.modulos.com.au,https://api.modulos.com.au,https://tasplanning.report
- # Optional demo gate:
- - DEMO_REQUIRE_TOKEN=0
- - DEMO_TOKEN=DHv2xUx7vWzGg3O8UihDbUVQ7Svrub1FJXHv2Y3jyOTRrOTO19cLytm3b8Y8A6eC
- - TPR_DB=/data/telemetry.db
- - TPR_IP_SECRET=${TPR_IP_SECRET:-mmOwQgqljUs1CPiKW3O9vvL4XGalAHojOEmB7SJLBxXBPXHbBoDCMyS8fPc62aDk}
- depends_on:
- qdrant:
- condition: service_healthy
- volumes:
- - ./backend:/app
- - /home/modulos_llm/telemetry_data:/data
- restart: unless-stopped
- healthcheck:
- test: ["CMD", "curl", "-f", "http://localhost:8000/readyz"]
- interval: 20s
- timeout: 3s
- retries: 5
- web:
- build:
- context: .
- dockerfile: ./web/Dockerfile
- container_name: modulos-web
- ports:
- - "2380:80"
- volumes:
- - ./public:/var/www/html
- - cache:/var/www/html/cache
- - /home/modulos_llm/telemetry_data:/data
- environment:
- - TPR_DB=/data/telemetry.db
- - DEBIAN_FRONTEND=noninteractive
- - GOOGLE_APPLICATION_CREDENTIALS=/var/www/secure/service-account.json
- - GDOC_PARENT_ID=1Zkv6eThu-3szvRpug3fXiAuTDWLsWxxl
- - GDOC_SHARE_EMAIL=modulos.aust@gmail.com
- - GMAPS_API_KEY=${GMAPS_API_KEY}
- - SMTP_HOST=mail.modulos.com.au
- - SMTP_PORT=465
- - SMTP_USER=no-reply@modulos.com.au
- - SMTP_PASS=${SMTP_PASS}
- - SMTP_FROM=no-reply@modulos.com.au
- - SMTP_FROM_NAME=Tas Planning Assistant
- - NOTIFY_EMAIL=ben@modulos.com.au
- - APP_API_BASE=https://api.modulos.com.au/ask
- - CORS_ORIGINS=${CORS_ORIGINS:-https://tasplanning.report,https://modulosdesign.com.au,https://llm.modulos.com.au}
- - APP_ENV=${APP_ENV:-production}
- depends_on:
- - backend
- restart: unless-stopped
- command: >
- bash -lc '
- set -euo pipefail;
- apt-get update -y;
- apt-get install -y --no-install-recommends git unzip libzip-dev netcat-openbsd;
- rm -rf /var/lib/apt/lists/*;
- a2enmod rewrite headers >/dev/null || true;
- # Only build zip if not loaded
- php -m | grep -qi "^zip$" || docker-php-ext-install zip;
- # Write clean confs (printf avoids YAML here-doc pitfalls)
- printf "%s\n" "<Directory \"/var/www/html\">" \
- " AllowOverride All" \
- " Require all granted" \
- "</Directory>" \
- > /etc/apache2/conf-enabled/allowoverride.conf
- printf "%s\n" "SetEnvIfNoCase X-Forwarded-Proto ^https$ HTTPS=on" \
- > /etc/apache2/conf-enabled/proxy-https.conf
- # Extra: set HTTPS via mod_rewrite for libs reading env later
- printf "%s\n" "RewriteEngine On" \
- "RewriteCond %{HTTP:X-Forwarded-Proto} =https" \
- "RewriteRule .* - [E=HTTPS:on]" \
- > /etc/apache2/conf-enabled/rewrite-https.conf
- printf "ServerName localhost\n" > /etc/apache2/conf-enabled/servername.conf
- printf "PassEnv GMAPS_API_KEY\nPassEnv CORS_ORIGINS\nPassEnv APP_ENV\n" > /etc/apache2/conf-enabled/passenv.conf;
- chown -R www-data:www-data /var/www/html/cache || true;
- apachectl -t;
- exec apache2-foreground
- '
- sqliteweb:
- image: coleifer/sqlite-web:latest
- container_name: modulos-sqliteweb
- depends_on:
- - backend
- user: "10001:10001"
- volumes:
- - /home/modulos_llm/telemetry_data:/data # same volume the backend uses
- # external: true
- environment:
- - SQLITE_DATABASE=telemetry.db # looks for /data/telemetry.db
- # optional: protect with a password
- # - SQLITE_WEB_PASSWORD=${SQLITE_WEB_PASSWORD:-}
- ports:
- - "8091:8080"
- restart: unless-stopped
- composer:
- build:
- context: .
- dockerfile: ./web/Dockerfile
- working_dir: /app
- volumes:
- - ./public:/app
- # external: true
- command: ["composer", "install", "--no-interaction", "--no-progress", "--prefer-dist"]
- restart: unless-stopped
- depends_on:
- - web
- volumes:
- cache:
- external: true
- name: modulos_llm_cache
- telemetry_data: {}
|