name: st-messages

services:
  postgresql:
    image: postgres:16.6
    ports:
      - "8912:5432"
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"]
      interval: 1s
      timeout: 2s
      retries: 300
    env_file:
      - env.d/development/postgresql.defaults
      - env.d/development/postgresql.local

  redis:
    image: redis:5
    ports:
      - "8913:6379"

  opensearch:
    image: opensearchproject/opensearch:2.19.2
    environment:
      - discovery.type=single-node
      - bootstrap.memory_lock=true
      - "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m"
      - "DISABLE_INSTALL_DEMO_CONFIG=true"
      - "DISABLE_SECURITY_PLUGIN=true"
      # - http.cors.enabled=true
      # - "http.cors.allow-origin=/.*/"
    ports:
      - "8914:9200"  # REST API
      - "8915:9600"  # Performance Analyzer
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9200"]
      interval: 1s
      timeout: 5s
      retries: 60
    ulimits:
      memlock:
        soft: -1 # Set memlock to unlimited (no soft or hard limit)
        hard: -1
      nofile:
        soft: 65536 # Maximum number of open files for the opensearch user - set to at least 65536
        hard: 65536

  mailcatcher:
    image: maildev/maildev:2.2.1
    ports:
      - "8904:1080"
      - "8917:1025"

  objectstorage:
    # user: ${DOCKER_USER:-1000}
    image: rustfs/rustfs:1.0.0-alpha.83
    environment:
      - RUSTFS_ACCESS_KEY=st-messages
      - RUSTFS_SECRET_KEY=password
      - RUSTFS_CONSOLE_ENABLE=true
      - RUSTFS_ADDRESS=0.0.0.0:9000
      - RUSTFS_CONSOLE_ADDRESS=0.0.0.0:9001
      - RUSTFS_CORS_ALLOWED_ORIGINS=*
      - RUSTFS_CONSOLE_CORS_ALLOWED_ORIGINS=*
    ports:
      - "8906:9000"
      - "8907:9001"
    healthcheck:
      test:
        [
          "CMD",
          "sh",
          "-c",
          "curl -f http://127.0.0.1:9000/health && curl -f http://127.0.0.1:9001/rustfs/console/health",
        ]
      interval: 1s
      timeout: 5s
      retries: 60
      start_period: 0s
    volumes:
      - objectstorage-data:/data

  backend-base:
    build:
      context: src/backend
      target: runtime-dev
      args:
        DOCKER_USER: ${DOCKER_USER:-1000}
    user: ${DOCKER_USER:-1000}
    volumes:
      - ./src/backend:/app
      - ./data/static:/data/static
    healthcheck:
      test: ["CMD", "python", "-c", "import urllib.request as u; u.urlopen('http://localhost:8000/__heartbeat__/', timeout=1)"]
      interval: 3s
      retries: 3
      start_period: 10s

  backend-dev:
    extends: backend-base
    environment:
      - PYLINTHOME=/app/.pylint.d
      - DJANGO_CONFIGURATION=Development
    env_file:
      - env.d/development/backend.defaults
      - env.d/development/backend.local
    ports:
      - "8901:8000"
    depends_on:
      postgresql:
        condition: service_healthy
        # restart: true
      objectstorage:
       condition: service_healthy
      redis:
        condition: service_started
      opensearch:
        condition: service_healthy
      keycloak:
        condition: service_started
      mailcatcher:
        condition: service_started

  backend-db:
    extends: backend-base
    profiles:
      - tools
    environment:
      - DJANGO_CONFIGURATION=DevelopmentMinimal
    env_file:
      - env.d/development/backend.defaults
      - env.d/development/backend.local
    ports:
      - "8901:8000"
    depends_on:
      postgresql:
        condition: service_healthy
        # restart: true

  backend-uv:
    profiles:
      - tools
    volumes:
      - ./src/backend:/app
    build:
      context: src/backend/
      target: uv
    pull_policy: build

  worker-dev:
    build:
      context: src/backend
      target: runtime-dev
      args:
        DOCKER_USER: ${DOCKER_USER:-1000}
    user: ${DOCKER_USER:-1000}
    command: ["python", "worker.py", "--loglevel=DEBUG"]
    environment:
      - DJANGO_CONFIGURATION=Development
    env_file:
      - env.d/development/backend.defaults
      - env.d/development/backend.local
    volumes:
      - ./src/backend:/app
      - ./data/static:/data/static
    depends_on:
      - backend-dev

  worker-ui:
    build:
      context: src/backend
      target: runtime-dev
      args:
        DOCKER_USER: ${DOCKER_USER:-1000}
    user: ${DOCKER_USER:-1000}
    depends_on:
      - redis
    environment:
      - FLOWER_UNAUTHENTICATED_API=true
      - DJANGO_CONFIGURATION=Development
    env_file:
      - env.d/development/backend.defaults
      - env.d/development/backend.local
    volumes:
      - ./src/backend:/app
    ports:
      - "8903:8803"
    command: celery -A messages.celery_app flower --port=8803

  frontend-base:
    user: "${DOCKER_USER:-1000}"
    build:
      context: ./src/frontend
      dockerfile: Dockerfile
      target: frontend-deps
      args:
        DOCKER_USER: ${DOCKER_USER:-1000}

  frontend-dev:
    extends: frontend-base
    env_file:
      - env.d/development/frontend.defaults
      - env.d/development/frontend.local
    command: ["npm", "run", "dev"]
    volumes:
      - ./src/frontend/:/home/frontend/
    ports:
      - "8900:3000"

  frontend-tools:
    extends: frontend-base
    profiles:
      - frontend-tools
    volumes:
      - ./src/backend/core/api/openapi.json:/home/backend/core/api/openapi.json
      - ./src/frontend/:/home/frontend/

  frontend-tools-amd64:
    extends: frontend-tools
    platform: linux/amd64

  crowdin:
    image: crowdin/cli:4.11.0
    volumes:
      - ".:/app"
    env_file:
      - env.d/development/crowdin.defaults
      - env.d/development/crowdin.local
    user: "${DOCKER_USER:-1000}"
    working_dir: /app

  mta-in:
    build:
      context: src/mta-in
      target: runtime-prod
    env_file:
      - env.d/development/mta-in.defaults
      - env.d/development/mta-in.local
    ports:
      - "8910:25"
    depends_on:
      - backend-dev

  mta-in-test:
    profiles:
      - tools
    build:
      context: src/mta-in
      target: runtime-dev
    env_file:
      - env.d/development/mta-in.defaults
      - env.d/development/mta-in.local
    environment:
      - EXEC_CMD=true
      - MDA_API_BASE_URL=http://localhost:8000/api/mail/
      - MTA_HOST=localhost
    command: pytest -vvs tests/
    volumes:
      - ./src/mta-in:/app

  mta-in-uv:
    profiles:
      - tools
    volumes:
      - ./src/mta-in:/app
    build:
      context: src/mta-in
      target: uv
    pull_policy: build

  mta-out:
    build:
      context: src/mta-out
      target: runtime-prod
    env_file:
      - env.d/development/mta-out.defaults
      - env.d/development/mta-out.local
    ports:
      - "8911:587"
    depends_on:
      mailcatcher:
        condition: service_started

  mta-out-test:
    profiles:
      - tools
    build:
      context: src/mta-out
      target: runtime-dev
    env_file:
      - env.d/development/mta-out.defaults
      - env.d/development/mta-out.local
    environment:
      - EXEC_CMD=true
      - MTA_OUT_SMTP_HOST=localhost:587
      - MTA_OUT_SMTP_USERNAME=user
      - MTA_OUT_SMTP_PASSWORD=pass
      - SMTP_RELAY_HOST=localhost:2525
    command: pytest -vvs tests/
    volumes:
      - ./src/mta-out:/app

  socks-proxy:
    build:
      context: src/socks-proxy
      target: runtime
    env_file:
      - env.d/development/socks-proxy.defaults
      - env.d/development/socks-proxy.local
    ports:
      - "8916:1080"

  socks-proxy-test:
    profiles:
      - tools
    build:
      context: src/socks-proxy/tests
    environment:
      - SOCKS_PROXY1=user1:pwd1@socks-proxy:1080
      - SOCKS_PROXY2=user2:pwd2@socks-proxy:1080
    depends_on:
      socks-proxy:
        condition: service_started

  mta-out-uv:
    profiles:
      - tools
    volumes:
      - ./src/mta-out:/app
    build:
      context: src/mta-out
      target: uv
    pull_policy: build

  keycloak:
    image: quay.io/keycloak/keycloak:26.5.3
    volumes:
      - ./src/keycloak/realm.json:/opt/keycloak/data/import/realm.json:ro
      - ./src/keycloak/themes/dsfr-2.2.1.jar:/opt/keycloak/providers/keycloak-theme.jar:ro
    environment:
      - HOST=http://localhost:8902
      - ADMIN_HOST=http://localhost:8902
    command:
      - start-dev
      - --features=preview
      - --import-realm
      - --proxy-headers=xforwarded
      - --http-enabled=true
      - --hostname=$${HOST}
      - --hostname-admin=$${ADMIN_HOST}
      - --http-port=8802
    env_file:
      - env.d/development/keycloak.defaults
      - env.d/development/keycloak.local
    ports:
      - "8902:8802"
    depends_on:
      - postgresql

  mpa:
    build:
      context: src/mpa/rspamd
    environment:
      - RSPAMD_password=password
      - PORT=8010
    ports:
      - "8918:8010"
    depends_on:
      redis:
        condition: service_started

  mpa-test:
    profiles:
      - tools
    build:
      context: src/mpa/tests
    environment:
      - RSPAMD_URL=http://mpa:8010/_api
      - RSPAMD_AUTH=Bearer password
    command: pytest -vvs tests/
    volumes:
      - ./src/mpa/tests:/app/tests
    depends_on:
      mpa:
        condition: service_started
      redis:
        condition: service_started

volumes:
  objectstorage-data:
