version: '3'
services:
  api_server:
    image: danswer/danswer-ee-backend:latest
    build:
      context: ../../backend
      dockerfile: Dockerfile
    command: >
      /bin/sh -c "alembic upgrade head &&
      echo \"Starting Danswer Api Server\" &&
      uvicorn ee.danswer.main:app --host 0.0.0.0 --port 8080"
    depends_on:
      - relational_db
      - index
      - inference_model_server
    restart: always
    env_file:
      - .env
    environment:
      - AUTH_TYPE=${AUTH_TYPE:-oidc}
      - POSTGRES_HOST=relational_db
      - VESPA_HOST=index
      - MODEL_SERVER_HOST=${MODEL_SERVER_HOST:-inference_model_server}
    extra_hosts:
      - "host.docker.internal:host-gateway"
    logging:
      driver: json-file
      options:
        max-size: "50m"
        max-file: "6"


  background:
    image: danswer/danswer-ee-backend:latest
    build:
      context: ../../backend
      dockerfile: Dockerfile
    command: /usr/bin/supervisord -c /etc/supervisor/conf.d/ee.supervisord.conf
    depends_on:
      - relational_db
      - index
      - inference_model_server
      - indexing_model_server
    restart: always
    env_file:
      - .env
    environment:
      - AUTH_TYPE=${AUTH_TYPE:-oidc}
      - POSTGRES_HOST=relational_db
      - VESPA_HOST=index
      - MODEL_SERVER_HOST=${MODEL_SERVER_HOST:-inference_model_server}
      - INDEXING_MODEL_SERVER_HOST=${INDEXING_MODEL_SERVER_HOST:-indexing_model_server}
    extra_hosts:
      - "host.docker.internal:host-gateway"
    logging:
      driver: json-file
      options:
        max-size: "50m"
        max-file: "6"


  web_server:
    image: danswer/danswer-ee-web-server:latest
    build:
      context: ../../web
      dockerfile: Dockerfile
      args:
        - NEXT_PUBLIC_DISABLE_STREAMING=${NEXT_PUBLIC_DISABLE_STREAMING:-false}
        - NEXT_PUBLIC_NEW_CHAT_DIRECTS_TO_SAME_PERSONA=${NEXT_PUBLIC_NEW_CHAT_DIRECTS_TO_SAME_PERSONA:-false}
        - NEXT_PUBLIC_POSITIVE_PREDEFINED_FEEDBACK_OPTIONS=${NEXT_PUBLIC_POSITIVE_PREDEFINED_FEEDBACK_OPTIONS:-}
        - NEXT_PUBLIC_NEGATIVE_PREDEFINED_FEEDBACK_OPTIONS=${NEXT_PUBLIC_NEGATIVE_PREDEFINED_FEEDBACK_OPTIONS:-}
        - NEXT_PUBLIC_DISABLE_LOGOUT=${NEXT_PUBLIC_DISABLE_LOGOUT:-}
        - NEXT_PUBLIC_THEME=${NEXT_PUBLIC_THEME:-}
        - NEXT_PUBLIC_EE_ENABLED=${NEXT_PUBLIC_EE_ENABLED:-true}
    depends_on:
      - api_server
    restart: always
    env_file:
      - .env
    environment:
      - INTERNAL_URL=http://api_server:8080
    logging:
      driver: json-file
      options:
        max-size: "50m"
        max-file: "6"


  inference_model_server:
    image: danswer/danswer-model-server:latest
    build:
      context: ../../backend
      dockerfile: Dockerfile.model_server
    command: >
      /bin/sh -c "if [ \"${DISABLE_MODEL_SERVER:-false}\" = \"True\" ]; then
        echo 'Skipping service...';
        exit 0;
      else
        exec uvicorn model_server.main:app --host 0.0.0.0 --port 9000;
      fi"
    restart: on-failure
    environment:
      - MIN_THREADS_ML_MODELS=${MIN_THREADS_ML_MODELS:-}
      # Set to debug to get more fine-grained logs
      - LOG_LEVEL=${LOG_LEVEL:-info}
    volumes:
      # Not necessary, this is just to reduce download time during startup
      - model_cache_huggingface:/root/.cache/huggingface/
    logging:
      driver: json-file
      options:
        max-size: "50m"
        max-file: "6"


  indexing_model_server:
    image: danswer/danswer-model-server:latest
    build:
      context: ../../backend
      dockerfile: Dockerfile.model_server
    command: >
      /bin/sh -c "if [ \"${DISABLE_MODEL_SERVER:-false}\" = \"True\" ]; then
        echo 'Skipping service...';
        exit 0;
      else
        exec uvicorn model_server.main:app --host 0.0.0.0 --port 9000;
      fi"
    restart: on-failure
    environment:
      - MIN_THREADS_ML_MODELS=${MIN_THREADS_ML_MODELS:-}
      - INDEXING_ONLY=True
      # Set to debug to get more fine-grained logs
      - LOG_LEVEL=${LOG_LEVEL:-info}
    volumes:
      # Not necessary, this is just to reduce download time during startup
      - model_cache_huggingface:/root/.cache/huggingface/
    logging:
      driver: json-file
      options:
        max-size: "50m"
        max-file: "6"


  relational_db:
    image: postgres:15.2-alpine
    restart: always
    # POSTGRES_USER and POSTGRES_PASSWORD should be set in .env file
    env_file:
      - .env
    volumes:
      - db_volume:/var/lib/postgresql/data
    logging:
      driver: json-file
      options:
        max-size: "50m"
        max-file: "6"


  # This container name cannot have an underscore in it due to Vespa expectations of the URL
  index:
    image: vespaengine/vespa:8.277.17
    restart: always
    ports:
      - "19071:19071"
      - "8081:8081"
    volumes:
      - vespa_volume:/opt/vespa/var
    logging:
      driver: json-file
      options:
        max-size: "50m"
        max-file: "6"


  nginx:
    image: nginx:1.23.4-alpine
    restart: always
    # nginx will immediately crash with `nginx: [emerg] host not found in upstream`
    # if api_server / web_server are not up 
    depends_on:
      - api_server
      - web_server
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ../data/nginx:/etc/nginx/conf.d
      - ../data/sslcerts:/etc/nginx/sslcerts
    logging:
      driver: json-file
      options:
        max-size: "50m"
        max-file: "6"
    # the specified script waits for the api_server to start up. 
    # Without this we've seen issues where nginx shows no error logs but 
    # does not recieve any traffic
    # NOTE: we have to use dos2unix to remove Carriage Return chars from the file
    # in order to make this work on both Unix-like systems and windows
    command: > 
      /bin/sh -c "dos2unix /etc/nginx/conf.d/run-nginx.sh 
      && /etc/nginx/conf.d/run-nginx.sh app.conf.template.no-letsencrypt"
    env_file:
      - .env.nginx


volumes:
  db_volume:
  vespa_volume:
  # Created by the container itself
  model_cache_huggingface:
