Initial commit
Some checks failed
CI/CD Pipeline / Code Quality & Linting (push) Has been cancelled
CI/CD Pipeline / Policy Validation (push) Has been cancelled
CI/CD Pipeline / Test Suite (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-coverage) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-extract) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-firm-connectors) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-forms) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-hmrc) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-ingestion) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-kg) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-normalize-map) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-ocr) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-rag-indexer) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-rag-retriever) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-reason) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-rpa) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (ui-review) (push) Has been cancelled
CI/CD Pipeline / Security Scanning (svc-coverage) (push) Has been cancelled
CI/CD Pipeline / Security Scanning (svc-extract) (push) Has been cancelled
CI/CD Pipeline / Security Scanning (svc-kg) (push) Has been cancelled
CI/CD Pipeline / Security Scanning (svc-rag-retriever) (push) Has been cancelled
CI/CD Pipeline / Security Scanning (ui-review) (push) Has been cancelled
CI/CD Pipeline / Generate SBOM (push) Has been cancelled
CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
CI/CD Pipeline / Deploy to Production (push) Has been cancelled
CI/CD Pipeline / Notifications (push) Has been cancelled

This commit is contained in:
harkon
2025-10-11 08:41:36 +01:00
commit b324ff09ef
276 changed files with 55220 additions and 0 deletions

View File

@@ -0,0 +1,228 @@
# FILE: infra/base/infrastructure.yaml
# Infrastructure Services for AI Tax Agent
# Environment-agnostic - use with environment-specific .env files
# Deploy with: ./infra/scripts/deploy.sh <environment> infrastructure
networks:
frontend:
external: true
name: frontend
backend:
external: true
name: backend
volumes:
postgres_data:
neo4j_data:
neo4j_logs:
qdrant_data:
minio_data:
vault_data:
redis_data:
nats_data:
services:
# Secrets Management
vault:
image: hashicorp/vault:1.15
container_name: vault
restart: unless-stopped
networks:
- backend
- frontend
volumes:
- vault_data:/vault/data
environment:
VAULT_DEV_ROOT_TOKEN_ID: ${VAULT_DEV_ROOT_TOKEN_ID}
VAULT_DEV_LISTEN_ADDRESS: 0.0.0.0:8200
command: vault server -dev -dev-listen-address=0.0.0.0:8200
cap_add:
- IPC_LOCK
labels:
- "traefik.enable=true"
- "traefik.http.routers.vault.rule=Host(`vault.${DOMAIN}`)"
- "traefik.http.routers.vault.entrypoints=websecure"
- "traefik.http.routers.vault.tls=true"
- "traefik.http.routers.vault.tls.certresolver=godaddy"
- "traefik.http.routers.vault.middlewares=authentik-forwardauth@file"
- "traefik.http.services.vault.loadbalancer.server.port=8200"
# Object Storage
minio:
image: minio/minio:RELEASE.2025-09-07T16-13-09Z
container_name: minio
restart: unless-stopped
networks:
- backend
- frontend
volumes:
- minio_data:/data
environment:
MINIO_ROOT_USER: ${MINIO_ROOT_USER}
MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD}
MINIO_BROWSER_REDIRECT_URL: https://minio.${DOMAIN}
command: server /data --address ":9092" --console-address ":9093"
healthcheck:
test: ["CMD", "mc", "--version"]
interval: 30s
timeout: 20s
retries: 3
labels:
- "traefik.enable=true"
- "traefik.http.routers.minio-api.rule=Host(`minio-api.${DOMAIN}`)"
- "traefik.http.routers.minio-api.entrypoints=websecure"
- "traefik.http.routers.minio-api.tls=true"
- "traefik.http.routers.minio-api.tls.certresolver=godaddy"
- "traefik.http.routers.minio-api.middlewares=authentik-forwardauth@file"
- "traefik.http.routers.minio-api.service=minio-api"
- "traefik.http.services.minio-api.loadbalancer.server.port=9092"
- "traefik.http.routers.minio-console.rule=Host(`minio.${DOMAIN}`)"
- "traefik.http.routers.minio-console.entrypoints=websecure"
- "traefik.http.routers.minio-console.tls=true"
- "traefik.http.routers.minio-console.tls.certresolver=godaddy"
- "traefik.http.routers.minio-console.middlewares=authentik-forwardauth@file"
- "traefik.http.routers.minio-console.service=minio-console"
- "traefik.http.services.minio-console.loadbalancer.server.port=9093"
# Vector Database
qdrant:
image: qdrant/qdrant:v1.7.4
container_name: qdrant
restart: unless-stopped
networks:
- backend
- frontend
volumes:
- qdrant_data:/qdrant/storage
environment:
QDRANT__SERVICE__GRPC_PORT: ${QDRANT__SERVICE__GRPC_PORT:-6334}
QDRANT__SERVICE__HTTP_PORT: 6333
QDRANT__LOG_LEVEL: INFO
labels:
- "traefik.enable=true"
- "traefik.http.routers.qdrant.rule=Host(`qdrant.${DOMAIN}`)"
- "traefik.http.routers.qdrant.entrypoints=websecure"
- "traefik.http.routers.qdrant.tls=true"
- "traefik.http.routers.qdrant.tls.certresolver=godaddy"
- "traefik.http.routers.qdrant.middlewares=authentik-forwardauth@file"
- "traefik.http.services.qdrant.loadbalancer.server.port=6333"
# Knowledge Graph Database
neo4j:
image: neo4j:5.15-community
container_name: neo4j
restart: unless-stopped
networks:
- backend
- frontend
volumes:
- neo4j_data:/data
- neo4j_logs:/logs
environment:
NEO4J_AUTH: neo4j/${NEO4J_PASSWORD}
NEO4J_PLUGINS: '["apoc", "graph-data-science"]'
NEO4J_dbms_security_procedures_unrestricted: gds.*,apoc.*
NEO4J_dbms_security_procedures_allowlist: gds.*,apoc.*
NEO4J_apoc_export_file_enabled: true
NEO4J_apoc_import_file_enabled: true
NEO4J_apoc_import_file_use__neo4j__config: true
labels:
- "traefik.enable=true"
- "traefik.http.routers.neo4j.rule=Host(`neo4j.${DOMAIN}`)"
- "traefik.http.routers.neo4j.entrypoints=websecure"
- "traefik.http.routers.neo4j.tls=true"
- "traefik.http.routers.neo4j.tls.certresolver=godaddy"
- "traefik.http.routers.neo4j.middlewares=authentik-forwardauth@file"
- "traefik.http.services.neo4j.loadbalancer.server.port=7474"
# Secure Client Data Store
postgres:
image: postgres:15-alpine
container_name: postgres
restart: unless-stopped
networks:
- backend
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
POSTGRES_DB: tax_system
POSTGRES_USER: postgres
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_INITDB_ARGS: "--auth-host=scram-sha-256"
command: >
postgres
-c shared_preload_libraries=pg_stat_statements
-c pg_stat_statements.track=all
-c max_connections=200
-c shared_buffers=256MB
-c effective_cache_size=1GB
-c maintenance_work_mem=64MB
-c checkpoint_completion_target=0.9
-c wal_buffers=16MB
-c default_statistics_target=100
-c random_page_cost=1.1
-c effective_io_concurrency=200
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 30s
timeout: 10s
retries: 3
# Cache & Session Store
redis:
image: redis:7-alpine
container_name: redis
restart: unless-stopped
networks:
- backend
volumes:
- redis_data:/data
command: >
redis-server
--appendonly yes
--appendfsync everysec
--maxmemory 512mb
--maxmemory-policy allkeys-lru
healthcheck:
test: ["CMD-SHELL", "redis-cli ping | grep PONG"]
interval: 30s
timeout: 10s
retries: 3
# Message Broker & Event Streaming
nats:
image: nats:2.10-alpine
container_name: nats
restart: unless-stopped
networks:
- backend
- frontend
volumes:
- nats_data:/data
command: >
--jetstream
--store_dir=/data
--http_port=8222
environment:
NATS_LOG_LEVEL: ${NATS_LOG_LEVEL:-info}
healthcheck:
test:
[
"CMD",
"wget",
"--no-verbose",
"--tries=1",
"--spider",
"http://localhost:8222/healthz",
]
interval: 30s
timeout: 10s
retries: 3
labels:
- "traefik.enable=true"
- "traefik.http.routers.nats-monitor.rule=Host(`nats.${DOMAIN}`)"
- "traefik.http.routers.nats-monitor.entrypoints=websecure"
- "traefik.http.routers.nats-monitor.tls=true"
- "traefik.http.routers.nats-monitor.tls.certresolver=godaddy"
- "traefik.http.routers.nats-monitor.middlewares=authentik-forwardauth@file"
- "traefik.http.services.nats-monitor.loadbalancer.server.port=8222"

126
infra/base/monitoring.yaml Normal file
View File

@@ -0,0 +1,126 @@
# FILE: infra/compose/production/monitoring.yaml
# Production Monitoring Stack for AI Tax Agent
# Deploy to: /opt/compose/ai-tax-agent/monitoring.yaml
networks:
frontend:
external: true
name: frontend
backend:
external: true
name: backend
volumes:
prometheus_data:
grafana_data:
loki_data:
services:
# Metrics Collection
prometheus:
image: prom/prometheus:v2.48.1
container_name: prometheus
restart: unless-stopped
networks:
- backend
- frontend
volumes:
- prometheus_data:/prometheus
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
command:
- "--config.file=/etc/prometheus/prometheus.yml"
- "--storage.tsdb.path=/prometheus"
- "--web.console.libraries=/etc/prometheus/console_libraries"
- "--web.console.templates=/etc/prometheus/consoles"
- "--storage.tsdb.retention.time=30d"
- "--web.enable-lifecycle"
labels:
- "traefik.enable=true"
- "traefik.http.routers.prometheus.rule=Host(`prometheus.${DOMAIN}`)"
- "traefik.http.routers.prometheus.entrypoints=websecure"
- "traefik.http.routers.prometheus.tls=true"
- "traefik.http.routers.prometheus.tls.certresolver=godaddy"
- "traefik.http.routers.prometheus.middlewares=authentik-forwardauth@file"
- "traefik.http.services.prometheus.loadbalancer.server.port=9090"
# Visualization & Dashboards
grafana:
image: grafana/grafana:10.2.3
container_name: grafana
restart: unless-stopped
networks:
- backend
- frontend
volumes:
- grafana_data:/var/lib/grafana
- ./grafana/provisioning:/etc/grafana/provisioning:ro
- ./grafana/dashboards:/var/lib/grafana/dashboards:ro
environment:
GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_PASSWORD}
GF_USERS_ALLOW_SIGN_UP: false
GF_USERS_AUTO_ASSIGN_ORG: true
GF_USERS_AUTO_ASSIGN_ORG_ROLE: Viewer
GF_AUTH_GENERIC_OAUTH_ENABLED: true
GF_AUTH_GENERIC_OAUTH_NAME: Authentik
GF_AUTH_GENERIC_OAUTH_CLIENT_ID: ${GRAFANA_OAUTH_CLIENT_ID}
GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET: ${GRAFANA_OAUTH_CLIENT_SECRET}
GF_AUTH_GENERIC_OAUTH_SCOPES: openid profile email groups
GF_AUTH_GENERIC_OAUTH_AUTH_URL: https://authentik.${DOMAIN}/application/o/authorize/
GF_AUTH_GENERIC_OAUTH_TOKEN_URL: https://authentik.${DOMAIN}/application/o/token/
GF_AUTH_GENERIC_OAUTH_API_URL: https://authentik.${DOMAIN}/application/o/userinfo/
GF_AUTH_GENERIC_OAUTH_AUTO_LOGIN: false
GF_AUTH_GENERIC_OAUTH_ALLOW_SIGN_UP: true
GF_AUTH_GENERIC_OAUTH_ROLE_ATTRIBUTE_PATH: role
GF_AUTH_GENERIC_OAUTH_ROLE_ATTRIBUTE_STRICT: false
GF_AUTH_GENERIC_OAUTH_GROUPS_ATTRIBUTE_PATH: groups
GF_AUTH_OAUTH_AUTO_LOGIN: false
GF_AUTH_DISABLE_LOGIN_FORM: false
GF_SERVER_ROOT_URL: https://grafana.${DOMAIN}
GF_SERVER_SERVE_FROM_SUB_PATH: false
GF_SECURITY_COOKIE_SECURE: true
GF_SECURITY_COOKIE_SAMESITE: lax
GF_AUTH_GENERIC_OAUTH_USE_PKCE: true
labels:
- "traefik.enable=true"
- "traefik.http.routers.grafana.rule=Host(`grafana.${DOMAIN}`)"
- "traefik.http.routers.grafana.entrypoints=websecure"
- "traefik.http.routers.grafana.tls=true"
- "traefik.http.routers.grafana.tls.certresolver=godaddy"
- "traefik.http.services.grafana.loadbalancer.server.port=3000"
# Log Aggregation
loki:
image: grafana/loki:2.9.4
container_name: loki
restart: unless-stopped
networks:
- backend
- frontend
volumes:
- loki_data:/loki
- ./loki/loki.yml:/etc/loki/local-config.yaml:ro
command: -config.file=/etc/loki/local-config.yaml
labels:
- "traefik.enable=true"
- "traefik.http.routers.loki.rule=Host(`loki.${DOMAIN}`)"
- "traefik.http.routers.loki.entrypoints=websecure"
- "traefik.http.routers.loki.tls=true"
- "traefik.http.routers.loki.tls.certresolver=godaddy"
- "traefik.http.routers.loki.middlewares=authentik-forwardauth@file"
- "traefik.http.services.loki.loadbalancer.server.port=3100"
# Log Shipper (for Docker containers)
promtail:
image: grafana/promtail:2.9.4
container_name: promtail
restart: unless-stopped
networks:
- backend
volumes:
- /var/log:/var/log:ro
- /var/lib/docker/containers:/var/lib/docker/containers:ro
- ./loki/promtail-config.yml:/etc/promtail/config.yml:ro
command: -config.file=/etc/promtail/config.yml
depends_on:
- loki

