213 lines
7.3 KiB
YAML
213 lines
7.3 KiB
YAML
services:
|
||
database:
|
||
image: postgres:16-alpine
|
||
container_name: ipsextractor-db
|
||
environment:
|
||
POSTGRES_DB: ipsextractor
|
||
POSTGRES_USER: ipsextractor
|
||
POSTGRES_PASSWORD: ipsextractor
|
||
volumes:
|
||
- ipsextractor_db:/var/lib/postgresql/data
|
||
healthcheck:
|
||
test: ["CMD-SHELL", "pg_isready -U ipsextractor -d ipsextractor"]
|
||
interval: 5s
|
||
timeout: 5s
|
||
retries: 15
|
||
start_period: 90s
|
||
|
||
redis:
|
||
image: redis:7-alpine
|
||
container_name: ipsextractor-redis
|
||
command: redis-server --maxmemory 512mb --maxmemory-policy allkeys-lru --save ""
|
||
healthcheck:
|
||
test: ["CMD", "redis-cli", "ping"]
|
||
interval: 5s
|
||
timeout: 3s
|
||
retries: 10
|
||
|
||
db-migrations:
|
||
build:
|
||
context: ./services/db
|
||
dockerfile: Dockerfile
|
||
container_name: ipsextractor-db-migrations
|
||
depends_on:
|
||
database:
|
||
condition: service_healthy
|
||
environment:
|
||
DATABASE_URL: postgresql+psycopg://ipsextractor:ipsextractor@database:5432/ipsextractor
|
||
restart: on-failure
|
||
|
||
extraction:
|
||
build:
|
||
context: ./services/extraction
|
||
dockerfile: Dockerfile
|
||
container_name: ipsextractor-extraction
|
||
depends_on:
|
||
database:
|
||
condition: service_healthy
|
||
redis:
|
||
condition: service_healthy
|
||
db-migrations:
|
||
condition: service_completed_successfully
|
||
environment:
|
||
DATABASE_URL: postgresql+psycopg://ipsextractor:ipsextractor@database:5432/ipsextractor
|
||
REDIS_URL: redis://redis:6379/0
|
||
EXTRACTOR_BASE_URL: https://api.openai.com/v1
|
||
EXTRACTOR_API_KEY: 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
|
||
EXTRACTOR_MODEL: ${EXTRACTOR_MODEL:-gpt-5.4-mini}
|
||
NORMALIZER_BASE_URL: https://api.openai.com/v1
|
||
NORMALIZER_API_KEY: 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
|
||
NORMALIZER_MODEL: gpt-5.4-mini
|
||
EXTRACTOR_TIMEOUT_S: ${EXTRACTOR_TIMEOUT_S:-120}
|
||
PDF_DPI: ${PDF_DPI:-150}
|
||
PDF_THREAD_COUNT: ${PDF_THREAD_COUNT:-4}
|
||
CONCURRENCY_LIMIT: ${CONCURRENCY_LIMIT:-50}
|
||
ALLOWED_DOCUMENT_TYPES: ${ALLOWED_DOCUMENT_TYPES:-CC,TI,CE,RC,PA,PPT,PEP,EPT,NUIP}
|
||
volumes:
|
||
- ${IPS_DOCUMENT_ROOT:-./data}:/data
|
||
- ips_queue:/tmp/ips_queue
|
||
healthcheck:
|
||
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8001/health', timeout=5)"]
|
||
interval: 10s
|
||
timeout: 5s
|
||
retries: 5
|
||
start_period: 30s
|
||
|
||
# Escala horizontalmente: docker compose up --scale worker=4
|
||
worker:
|
||
build:
|
||
context: ./services/extraction
|
||
dockerfile: Dockerfile
|
||
command: python -m worker.main
|
||
depends_on:
|
||
database:
|
||
condition: service_healthy
|
||
redis:
|
||
condition: service_healthy
|
||
db-migrations:
|
||
condition: service_completed_successfully
|
||
deploy:
|
||
replicas: ${WORKER_REPLICAS:-2}
|
||
environment:
|
||
DATABASE_URL: postgresql+psycopg://ipsextractor:ipsextractor@database:5432/ipsextractor
|
||
REDIS_URL: redis://redis:6379/0
|
||
EXTRACTOR_BASE_URL: https://api.openai.com/v1
|
||
EXTRACTOR_API_KEY: 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
|
||
EXTRACTOR_MODEL: ${EXTRACTOR_MODEL:-gpt-5.4-mini}
|
||
NORMALIZER_BASE_URL: https://api.openai.com/v1
|
||
NORMALIZER_API_KEY: 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
|
||
NORMALIZER_MODEL: gpt-5.4-mini
|
||
EXTRACTOR_TIMEOUT_S: ${EXTRACTOR_TIMEOUT_S:-120}
|
||
PDF_DPI: ${PDF_DPI:-150}
|
||
PDF_THREAD_COUNT: ${PDF_THREAD_COUNT:-4}
|
||
WORKER_CONCURRENCY: ${WORKER_CONCURRENCY:-25}
|
||
ALLOWED_DOCUMENT_TYPES: ${ALLOWED_DOCUMENT_TYPES:-CC,TI,CE,RC,PA,PPT,PEP,EPT,NUIP}
|
||
volumes:
|
||
- ips_queue:/tmp/ips_queue
|
||
|
||
cleaning:
|
||
build:
|
||
context: ./services/cleaning
|
||
dockerfile: Dockerfile
|
||
container_name: ipsextractor-cleaning
|
||
depends_on:
|
||
database:
|
||
condition: service_healthy
|
||
db-migrations:
|
||
condition: service_completed_successfully
|
||
environment:
|
||
DATABASE_URL: postgresql+psycopg://ipsextractor:ipsextractor@database:5432/ipsextractor
|
||
|
||
count-api:
|
||
build:
|
||
context: ./services/services-count-facturas-medicas-serving
|
||
dockerfile: Dockerfile
|
||
container_name: ipsextractor-count-api
|
||
restart: unless-stopped
|
||
depends_on:
|
||
db-migrations:
|
||
condition: service_completed_successfully
|
||
environment:
|
||
PORT: "8080"
|
||
# OCR_DPI: 150 reduce RAM (~4×) frente a 300; suficiente para contar facturas.
|
||
OCR_DPI: ${OCR_DPI:-150}
|
||
OCR_LANG: ${OCR_LANG:-spa}
|
||
# Con varios lotes paralelos desde el desktop, limitar goroutines evita OOM.
|
||
OCR_POOL_SIZE: ${OCR_POOL_SIZE:-4}
|
||
SYNC_MAX_FILES: ${SYNC_MAX_FILES:-50}
|
||
SYNC_PROCESS_CONCURRENCY: ${SYNC_PROCESS_CONCURRENCY:-4}
|
||
MAX_PDF_SIZE_MB: ${MAX_PDF_SIZE_MB:-20}
|
||
LOG_PIPELINE_TIMING: ${LOG_PIPELINE_TIMING:-false}
|
||
volumes:
|
||
- ./services/services-count-facturas-medicas-serving/models/latest:/app/models:ro
|
||
healthcheck:
|
||
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
|
||
interval: 10s
|
||
timeout: 5s
|
||
retries: 5
|
||
start_period: 90s
|
||
deploy:
|
||
resources:
|
||
limits:
|
||
memory: ${COUNT_API_MEMORY:-4g}
|
||
|
||
bot-descarga:
|
||
build:
|
||
context: ./services/bot_descarga
|
||
dockerfile: Dockerfile
|
||
container_name: ipsextractor-bot-descarga
|
||
restart: unless-stopped
|
||
depends_on:
|
||
database:
|
||
condition: service_healthy
|
||
environment:
|
||
BOT_API_TOKEN: ${BOT_API_TOKEN:-dev-token-change-me}
|
||
BOT_API_HOST: 0.0.0.0
|
||
BOT_API_PORT: "8200"
|
||
DATABASE_URL: postgresql+psycopg://ipsextractor:ipsextractor@database:5432/ipsextractor
|
||
MINIO_ENDPOINT: ${MINIO_ENDPOINT:-https://s3.builker.xyz}
|
||
MINIO_BUCKET: ${MINIO_BUCKET:-pys-cuentas-medicas}
|
||
MINIO_ANONYMOUS: ${MINIO_ANONYMOUS:-1}
|
||
MINIO_ACCESS_KEY: ${MINIO_ACCESS_KEY:-}
|
||
MINIO_SECRET_KEY: ${MINIO_SECRET_KEY:-}
|
||
MINIO_REGION: ${MINIO_REGION:-us-east-1}
|
||
healthcheck:
|
||
test: ["CMD", "curl", "-f", "http://127.0.0.1:8200/health"]
|
||
interval: 10s
|
||
timeout: 5s
|
||
retries: 5
|
||
start_period: 20s
|
||
|
||
api_gateway:
|
||
build:
|
||
context: ./services/api_gateway
|
||
dockerfile: Dockerfile
|
||
container_name: ipsextractor-api
|
||
depends_on:
|
||
extraction:
|
||
condition: service_healthy
|
||
cleaning:
|
||
condition: service_started
|
||
count-api:
|
||
condition: service_healthy
|
||
bot-descarga:
|
||
condition: service_healthy
|
||
environment:
|
||
EXTRACTION_URL: http://extraction:8001
|
||
CLEANING_URL: http://cleaning:8002
|
||
COUNT_URL: http://count-api:8080
|
||
BOT_DESCARGA_URL: http://bot-descarga:8200
|
||
ports:
|
||
# Único puerto expuesto al host. Los demás servicios solo son accesibles en la red Docker.
|
||
- "0.0.0.0:8189:8000"
|
||
healthcheck:
|
||
test: ["CMD", "curl", "-f", "http://localhost:8000/health/live"]
|
||
interval: 10s
|
||
timeout: 5s
|
||
retries: 5
|
||
start_period: 15s
|
||
|
||
volumes:
|
||
ipsextractor_db:
|
||
ips_queue:
|