Ctrl K
ComunidadGuías…

docker-compose.yml

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
services:

  db:
    image: timescale/timescaledb:2.31.0-pg16@sha256:322ae364eca3321cf2a48f1ef31213b87843413b3cf8feeebf54e999a26bb731
    container_name: pulsebase-db
    restart: unless-stopped
    environment:
      POSTGRES_DB: garmin
      POSTGRES_USER: ${DB_USER}
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    ports:
      - "127.0.0.1:5433:5432"
    volumes:
      - timescale-data:/var/lib/postgresql/data
    networks:
      - internal
    labels:
      - "monitoring=true"
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${DB_USER} -d garmin"]
      interval: 10s
      timeout: 5s
      retries: 5
    deploy:
      resources:
        limits:
          memory: 2g
          cpus: '1.00'
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

  flyway:
    image: flyway/flyway:13@sha256:4c535796a4a08daf542ac266b4f218e01e35051a8103de876536dfcdd1808471
    container_name: pulsebase-flyway
    command: migrate
    volumes:
      - ./db/migrations:/flyway/sql
    environment:
      - FLYWAY_URL=jdbc:postgresql://db:5432/garmin
      - FLYWAY_USER=${DB_USER}
      - FLYWAY_PASSWORD=${DB_PASSWORD}
      - FLYWAY_CONNECT_RETRIES=10
      - FLYWAY_MIXED=true
      - FLYWAY_PLACEHOLDERS_DB_APP_USER=${DB_APP_USER}
      - FLYWAY_PLACEHOLDERS_DB_APP_PASSWORD=${DB_APP_PASSWORD}
      - FLYWAY_PLACEHOLDERS_DB_SYNC_USER=${DB_SYNC_USER}
      - FLYWAY_PLACEHOLDERS_DB_SYNC_PASSWORD=${DB_SYNC_PASSWORD}
      - FLYWAY_PLACEHOLDERS_DB_ML_USER=${DB_ML_USER}
      - FLYWAY_PLACEHOLDERS_DB_ML_PASSWORD=${DB_ML_PASSWORD}
    depends_on:
      db:
        condition: service_healthy
    networks:
      - internal
    deploy:
      resources:
        limits:
          memory: 256m
          cpus: '0.25'
    logging:
      driver: json-file
      options:
        max-size: "5m"
        max-file: "2"

  api:
    build:
      context: .
      dockerfile: api/Dockerfile
    container_name: pulsebase-api
    restart: unless-stopped
    stop_grace_period: 45s
    init: true
    security_opt:
      - "no-new-privileges:true"
    labels:
      - "monitoring=true"
    env_file:
      - env/.env.app
      - env/.env.api
    environment:
      DB_HOST: db
      DB_PORT: 5432
      DB_NAME: garmin
    depends_on:
      flyway:
        condition: service_completed_successfully
    networks:
      - internal
      - gateway-garmin
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/ready"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 30s
    deploy:
      resources:
        limits:
          memory: 512m
          cpus: '0.50'
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

  sync-service:
    build:
      context: .
      dockerfile: sync-service/Dockerfile
    container_name: pulsebase-sync
    restart: unless-stopped
    stop_grace_period: 120s
    init: true
    security_opt:
      - "no-new-privileges:true"
    labels:
      - "monitoring=true"
    depends_on:
      flyway:
        condition: service_completed_successfully
    env_file:
      - env/.env.app
      - env/.env.sync
    environment:
      DB_HOST: db
      DB_PORT: 5432
      DB_NAME: garmin
    networks:
      - internal
    healthcheck:
      test: ["CMD-SHELL", "test -f /tmp/sync_alive && python -c \"import urllib.request; urllib.request.urlopen('http://localhost:8080/health')\""]
      interval: 30s
      timeout: 5s
      start_period: 120s
      retries: 3
    deploy:
      resources:
        limits:
          memory: 256m
          cpus: '0.25'
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

  ml-service:
    build: ./ml-service
    container_name: pulsebase-ml
    restart: unless-stopped
    stop_grace_period: 120s
    init: true
    security_opt:
      - "no-new-privileges:true"
    labels:
      - "monitoring=true"
    depends_on:
      flyway:
        condition: service_completed_successfully
    env_file:
      - env/.env.app
      - env/.env.ml
    environment:
      MODEL_DIR: /app/models
      DB_HOST: db
      DB_PORT: 5432
      DB_NAME: garmin
    volumes:
      - ml-models:/app/models
    networks:
      - internal
    healthcheck:
      test: ["CMD-SHELL", "test -f /tmp/ml_alive && python -c \"import urllib.request; urllib.request.urlopen('http://localhost:8080/health')\""]
      interval: 30s
      timeout: 5s
      start_period: 60s
      retries: 3
    deploy:
      resources:
        limits:
          memory: 1g
          cpus: '1.00'
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

  backup:
    build: ./backup
    container_name: pulsebase-backup
    restart: unless-stopped
    labels:
      - "monitoring=true"
    # DB admin creds come from env/.env (pg_dump needs full read); backup config
    # from env/.env.backup (optional — stack still starts if absent, the run just
    # fails its preflight on a missing AGE_RECIPIENT).
    env_file:
      - path: env/.env.backup
        required: false
    environment:
      PGHOST: db
      PGPORT: 5432
      PGUSER: ${DB_USER}
      PGPASSWORD: ${DB_PASSWORD}
      PGDATABASE: garmin
    depends_on:
      db:
        condition: service_healthy
    volumes:
      - backups:/backups
    networks:
      - internal
    deploy:
      resources:
        limits:
          memory: 256m
          cpus: '0.25'
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

volumes:
  timescale-data:
  ml-models:
  backups:

networks:
  internal:
    driver: bridge
  gateway-garmin:
    external: true
    name: gateway-garmin