453
infra/base/services.yaml Normal file
View File

@@ -0,0 +1,453 @@
# FILE: infra/compose/production/services.yaml
# Production Application Services for AI Tax Agent
# Deploy to: /opt/compose/ai-tax-agent/services.yaml
# NOTE: Build images locally and push to registry before deploying
networks:
frontend:
external: true
name: frontend
backend:
external: true
name: backend
services:
# Document Ingestion Service
svc-ingestion:
image: gitea.harkon.co.uk/harkon/svc-ingestion:latest
container_name: svc-ingestion
restart: unless-stopped
networks:
- backend
- frontend
environment:
- VAULT_ADDR=http://vault:8200
- VAULT_TOKEN=${VAULT_DEV_ROOT_TOKEN_ID}
- MINIO_ENDPOINT=minio:9092
- MINIO_ACCESS_KEY=${MINIO_ROOT_USER}
- MINIO_SECRET_KEY=${MINIO_ROOT_PASSWORD}
- POSTGRES_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/tax_system
- NEO4J_URL=bolt://neo4j:7687
- NEO4J_USER=neo4j
- NEO4J_PASSWORD=${NEO4J_PASSWORD}
- REDIS_URL=redis://redis:6379
- EVENT_BUS_TYPE=${EVENT_BUS_TYPE}
- NATS_SERVERS=${NATS_SERVERS}
- NATS_STREAM_NAME=${NATS_STREAM_NAME}
- NATS_CONSUMER_GROUP=${NATS_CONSUMER_GROUP}
labels:
- "traefik.enable=true"
- "traefik.http.routers.svc-ingestion.rule=Host(`api.${DOMAIN}`) && PathPrefix(`/ingestion`)"
- "traefik.http.routers.svc-ingestion.entrypoints=websecure"
- "traefik.http.routers.svc-ingestion.tls=true"
- "traefik.http.routers.svc-ingestion.tls.certresolver=godaddy"
- "traefik.http.routers.svc-ingestion.middlewares=authentik-forwardauth@file,rate-limit@file"
- "traefik.http.services.svc-ingestion.loadbalancer.server.port=8000"
# Data Extraction Service
svc-extract:
image: gitea.harkon.co.uk/harkon/svc-extract:latest
container_name: svc-extract
restart: unless-stopped
networks:
- backend
- frontend
environment:
- VAULT_ADDR=http://vault:8200
- VAULT_TOKEN=${VAULT_DEV_ROOT_TOKEN_ID}
- MINIO_ENDPOINT=minio:9092
- MINIO_ACCESS_KEY=${MINIO_ROOT_USER}
- MINIO_SECRET_KEY=${MINIO_ROOT_PASSWORD}
- POSTGRES_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/tax_system
- NEO4J_URL=bolt://neo4j:7687
- NEO4J_USER=neo4j
- NEO4J_PASSWORD=${NEO4J_PASSWORD}
- REDIS_URL=redis://redis:6379
- RAG_EMBEDDING_MODEL=${RAG_EMBEDDING_MODEL}
- EVENT_BUS_TYPE=${EVENT_BUS_TYPE}
- NATS_SERVERS=${NATS_SERVERS}
- NATS_STREAM_NAME=${NATS_STREAM_NAME}
- NATS_CONSUMER_GROUP=${NATS_CONSUMER_GROUP}
labels:
- "traefik.enable=true"
- "traefik.http.routers.svc-extract.rule=Host(`api.${DOMAIN}`) && PathPrefix(`/extract`)"
- "traefik.http.routers.svc-extract.entrypoints=websecure"
- "traefik.http.routers.svc-extract.tls=true"
- "traefik.http.routers.svc-extract.tls.certresolver=godaddy"
- "traefik.http.routers.svc-extract.middlewares=authentik-forwardauth@file,rate-limit@file"
- "traefik.http.services.svc-extract.loadbalancer.server.port=8000"
# Knowledge Graph Service
svc-kg:
image: gitea.harkon.co.uk/harkon/svc-kg:latest
container_name: svc-kg
restart: unless-stopped
networks:
- backend
- frontend
environment:
- VAULT_ADDR=http://vault:8200
- VAULT_TOKEN=${VAULT_DEV_ROOT_TOKEN_ID}
- NEO4J_URI=bolt://neo4j:7687
- NEO4J_USER=neo4j
- NEO4J_PASSWORD=${NEO4J_PASSWORD}
- EVENT_BUS_TYPE=${EVENT_BUS_TYPE}
- NATS_SERVERS=${NATS_SERVERS}
- NATS_STREAM_NAME=${NATS_STREAM_NAME}
- NATS_CONSUMER_GROUP=${NATS_CONSUMER_GROUP}
labels:
- "traefik.enable=true"
- "traefik.http.routers.svc-kg.rule=Host(`api.${DOMAIN}`) && PathPrefix(`/kg`)"
- "traefik.http.routers.svc-kg.entrypoints=websecure"
- "traefik.http.routers.svc-kg.tls=true"
- "traefik.http.routers.svc-kg.tls.certresolver=godaddy"
- "traefik.http.routers.svc-kg.middlewares=authentik-forwardauth@file,rate-limit@file"
- "traefik.http.services.svc-kg.loadbalancer.server.port=8000"
# RAG Retrieval Service
svc-rag-retriever:
image: gitea.harkon.co.uk/harkon/svc-rag-retriever:latest
container_name: svc-rag-retriever
restart: unless-stopped
networks:
- backend
- frontend
environment:
- VAULT_ADDR=http://vault:8200
- VAULT_TOKEN=${VAULT_DEV_ROOT_TOKEN_ID}
- QDRANT_URL=http://qdrant:6333
- NEO4J_URI=bolt://neo4j:7687
- NEO4J_USER=neo4j
- NEO4J_PASSWORD=${NEO4J_PASSWORD}
- RAG_EMBEDDING_MODEL=${RAG_EMBEDDING_MODEL}
- RAG_RERANKER_MODEL=${RAG_RERANKER_MODEL}
- EVENT_BUS_TYPE=${EVENT_BUS_TYPE}
- NATS_SERVERS=${NATS_SERVERS}
- NATS_STREAM_NAME=${NATS_STREAM_NAME}
- NATS_CONSUMER_GROUP=${NATS_CONSUMER_GROUP}
labels:
- "traefik.enable=true"
- "traefik.http.routers.svc-rag-retriever.rule=Host(`api.${DOMAIN}`) && PathPrefix(`/rag`)"
- "traefik.http.routers.svc-rag-retriever.entrypoints=websecure"
- "traefik.http.routers.svc-rag-retriever.tls=true"
- "traefik.http.routers.svc-rag-retriever.tls.certresolver=godaddy"
- "traefik.http.routers.svc-rag-retriever.middlewares=authentik-forwardauth@file,rate-limit@file"
- "traefik.http.services.svc-rag-retriever.loadbalancer.server.port=8000"
# Forms Service
svc-forms:
image: gitea.harkon.co.uk/harkon/svc-forms:latest
container_name: svc-forms
restart: unless-stopped
networks:
- backend
- frontend
environment:
- VAULT_ADDR=http://vault:8200
- VAULT_TOKEN=${VAULT_DEV_ROOT_TOKEN_ID}
- POSTGRES_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/tax_system
- NEO4J_URL=bolt://neo4j:7687
- NEO4J_USER=neo4j
- NEO4J_PASSWORD=${NEO4J_PASSWORD}
- REDIS_URL=redis://redis:6379
- MINIO_ENDPOINT=minio:9092
- MINIO_ACCESS_KEY=${MINIO_ROOT_USER}
- MINIO_SECRET_KEY=${MINIO_ROOT_PASSWORD}
- QDRANT_URL=http://qdrant:6333
- EVENT_BUS_TYPE=${EVENT_BUS_TYPE}
- NATS_SERVERS=${NATS_SERVERS}
- NATS_STREAM_NAME=${NATS_STREAM_NAME}
- NATS_CONSUMER_GROUP=${NATS_CONSUMER_GROUP}
labels:
- "traefik.enable=true"
- "traefik.http.routers.svc-forms.rule=Host(`api.${DOMAIN}`) && PathPrefix(`/forms`)"
- "traefik.http.routers.svc-forms.entrypoints=websecure"
- "traefik.http.routers.svc-forms.tls=true"
- "traefik.http.routers.svc-forms.tls.certresolver=godaddy"
- "traefik.http.routers.svc-forms.middlewares=authentik-forwardauth@file,rate-limit@file"
- "traefik.http.services.svc-forms.loadbalancer.server.port=8000"
# HMRC Integration Service
svc-hmrc:
image: gitea.harkon.co.uk/harkon/svc-hmrc:latest
container_name: svc-hmrc
restart: unless-stopped
networks:
- backend
- frontend
environment:
- VAULT_ADDR=http://vault:8200
- VAULT_TOKEN=${VAULT_DEV_ROOT_TOKEN_ID}
- POSTGRES_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/tax_system
- NEO4J_URL=bolt://neo4j:7687
- NEO4J_USER=neo4j
- NEO4J_PASSWORD=${NEO4J_PASSWORD}
- REDIS_URL=redis://redis:6379
- MINIO_ENDPOINT=minio:9092
- MINIO_ACCESS_KEY=${MINIO_ROOT_USER}
- MINIO_SECRET_KEY=${MINIO_ROOT_PASSWORD}
- QDRANT_URL=http://qdrant:6333
- HMRC_MTD_ITSA_MODE=${HMRC_MTD_ITSA_MODE}
- EVENT_BUS_TYPE=${EVENT_BUS_TYPE}
- NATS_SERVERS=${NATS_SERVERS}
- NATS_STREAM_NAME=${NATS_STREAM_NAME}
- NATS_CONSUMER_GROUP=${NATS_CONSUMER_GROUP}
labels:
- "traefik.enable=true"
- "traefik.http.routers.svc-hmrc.rule=Host(`api.${DOMAIN}`) && PathPrefix(`/hmrc`)"
- "traefik.http.routers.svc-hmrc.entrypoints=websecure"
- "traefik.http.routers.svc-hmrc.tls=true"
- "traefik.http.routers.svc-hmrc.tls.certresolver=godaddy"
- "traefik.http.routers.svc-hmrc.middlewares=authentik-forwardauth@file,rate-limit@file"
- "traefik.http.services.svc-hmrc.loadbalancer.server.port=8000"
# OCR Service
svc-ocr:
image: gitea.harkon.co.uk/harkon/svc-ocr:latest
container_name: svc-ocr
restart: unless-stopped
networks:
- backend
- frontend
environment:
- VAULT_ADDR=http://vault:8200
- VAULT_TOKEN=${VAULT_DEV_ROOT_TOKEN_ID}
- POSTGRES_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/tax_system
- NEO4J_URL=bolt://neo4j:7687
- NEO4J_USER=neo4j
- NEO4J_PASSWORD=${NEO4J_PASSWORD}
- REDIS_URL=redis://redis:6379
- MINIO_ENDPOINT=minio:9092
- MINIO_ACCESS_KEY=${MINIO_ROOT_USER}
- MINIO_SECRET_KEY=${MINIO_ROOT_PASSWORD}
- QDRANT_URL=http://qdrant:6333
- EVENT_BUS_TYPE=${EVENT_BUS_TYPE}
- NATS_SERVERS=${NATS_SERVERS}
- NATS_STREAM_NAME=${NATS_STREAM_NAME}
- NATS_CONSUMER_GROUP=${NATS_CONSUMER_GROUP}
labels:
- "traefik.enable=true"
- "traefik.http.routers.svc-ocr.rule=Host(`api.${DOMAIN}`) && PathPrefix(`/ocr`)"
- "traefik.http.routers.svc-ocr.entrypoints=websecure"
- "traefik.http.routers.svc-ocr.tls=true"
- "traefik.http.routers.svc-ocr.tls.certresolver=godaddy"
- "traefik.http.routers.svc-ocr.middlewares=authentik-forwardauth@file,rate-limit@file"
- "traefik.http.services.svc-ocr.loadbalancer.server.port=8000"
# RAG Indexer Service
svc-rag-indexer:
image: gitea.harkon.co.uk/harkon/svc-rag-indexer:latest
container_name: svc-rag-indexer
restart: unless-stopped
networks:
- backend
- frontend
environment:
- VAULT_ADDR=http://vault:8200
- VAULT_TOKEN=${VAULT_DEV_ROOT_TOKEN_ID}
- POSTGRES_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/tax_system
- NEO4J_URL=bolt://neo4j:7687
- NEO4J_USER=neo4j
- NEO4J_PASSWORD=${NEO4J_PASSWORD}
- REDIS_URL=redis://redis:6379
- MINIO_ENDPOINT=minio:9092
- MINIO_ACCESS_KEY=${MINIO_ROOT_USER}
- MINIO_SECRET_KEY=${MINIO_ROOT_PASSWORD}
- QDRANT_URL=http://qdrant:6333
- EVENT_BUS_TYPE=${EVENT_BUS_TYPE}
- NATS_SERVERS=${NATS_SERVERS}
- NATS_STREAM_NAME=${NATS_STREAM_NAME}
- NATS_CONSUMER_GROUP=${NATS_CONSUMER_GROUP}
labels:
- "traefik.enable=true"
- "traefik.http.routers.svc-rag-indexer.rule=Host(`api.${DOMAIN}`) && PathPrefix(`/rag-indexer`)"
- "traefik.http.routers.svc-rag-indexer.entrypoints=websecure"
- "traefik.http.routers.svc-rag-indexer.tls=true"
- "traefik.http.routers.svc-rag-indexer.tls.certresolver=godaddy"
- "traefik.http.routers.svc-rag-indexer.middlewares=authentik-forwardauth@file,rate-limit@file"
- "traefik.http.services.svc-rag-indexer.loadbalancer.server.port=8000"
# Reasoning Service
svc-reason:
image: gitea.harkon.co.uk/harkon/svc-reason:latest
container_name: svc-reason
restart: unless-stopped
networks:
- backend
- frontend
environment:
- VAULT_ADDR=http://vault:8200
- VAULT_TOKEN=${VAULT_DEV_ROOT_TOKEN_ID}
- POSTGRES_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/tax_system
- NEO4J_URL=bolt://neo4j:7687
- NEO4J_USER=neo4j
- NEO4J_PASSWORD=${NEO4J_PASSWORD}
- REDIS_URL=redis://redis:6379
- MINIO_ENDPOINT=minio:9092
- MINIO_ACCESS_KEY=${MINIO_ROOT_USER}
- MINIO_SECRET_KEY=${MINIO_ROOT_PASSWORD}
- QDRANT_URL=http://qdrant:6333
- EVENT_BUS_TYPE=${EVENT_BUS_TYPE}
- NATS_SERVERS=${NATS_SERVERS}
- NATS_STREAM_NAME=${NATS_STREAM_NAME}
- NATS_CONSUMER_GROUP=${NATS_CONSUMER_GROUP}
labels:
- "traefik.enable=true"
- "traefik.http.routers.svc-reason.rule=Host(`api.${DOMAIN}`) && PathPrefix(`/reason`)"
- "traefik.http.routers.svc-reason.entrypoints=websecure"
- "traefik.http.routers.svc-reason.tls=true"
- "traefik.http.routers.svc-reason.tls.certresolver=godaddy"
- "traefik.http.routers.svc-reason.middlewares=authentik-forwardauth@file,rate-limit@file"
- "traefik.http.services.svc-reason.loadbalancer.server.port=8000"
# RPA Service
svc-rpa:
image: gitea.harkon.co.uk/harkon/svc-rpa:latest
container_name: svc-rpa
restart: unless-stopped
networks:
- backend
- frontend
environment:
- VAULT_ADDR=http://vault:8200
- VAULT_TOKEN=${VAULT_DEV_ROOT_TOKEN_ID}
- POSTGRES_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/tax_system
- NEO4J_URL=bolt://neo4j:7687
- NEO4J_USER=neo4j
- NEO4J_PASSWORD=${NEO4J_PASSWORD}
- REDIS_URL=redis://redis:6379
- MINIO_ENDPOINT=minio:9092
- MINIO_ACCESS_KEY=${MINIO_ROOT_USER}
- MINIO_SECRET_KEY=${MINIO_ROOT_PASSWORD}
- QDRANT_URL=http://qdrant:6333
- EVENT_BUS_TYPE=${EVENT_BUS_TYPE}
- NATS_SERVERS=${NATS_SERVERS}
- NATS_STREAM_NAME=${NATS_STREAM_NAME}
- NATS_CONSUMER_GROUP=${NATS_CONSUMER_GROUP}
labels:
- "traefik.enable=true"
- "traefik.http.routers.svc-rpa.rule=Host(`api.${DOMAIN}`) && PathPrefix(`/rpa`)"
- "traefik.http.routers.svc-rpa.entrypoints=websecure"
- "traefik.http.routers.svc-rpa.tls=true"
- "traefik.http.routers.svc-rpa.tls.certresolver=godaddy"
- "traefik.http.routers.svc-rpa.middlewares=authentik-forwardauth@file,rate-limit@file"
- "traefik.http.services.svc-rpa.loadbalancer.server.port=8000"
# Normalize & Map Service
svc-normalize-map:
image: gitea.harkon.co.uk/harkon/svc-normalize-map:latest
container_name: svc-normalize-map
restart: unless-stopped
networks:
- backend
- frontend
environment:
- VAULT_ADDR=http://vault:8200
- VAULT_TOKEN=${VAULT_DEV_ROOT_TOKEN_ID}
- POSTGRES_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/tax_system
- NEO4J_URL=bolt://neo4j:7687
- NEO4J_USER=neo4j
- NEO4J_PASSWORD=${NEO4J_PASSWORD}
- REDIS_URL=redis://redis:6379
- MINIO_ENDPOINT=minio:9092
- MINIO_ACCESS_KEY=${MINIO_ROOT_USER}
- MINIO_SECRET_KEY=${MINIO_ROOT_PASSWORD}
- QDRANT_URL=http://qdrant:6333
- EVENT_BUS_TYPE=${EVENT_BUS_TYPE}
- NATS_SERVERS=${NATS_SERVERS}
- NATS_STREAM_NAME=${NATS_STREAM_NAME}
- NATS_CONSUMER_GROUP=${NATS_CONSUMER_GROUP}
labels:
- "traefik.enable=true"
- "traefik.http.routers.svc-normalize-map.rule=Host(`api.${DOMAIN}`) && PathPrefix(`/normalize-map`)"
- "traefik.http.routers.svc-normalize-map.entrypoints=websecure"
- "traefik.http.routers.svc-normalize-map.tls=true"
- "traefik.http.routers.svc-normalize-map.tls.certresolver=godaddy"
- "traefik.http.routers.svc-normalize-map.middlewares=authentik-forwardauth@file,rate-limit@file"
- "traefik.http.services.svc-normalize-map.loadbalancer.server.port=8000"
# Coverage Service
svc-coverage:
image: gitea.harkon.co.uk/harkon/svc-coverage:latest
container_name: svc-coverage
restart: unless-stopped
networks:
- backend
- frontend
environment:
- VAULT_ADDR=http://vault:8200
- VAULT_TOKEN=${VAULT_DEV_ROOT_TOKEN_ID}
- POSTGRES_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/tax_system
- NEO4J_URL=bolt://neo4j:7687
- NEO4J_USER=neo4j
- NEO4J_PASSWORD=${NEO4J_PASSWORD}
- REDIS_URL=redis://redis:6379
- MINIO_ENDPOINT=minio:9092
- MINIO_ACCESS_KEY=${MINIO_ROOT_USER}
- MINIO_SECRET_KEY=${MINIO_ROOT_PASSWORD}
- QDRANT_URL=http://qdrant:6333
- EVENT_BUS_TYPE=${EVENT_BUS_TYPE}
- NATS_SERVERS=${NATS_SERVERS}
- NATS_STREAM_NAME=${NATS_STREAM_NAME}
- NATS_CONSUMER_GROUP=${NATS_CONSUMER_GROUP}
labels:
- "traefik.enable=true"
- "traefik.http.routers.svc-coverage.rule=Host(`api.${DOMAIN}`) && PathPrefix(`/coverage`)"
- "traefik.http.routers.svc-coverage.entrypoints=websecure"
- "traefik.http.routers.svc-coverage.tls=true"
- "traefik.http.routers.svc-coverage.tls.certresolver=godaddy"
- "traefik.http.routers.svc-coverage.middlewares=authentik-forwardauth@file,rate-limit@file"
- "traefik.http.services.svc-coverage.loadbalancer.server.port=8000"
# Firm Connectors Service
svc-firm-connectors:
image: gitea.harkon.co.uk/harkon/svc-firm-connectors:latest
container_name: svc-firm-connectors
restart: unless-stopped
networks:
- backend
- frontend
environment:
- VAULT_ADDR=http://vault:8200
- VAULT_TOKEN=${VAULT_DEV_ROOT_TOKEN_ID}
- POSTGRES_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/tax_system
- NEO4J_URL=bolt://neo4j:7687
- NEO4J_USER=neo4j
- NEO4J_PASSWORD=${NEO4J_PASSWORD}
- REDIS_URL=redis://redis:6379
- MINIO_ENDPOINT=minio:9092
- MINIO_ACCESS_KEY=${MINIO_ROOT_USER}
- MINIO_SECRET_KEY=${MINIO_ROOT_PASSWORD}
- QDRANT_URL=http://qdrant:6333
- EVENT_BUS_TYPE=${EVENT_BUS_TYPE}
- NATS_SERVERS=${NATS_SERVERS}
- NATS_STREAM_NAME=${NATS_STREAM_NAME}
- NATS_CONSUMER_GROUP=${NATS_CONSUMER_GROUP}
labels:
- "traefik.enable=true"
- "traefik.http.routers.svc-firm-connectors.rule=Host(`api.${DOMAIN}`) && PathPrefix(`/firm-connectors`)"
- "traefik.http.routers.svc-firm-connectors.entrypoints=websecure"
- "traefik.http.routers.svc-firm-connectors.tls=true"
- "traefik.http.routers.svc-firm-connectors.tls.certresolver=godaddy"
- "traefik.http.routers.svc-firm-connectors.middlewares=authentik-forwardauth@file,rate-limit@file"
- "traefik.http.services.svc-firm-connectors.loadbalancer.server.port=8000"
# Review UI
ui-review:
image: gitea.harkon.co.uk/harkon/ui-review:latest
container_name: ui-review
restart: unless-stopped
networks:
- frontend
environment:
- NEXTAUTH_URL=https://app.${DOMAIN}
- NEXTAUTH_SECRET=${NEXTAUTH_SECRET}
- API_BASE_URL=https://api.${DOMAIN}
labels:
- "traefik.enable=true"
- "traefik.http.routers.ui-review.rule=Host(`app.${DOMAIN}`)"
- "traefik.http.routers.ui-review.entrypoints=websecure"
- "traefik.http.routers.ui-review.tls=true"
- "traefik.http.routers.ui-review.tls.certresolver=godaddy"
- "traefik.http.routers.ui-review.middlewares=authentik-forwardauth@file"
- "traefik.http.services.ui-review.loadbalancer.server.port=3030"