name: prod-hackaton-template

services:
  backend:
    build:
      context: .
      dockerfile: Containerfile
      target: runtime
      tags:
        - template-project-backend:latest
      pull: true
    depends_on:
      # migrations:
      #   restart: false
      #   condition: service_completed_successfully
      #   required: false
      postgres:
        restart: false
        condition: service_healthy
        required: true
      # redis:
      #   restart: false
      #   condition: service_healthy
      #   required: true
    env_file:
      - path: ./infrastructure/configs/backend/.env.template
        required: true
      - path: ./infrastructure/configs/backend/.env
        required: false
    healthcheck:
      test: [ "CMD", "curl", "-fsS", "http://localhost:8080/healthcheck" ]
      interval: 5s
      timeout: 4s
      start_period: 5s
      start_interval: 2s
      retries: 5
    networks:
      - default
    profiles:
      - backend
    ports:
      - 8080:8080
    # ports:
    #   - name: web
    #     target: 8080
    #     published: 13560
    #     host_ip: 127.0.0.1
    #     protocol: tcp
    #     app_protocol: http
    restart: unless-stopped
    shm_size: 4mb
    volumes:
      - type: bind
        source: ./infrastructure/configs/backend/config.toml
        target: /app/config.toml
        read_only: true
        bind:
          selinux: z
      - type: bind
        source: ./infrastructure/configs/backend/firebase.json
        target: /app/firebase.json
        read_only: true
        bind:
          selinux: z

  ml:
    build:
      context: .
      dockerfile: Containerfile
      target: ml
      tags:
        - template-project-ml:latest
      pull: true
    healthcheck:
      test: [ "CMD", "curl", "-fsS", "http://localhost:8081/healthcheck" ]
      interval: 5s
      timeout: 4s
      start_period: 5s
      start_interval: 2s
      retries: 5
    networks:
      - default
    profiles:
      - ml
    ports:
      - name: web
        target: 8081
        published: 13562
        host_ip: 127.0.0.1
        protocol: tcp
        app_protocol: http
    restart: unless-stopped
    shm_size: 4mb
    volumes:
      - type: bind
        source: ./infrastructure/configs/ml/config.toml
        target: /app/config.toml
        read_only: true
        bind:
          selinux: z

  tests:
    build:
      context: .
      dockerfile: Containerfile
      target: tests
      tags:
        - template-project-tests:latest
      pull: true
    depends_on:
      migrations:
        restart: false
        condition: service_completed_successfully
        required: true
      postgres:
        restart: false
        condition: service_healthy
        required: true
      # redis:
      #   restart: false
      #   condition: service_healthy
      #   required: true
    env_file:
      - path: ./infrastructure/configs/backend/.env.template
        required: true
      - path: ./infrastructure/configs/backend/.env
        required: false
    healthcheck:
      test: [ "CMD", "pg_isready", "-U", "postgres", "--dbname=postgres" ]
      interval: 5s
      timeout: 4s
      start_period: 5s
      start_interval: 2s
      retries: 5
    networks:
      - default
    profiles:
      - tests
    shm_size: 4mb
    volumes:
      - type: bind
        source: ./infrastructure/configs/backend/config.toml
        target: /app/config.toml
        read_only: true
        bind:
          selinux: z
      - type: bind
        source: ./.cov
        target: /app/cov
        read_only: false
        bind:
          selinux: z

  migrations:
    build:
      context: .
      dockerfile: Containerfile
      target: migrations
      tags:
        - template-project-migrations:latest
      pull: true
    depends_on:
      postgres:
        restart: false
        condition: service_healthy
        required: true
    env_file:
      - path: ./infrastructure/configs/backend/.env.template
        required: true
      - path: ./infrastructure/configs/backend/.env
        required: false
    networks:
      - default
    profiles:
      - migrations
    shm_size: 4mb
    volumes:
      - type: bind
        source: ./infrastructure/configs/backend/config.toml
        target: /app/config.toml
        read_only: false
        bind:
          selinux: z
      - type: bind
        source: ./alembic.ini
        target: /app/alembic.ini
        read_only: true
        bind:
          selinux: z

  postgres:
    image: docker.io/pgvector/pgvector:pg17-trixie
    env_file:
      - path: ./infrastructure/configs/postgres/.env.template
        required: true
      - path: ./infrastructure/configs/postgres/.env
        required: false
    healthcheck:
      test: [ "CMD", "pg_isready", "-U", "postgres", "--dbname=app" ]
      interval: 5s
      timeout: 4s
      start_period: 5s
      start_interval: 2s
      retries: 5
    networks:
      - default
    oom_kill_disable: true
    restart: unless-stopped
    shm_size: 128mb
    volumes:
      - type: bind
        source: ./infrastructure/configs/postgres/postgresql.conf
        target: /etc/postgresql/postgresql.conf
        read_only: true
        bind:
          selinux: z
      - type: bind
        source: ./infrastructure/configs/postgres/init-db.sql
        target: /docker-entrypoint-initdb.d/init-db.sql
        read_only: true
        bind:
          selinux: z
      - type: volume
        source: postgres_data
        target: /var/lib/postgresql/data
    ports:
      - "5432:5432"

  pgadmin:
    image: docker.io/dpage/pgadmin4:9
    depends_on:
      postgres:
        restart: false
        condition: service_healthy
        required: true
    env_file:
      - path: ./infrastructure/configs/pgadmin/.env.template
        required: true
      - path: ./infrastructure/configs/pgadmin/.env
        required: false
    healthcheck:
      test: [ "CMD", "wget", "-O", "-", "http://localhost:80/misc/ping" ]
      interval: 5s
      timeout: 4s
      start_period: 5s
      start_interval: 2s
      retries: 5
    ports:
      - name: web
        target: 80
        published: 13561
        host_ip: 127.0.0.1
        protocol: tcp
        app_protocol: http
    networks:
      - default
    profiles:
      - observability
    restart: unless-stopped
    shm_size: 4mb
    volumes:
      - type: bind
        source: ./infrastructure/configs/pgadmin/servers.json
        target: /pgadmin4/servers.json
        read_only: true
        bind:
          selinux: z
      - type: volume
        source: pgadmin_data
        target: /var/lib/pgadmin

  redis:
    image: docker.io/redis:8-alpine
    command: redis-server /usr/local/etc/redis/redis.conf
    env_file:
      - path: ./infrastructure/configs/redis/.env.template
        required: true
      - path: ./infrastructure/configs/redis/.env
        required: false
    healthcheck:
      test: [ "CMD", "redis-cli", "ping" ]
      interval: 5s
      timeout: 4s
      start_period: 5s
      start_interval: 2s
      retries: 5
    networks:
      - default
    profiles:
      - redis
    restart: unless-stopped
    shm_size: 4mb
    volumes:
      - type: bind
        source: ./infrastructure/configs/redis/redis.conf
        target: /usr/local/etc/redis/redis.conf
        read_only: true
        bind:
          selinux: z
      - type: volume
        source: redis_data
        target: /data


networks:
  default:
    driver: bridge
    name: $COMPOSE_PROJECT_NAME
    attachable: false
    enable_ipv4: true
    enable_ipv6: true
    internal: false
    external: false


volumes:
  postgres_data:
  pgadmin_data:
  redis_data:
