version: "3.4"

x-logging:
  &default-logging
  driver: "json-file"
  options:
    max-size: "50m"
    max-file: "10"

services:
  proxy:
    image: pavics/canarieapi:0.3.5
    container_name: proxy
    ports:
      - "80:80"
      - "443:${PROXY_SECURE_PORT}"
      - "58094:8094"
      - "58093:8093"
      - "58091:8091"
      - "58079:8079"
      - "58086:8086"
    volumes:
      - ./config/proxy/conf.d:/etc/nginx/conf.d
      - ./config/proxy/nginx.conf:/etc/nginx/nginx.conf
      - ./config/canarie-api/docker_configuration.py:/config/docker_configuration.py
      - ${SSL_CERTIFICATE}:/etc/nginx/cert.pem
      - wps_outputs:/pavics-data/wps_outputs
      - ./config/canarie-api/entrypoint:/entrypoint:ro
    environment:
      CANARIE_API_CONFIG_FN: /config/docker_configuration.py
      CANARIE_MONITORING_EXTRA_CONF_DIR: ${CANARIE_MONITORING_EXTRA_CONF_DIR}
      # https://github.com/bird-house/birdhouse-deploy/issues/198
      REQUESTS_CA_BUNDLE: /etc/ssl/certs/ca-certificates.crt
    links:
      - thredds
    entrypoint: /entrypoint
    restart: always
    logging: *default-logging

  frontend:
    image: pavics/pavics-frontend:1.0.5
    container_name: frontend
    ports:
      - "3000:3000"
    env_file:
      - ./config/frontend/frontend.env
    restart: always
    logging: *default-logging

  project-api:
    image: pavics/pavics-project-api:0.9.0
    container_name: project-api
    environment:
      POSTGRES_HOST: postgres
    ports:
      - "3005:3005"
    links:
      - postgres
    env_file:
      - ./config/postgres/credentials.env
    restart: always
    logging: *default-logging

  postgres:
    image: postgres:9.6
    container_name: postgres
    # ports:  # should not be exposed directly, enable 'optional-components/database-external-ports' as needed
    volumes:
      - ${DATA_PERSIST_ROOT}/frontend_persist:/var/lib/postgresql/data/pgdata
      - ./config/postgres/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
      - ./config/postgres/postgres-setup.sh:/postgres-setup.sh
    environment:
      PGDATA: /var/lib/postgresql/data/pgdata
    env_file:
      - ./config/postgres/credentials.env
    restart: always
    logging: *default-logging

  phoenix:
    image: pavics/pyramid-phoenix:pavics-0.2.3
    container_name: phoenix
    environment:
      HOSTNAME: $HOSTNAME
      HTTP_PORT: 8081
      HTTPS_PORT: 8443
      OUTPUT_PORT: 38443
    ports:
      - "8081:8081"
      - "8443:8443"
      - "38443:38443"
      - "9001:9001"
    volumes:
      - ./config/phoenix/custom.cfg:/opt/birdhouse/src/phoenix/custom.cfg
      - ${SSL_CERTIFICATE}:/opt/birdhouse/etc/nginx/cert.pem
    links:
      - mongodb
    networks:
      - default
      - mongodb
    depends_on:
      - malleefowl
      - flyingpigeon
      - catalog
      - proxy
    restart: always
    logging: *default-logging

  catalog:
    image: pavics/pavics-datacatalog:0.6.11
    container_name: catalog
    ports:
      - "8086:80"
    volumes:
      - ./config/catalog/catalog.cfg:/home/catalog.cfg
      - wps_outputs:/var/www/html/wps_results
    depends_on:
      - postgres
    restart: always
    logging: *default-logging

  geoserver:
    image: ${GEOSERVER_IMAGE}
    container_name: geoserver
    ports:
      - "8087:8080"
    environment:
      # for custom entrypoint
      PAVICS_FQDN_PUBLIC: ${PAVICS_FQDN_PUBLIC}
      STABLE_EXTENSIONS: ${GEOSERVER_STABLE_EXTENSIONS}
      COMMUNITY_EXTENSIONS: ${GEOSERVER_COMMUNITY_EXTENSIONS}
      GEOSERVER_ADMIN_USER: ${GEOSERVER_ADMIN_USER}
      GEOSERVER_ADMIN_PASSWORD: ${GEOSERVER_ADMIN_PASSWORD}
      # fix "WARNING: Illegal reflective access by org.geotools.image.ImageWorker" in `docker logs geoserver`
      JAVA_OPTS: --add-exports=java.desktop/com.sun.imageio.plugins.jpeg=ALL-UNNAMED
      MAXIMUM_MEMORY: 8G
    volumes:
      # run deployment/fix-geoserver-data-dir-perm on existing
      # GEOSERVER_DATA_DIR to match user geoserveruser inside docker image
      - ${GEOSERVER_DATA_DIR}:/opt/geoserver/data_dir
      - ./config/geoserver/entrypointwrapper:/entrypointwrapper:ro
    links:
      - postgis
    entrypoint: /entrypointwrapper
    restart: always
    logging: *default-logging
    healthcheck:
      test: curl --fail --silent http://localhost:8080/ || exit 1
      interval: 1m30s
      timeout: 10s
      retries: 3

  malleefowl:
    image: pavics/malleefowl:pavics-0.3.5
    container_name: malleefowl
    environment:
      HOSTNAME: $HOSTNAME
      PAVICS_FQDN_PUBLIC: $PAVICS_FQDN_PUBLIC
      HTTP_PORT: 8091
      HTTPS_PORT: 28091
      OUTPUT_PORT: 38091
    ports:
      - "8091:8091"
      - "28091:28091"
      - "38091:38091"
      - "48091:9001"
    volumes:
      - ${DATA_PERSIST_ROOT}/datasets:/pavics-data
      - ./config/malleefowl/custom.cfg:/opt/birdhouse/src/malleefowl/custom.cfg
      - data:/opt/birdhouse/var/lib
      - wps_outputs:/opt/birdhouse/var/lib/pywps/outputs
    depends_on:
      - postgres
    restart: always
    logging: *default-logging

  flyingpigeon:
    image: birdhouse/flyingpigeon:1.6
    container_name: flyingpigeon
    environment:
      - PYWPS_CFG=/wps.cfg
    ports:
      - "8093:8093"
    volumes:
      - ./config/flyingpigeon/wps.cfg:/wps.cfg
      - wps_outputs:/data/wpsoutputs
      - /tmp
    depends_on:
      - postgres
    restart: always
    logging: *default-logging

  finch:
    image: ${FINCH_IMAGE}
    container_name: finch
    environment:
      HOSTNAME: $HOSTNAME
      HTTP_PORT: 5000
      PYWPS_CFG: /wps.cfg
    ports:
      - "8095:5000"
    volumes:
      - ./config/finch/wps.cfg:/wps.cfg
      # - data:/opt/birdhouse/var/lib
      - wps_outputs:/data/wpsoutputs
      - /tmp
    restart: always
    logging: *default-logging

  raven:
    image: pavics/raven:0.14.2
    container_name: raven
    ports:
      - "8096:9099"
    environment:
      PYWPS_CFG: /wps.cfg
    volumes:
      - ./config/raven/wps.cfg:/wps.cfg
      - wps_outputs:/data/wpsoutputs
      - /tmp
    restart: always
    logging: *default-logging

  hummingbird:
    image: pavics/hummingbird:0.5_dev
    container_name: hummingbird
    environment:
      HOSTNAME: $HOSTNAME
      HTTP_PORT: 8097
      HTTPS_PORT: 28097
      OUTPUT_PORT: 38097
    ports:
      - "8097:8097"
      - "28097:28097"
      - "38097:38097"
      - "48097:9001"
    volumes:
      - ./config/hummingbird/custom.cfg:/opt/birdhouse/src/hummingbird/custom.cfg
      - data:/opt/birdhouse/var/lib
      - wps_outputs:/opt/birdhouse/var/lib/pywps/outputs
    depends_on:
      - postgres
    restart: always
    logging: *default-logging

  solr:
    image: pavics/solr:5.2.1
    container_name: solr
    ports:
      - "8983:8983"
      - "48983:9001"
    volumes:
      - ${DATA_PERSIST_ROOT}/solr:/data
    restart: always
    logging: *default-logging

  ncwms2:
    image: pavics/ncwms2:2.0.4
    container_name: ncwms2
    ports:
      - "8080:8080"
      - "48080:9001"
    volumes:
      - ${DATA_PERSIST_ROOT}/datasets:/pavics-data
      - wps_outputs:/pavics-data/wps_outputs
      - ./config/ncwms2/custom.cfg:/opt/birdhouse/custom.cfg
      - ./config/ncwms2/server.xml:/opt/birdhouse/eggs/birdhousebuilder.recipe.tomcat-0.2.9-py2.7.egg/birdhousebuilder/recipe/tomcat/server.xml
    restart: always
    logging: *default-logging

  thredds:
    image: ${THREDDS_IMAGE}
    container_name: thredds
    ports:
      - "8083:8080"
    env_file:
      - ./config/thredds/thredds.env
    environment:
      # for reconstructing proper URL back to user when Thredds behind proxy
      # because Twitcher eats the "Host" http header set by Nginx
      PAVICS_FQDN_PUBLIC: $PAVICS_FQDN_PUBLIC
    volumes:
      - thredds_persistence:/usr/local/tomcat/content/thredds
      - ${DATA_PERSIST_ROOT}/datasets:/pavics-data
      - ${DATA_PERSIST_ROOT}/ncml:/pavics-ncml
      - wps_outputs:/pavics-data/wps_outputs
      - ./config/thredds/catalog.xml:/usr/local/tomcat/content/thredds/catalog.xml:ro
      - ./config/thredds/threddsConfig.xml:/usr/local/tomcat/content/thredds/threddsConfig.xml:ro
      - ./config/thredds/wmsConfig.xml:/usr/local/tomcat/content/thredds/wmsConfig.xml:ro
      - ./config/thredds/entrypointwrapper:/entrypointwrapper:ro
    entrypoint: /entrypointwrapper
    restart: always
    logging: *default-logging
    healthcheck:
      test:
        [
          "CMD",
          "curl",
          "--fail",
          "http://localhost:8080${TWITCHER_PROTECTED_PATH}/thredds/catalog.html",
        ]

  mongodb:
    image: mongo:3.4.0
    container_name: mongodb
    networks:
      - mongodb
    volumes:
      - ${DATA_PERSIST_ROOT}/mongodb_persist:/data/db
    # Mongodb crash with permission denied errors if the command is not overridden like this
    command: bash -c 'chown -R mongodb:mongodb /data && chmod -R 755 /data && mongod'
    restart: always
    logging: *default-logging

  postgis:
    image: pavics/postgis:2.2
    container_name: postgis
    restart: always
    logging: *default-logging

  portainer:
    image: portainer/portainer
    container_name: portainer
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /home/ubuntu/portainer:/data
    ports:
      - "9000:9000"
    restart: always
    logging: *default-logging

  magpie:
    image: pavics/magpie:${MAGPIE_VERSION}
    container_name: magpie
    ports:
      - "2001:2001"
    environment:
      TWITCHER_PROTECTED_URL: https://${PAVICS_FQDN_PUBLIC}${TWITCHER_PROTECTED_PATH}
      # target directories to allow loading multiple config files of corresponding category
      # each compose override should volume mount its files inside the matching directories
      # (note: DO NOT use 'MAGPIE_CONFIG_PATH' that would disable multi-config loading capability)
      MAGPIE_PROVIDERS_CONFIG_PATH: "/opt/local/src/magpie/config/providers"
      MAGPIE_PERMISSIONS_CONFIG_PATH: "/opt/local/src/magpie/config/permissions"
      MAGPIE_POSTGRES_HOST: postgres-magpie
      MAGPIE_PORT: 2001
      FORWARDED_ALLOW_IPS: "*"
    env_file:
      - ./config/postgres-magpie/credentials.env
    depends_on:
      - postgres-magpie
    links:
      - postgres-magpie
    volumes:
      - ./config/postgres-magpie/credentials.env:/opt/local/src/magpie/env/postgres.env
      - ./config/magpie/providers.cfg:/opt/local/src/magpie/config/providers/providers.cfg
      - ./config/magpie/permissions.cfg:/opt/local/src/magpie/config/permissions/permissions.cfg
      - ./config/magpie/magpie.ini:/opt/local/src/magpie/config/magpie.ini
    restart: always
    logging: *default-logging

  twitcher:
    image: pavics/twitcher:magpie-${MAGPIE_VERSION}
    container_name: twitcher
    ports:
      - "8000:8000"
    environment:
      # target directories to allow loading multiple config files of corresponding category
      # each compose override should volume mount its files inside the below directory
      # (note: DO NOT use 'MAGPIE_CONFIG_PATH' that would disable multi-config loading capability)
      # Only 'providers' sections are used to employ 'request/response hooks' with 'MagpieAdapter'.
      # Hooks are defined within Magpie config, but it is actually Twitcher proxy that runs them.
      # Other Magpie components are unknown and ignored by Twitcher itself.
      MAGPIE_PROVIDERS_CONFIG_PATH: "/opt/birdhouse/src/magpie/config"
    env_file:
      - ./config/postgres-magpie/credentials.env
    depends_on:
      - postgres-magpie
      - magpie
    links:
      - postgres-magpie
    volumes:
      - ./config/twitcher/twitcher.ini:/opt/birdhouse/src/twitcher/twitcher.ini
    command: "pserve /opt/birdhouse/src/twitcher/twitcher.ini"
    restart: always
    logging: *default-logging

  postgres-magpie:
    image: postgres:9.6
    container_name: postgres-magpie
    # ports:  # should not be exposed directly, enable 'optional-components/database-external-ports' as needed
    env_file:
      - ./config/postgres-magpie/credentials.env
    environment:
      PGDATA: /var/lib/postgresql/data/pgdata
    volumes:
      - ${MAGPIE_PERSIST_DIR}:/var/lib/postgresql/data/pgdata
      - ./config/postgres-magpie/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
    restart: always
    logging: *default-logging

  jupyterhub:
    image: pavics/jupyterhub:1.4.0-20210506
    container_name: jupyterhub
    hostname: jupyterhub
    ports:
      - "8800:8000"
    environment:
      DOCKER_NOTEBOOK_IMAGES: ${DOCKER_NOTEBOOK_IMAGES}
      JUPYTERHUB_IMAGE_SELECTION_NAMES: ${JUPYTERHUB_IMAGE_SELECTION_NAMES}
      DOCKER_NETWORK_NAME: jupyterhub_network
      JUPYTERHUB_USER_DATA_DIR: ${JUPYTERHUB_USER_DATA_DIR}
      JUPYTERHUB_ADMIN_USERS: ${JUPYTERHUB_ADMIN_USERS}
      JUPYTER_DEMO_USER: ${JUPYTER_DEMO_USER}
      JUPYTER_DEMO_USER_MEM_LIMIT: ${JUPYTER_DEMO_USER_MEM_LIMIT}
      JUPYTER_DEMO_USER_CPU_LIMIT: ${JUPYTER_DEMO_USER_CPU_LIMIT}
      JUPYTER_GOOGLE_DRIVE_SETTINGS: ${JUPYTER_GOOGLE_DRIVE_SETTINGS}
      JUPYTERHUB_README: ${JUPYTERHUB_README}
      MOUNT_IMAGE_SPECIFIC_NOTEBOOKS: ${MOUNT_IMAGE_SPECIFIC_NOTEBOOKS}
    volumes:
      - ./config/jupyterhub/jupyterhub_config.py:/srv/jupyterhub/jupyterhub_config.py:ro
      - ./config/jupyterhub/custom_templates:/custom_templates:ro
      - ${JUPYTERHUB_USER_DATA_DIR}:${JUPYTERHUB_USER_DATA_DIR}
      - jupyterhub_data_persistence:/persist:rw
      - /var/run/docker.sock:/var/run/docker.sock:rw
    links:
      - magpie
    networks:
    # ensure Hub and Notebook servers are on the same network 'jupyterhub_network'
    # the Hub and the rest of the stack are on network 'default'
      - default
      - jupyterhub_network
    restart: always
    logging: *default-logging

# need external network so the folder name is not prefixed to network name
networks:
  mongodb: {}
  jupyterhub_network:
    external:
      name: "jupyterhub_network"

volumes:
  data: {}
  wps_outputs: {}
  jupyterhub_data_persistence:
    external:
      name: jupyterhub_data_persistence
  thredds_persistence:
    external:
      name: thredds_persistence

# vi: tabstop=8 expandtab shiftwidth=2 softtabstop=2
