# 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: apa-frontend backend: external: true name: apa-backend services: # Document Ingestion Service apa-svc-ingestion: image: gitea.harkon.co.uk/harkon/svc-ingestion:latest container_name: apa-svc-ingestion restart: unless-stopped networks: - backend - frontend environment: - VAULT_ADDR=http://apa-vault:8200 - VAULT_TOKEN=${VAULT_DEV_ROOT_TOKEN_ID} - MINIO_ENDPOINT=apa-minio:9092 - MINIO_ACCESS_KEY=${MINIO_ROOT_USER} - MINIO_SECRET_KEY=${MINIO_ROOT_PASSWORD} - POSTGRES_URL=postgresql://postgres:${POSTGRES_PASSWORD}@apa-postgres:5432/tax_system - NEO4J_URL=bolt://apa-neo4j:7687 - NEO4J_USER=neo4j - NEO4J_PASSWORD=${NEO4J_PASSWORD} - REDIS_URL=redis://apa-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 apa-svc-extract: image: gitea.harkon.co.uk/harkon/svc-extract:latest container_name: apa-svc-extract restart: unless-stopped networks: - backend - frontend environment: - VAULT_ADDR=http://apa-vault:8200 - VAULT_TOKEN=${VAULT_DEV_ROOT_TOKEN_ID} - MINIO_ENDPOINT=apa-minio:9092 - MINIO_ACCESS_KEY=${MINIO_ROOT_USER} - MINIO_SECRET_KEY=${MINIO_ROOT_PASSWORD} - POSTGRES_URL=postgresql://postgres:${POSTGRES_PASSWORD}@apa-postgres:5432/tax_system - NEO4J_URL=bolt://apa-neo4j:7687 - NEO4J_USER=neo4j - NEO4J_PASSWORD=${NEO4J_PASSWORD} - REDIS_URL=redis://apa-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 apa-svc-kg: image: gitea.harkon.co.uk/harkon/svc-kg:latest container_name: apa-svc-kg restart: unless-stopped networks: - backend - frontend environment: - VAULT_ADDR=http://apa-vault:8200 - VAULT_TOKEN=${VAULT_DEV_ROOT_TOKEN_ID} - NEO4J_URI=bolt://apa-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 apa-svc-rag-retriever: image: gitea.harkon.co.uk/harkon/svc-rag-retriever:latest container_name: apa-svc-rag-retriever restart: unless-stopped networks: - backend - frontend environment: - VAULT_ADDR=http://apa-vault:8200 - VAULT_TOKEN=${VAULT_DEV_ROOT_TOKEN_ID} - QDRANT_URL=http://apa-qdrant:6333 - NEO4J_URI=bolt://apa-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 apa-svc-forms: image: gitea.harkon.co.uk/harkon/svc-forms:latest container_name: apa-svc-forms restart: unless-stopped networks: - backend - frontend environment: - VAULT_ADDR=http://apa-vault:8200 - VAULT_TOKEN=${VAULT_DEV_ROOT_TOKEN_ID} - POSTGRES_URL=postgresql://postgres:${POSTGRES_PASSWORD}@apa-postgres:5432/tax_system - NEO4J_URL=bolt://apa-neo4j:7687 - NEO4J_USER=neo4j - NEO4J_PASSWORD=${NEO4J_PASSWORD} - REDIS_URL=redis://apa-redis:6379 - MINIO_ENDPOINT=apa-minio:9092 - MINIO_ACCESS_KEY=${MINIO_ROOT_USER} - MINIO_SECRET_KEY=${MINIO_ROOT_PASSWORD} - QDRANT_URL=http://apa-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 apa-svc-hmrc: image: gitea.harkon.co.uk/harkon/svc-hmrc:latest container_name: apa-svc-hmrc restart: unless-stopped networks: - backend - frontend environment: - VAULT_ADDR=http://apa-vault:8200 - VAULT_TOKEN=${VAULT_DEV_ROOT_TOKEN_ID} - POSTGRES_URL=postgresql://postgres:${POSTGRES_PASSWORD}@apa-postgres:5432/tax_system - NEO4J_URL=bolt://apa-neo4j:7687 - NEO4J_USER=neo4j - NEO4J_PASSWORD=${NEO4J_PASSWORD} - REDIS_URL=redis://apa-redis:6379 - MINIO_ENDPOINT=apa-minio:9092 - MINIO_ACCESS_KEY=${MINIO_ROOT_USER} - MINIO_SECRET_KEY=${MINIO_ROOT_PASSWORD} - QDRANT_URL=http://apa-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 apa-svc-ocr: image: gitea.harkon.co.uk/harkon/svc-ocr:latest container_name: apa-svc-ocr restart: unless-stopped networks: - backend - frontend environment: - VAULT_ADDR=http://apa-vault:8200 - VAULT_TOKEN=${VAULT_DEV_ROOT_TOKEN_ID} - POSTGRES_URL=postgresql://postgres:${POSTGRES_PASSWORD}@apa-postgres:5432/tax_system - NEO4J_URL=bolt://apa-neo4j:7687 - NEO4J_USER=neo4j - NEO4J_PASSWORD=${NEO4J_PASSWORD} - REDIS_URL=redis://apa-redis:6379 - MINIO_ENDPOINT=apa-minio:9092 - MINIO_ACCESS_KEY=${MINIO_ROOT_USER} - MINIO_SECRET_KEY=${MINIO_ROOT_PASSWORD} - QDRANT_URL=http://apa-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 apa-svc-rag-indexer: image: gitea.harkon.co.uk/harkon/svc-rag-indexer:latest container_name: apa-svc-rag-indexer restart: unless-stopped networks: - backend - frontend environment: - VAULT_ADDR=http://apa-vault:8200 - VAULT_TOKEN=${VAULT_DEV_ROOT_TOKEN_ID} - POSTGRES_URL=postgresql://postgres:${POSTGRES_PASSWORD}@apa-postgres:5432/tax_system - NEO4J_URL=bolt://apa-neo4j:7687 - NEO4J_USER=neo4j - NEO4J_PASSWORD=${NEO4J_PASSWORD} - REDIS_URL=redis://apa-redis:6379 - MINIO_ENDPOINT=apa-minio:9092 - MINIO_ACCESS_KEY=${MINIO_ROOT_USER} - MINIO_SECRET_KEY=${MINIO_ROOT_PASSWORD} - QDRANT_URL=http://apa-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 apa-svc-reason: image: gitea.harkon.co.uk/harkon/svc-reason:latest container_name: apa-svc-reason restart: unless-stopped networks: - backend - frontend environment: - VAULT_ADDR=http://apa-vault:8200 - VAULT_TOKEN=${VAULT_DEV_ROOT_TOKEN_ID} - POSTGRES_URL=postgresql://postgres:${POSTGRES_PASSWORD}@apa-postgres:5432/tax_system - NEO4J_URL=bolt://apa-neo4j:7687 - NEO4J_USER=neo4j - NEO4J_PASSWORD=${NEO4J_PASSWORD} - REDIS_URL=redis://apa-redis:6379 - MINIO_ENDPOINT=apa-minio:9092 - MINIO_ACCESS_KEY=${MINIO_ROOT_USER} - MINIO_SECRET_KEY=${MINIO_ROOT_PASSWORD} - QDRANT_URL=http://apa-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 apa-svc-rpa: image: gitea.harkon.co.uk/harkon/svc-rpa:latest container_name: apa-svc-rpa restart: unless-stopped networks: - backend - frontend environment: - VAULT_ADDR=http://apa-vault:8200 - VAULT_TOKEN=${VAULT_DEV_ROOT_TOKEN_ID} - POSTGRES_URL=postgresql://postgres:${POSTGRES_PASSWORD}@apa-postgres:5432/tax_system - NEO4J_URL=bolt://apa-neo4j:7687 - NEO4J_USER=neo4j - NEO4J_PASSWORD=${NEO4J_PASSWORD} - REDIS_URL=redis://apa-redis:6379 - MINIO_ENDPOINT=apa-minio:9092 - MINIO_ACCESS_KEY=${MINIO_ROOT_USER} - MINIO_SECRET_KEY=${MINIO_ROOT_PASSWORD} - QDRANT_URL=http://apa-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 apa-svc-normalize-map: image: gitea.harkon.co.uk/harkon/svc-normalize-map:latest container_name: apa-svc-normalize-map restart: unless-stopped networks: - backend - frontend environment: - VAULT_ADDR=http://apa-vault:8200 - VAULT_TOKEN=${VAULT_DEV_ROOT_TOKEN_ID} - POSTGRES_URL=postgresql://postgres:${POSTGRES_PASSWORD}@apa-postgres:5432/tax_system - NEO4J_URL=bolt://apa-neo4j:7687 - NEO4J_USER=neo4j - NEO4J_PASSWORD=${NEO4J_PASSWORD} - REDIS_URL=redis://apa-redis:6379 - MINIO_ENDPOINT=apa-minio:9092 - MINIO_ACCESS_KEY=${MINIO_ROOT_USER} - MINIO_SECRET_KEY=${MINIO_ROOT_PASSWORD} - QDRANT_URL=http://apa-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 apa-svc-coverage: image: gitea.harkon.co.uk/harkon/svc-coverage:latest container_name: apa-svc-coverage restart: unless-stopped networks: - backend - frontend environment: - VAULT_ADDR=http://apa-vault:8200 - VAULT_TOKEN=${VAULT_DEV_ROOT_TOKEN_ID} - POSTGRES_URL=postgresql://postgres:${POSTGRES_PASSWORD}@apa-postgres:5432/tax_system - NEO4J_URL=bolt://apa-neo4j:7687 - NEO4J_USER=neo4j - NEO4J_PASSWORD=${NEO4J_PASSWORD} - REDIS_URL=redis://apa-redis:6379 - MINIO_ENDPOINT=apa-minio:9092 - MINIO_ACCESS_KEY=${MINIO_ROOT_USER} - MINIO_SECRET_KEY=${MINIO_ROOT_PASSWORD} - QDRANT_URL=http://apa-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 apa-svc-firm-connectors: image: gitea.harkon.co.uk/harkon/svc-firm-connectors:latest container_name: apa-svc-firm-connectors restart: unless-stopped networks: - backend - frontend environment: - VAULT_ADDR=http://apa-vault:8200 - VAULT_TOKEN=${VAULT_DEV_ROOT_TOKEN_ID} - POSTGRES_URL=postgresql://postgres:${POSTGRES_PASSWORD}@apa-postgres:5432/tax_system - NEO4J_URL=bolt://apa-neo4j:7687 - NEO4J_USER=neo4j - NEO4J_PASSWORD=${NEO4J_PASSWORD} - REDIS_URL=redis://apa-redis:6379 - MINIO_ENDPOINT=apa-minio:9092 - MINIO_ACCESS_KEY=${MINIO_ROOT_USER} - MINIO_SECRET_KEY=${MINIO_ROOT_PASSWORD} - QDRANT_URL=http://apa-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 apa-ui-review: image: gitea.harkon.co.uk/harkon/ui-review:latest container_name: apa-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"