Turns out, it was a stupid mistake (hard to spot) because there error messages is either not there or they do not repeat in the console output. The problem was double quoutes here:
      - BITSHARESD_ES_NODE_URL="http://elasticsearch:9200/"
Here is a working docker-compose.yml
version: '3'
services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:6.2.4
    container_name: elasticsearch
    environment:
      - ELASTIC_PASSWORD=secret
      - cluster.name=docker-cluster
      - discovery.type=single-node
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    networks:
      stack:
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - esdata:/usr/share/elasticsearch/data
    ports:
      - 9200:9200
  fullnode:
    image: bitshares/bitshares-core:latest
    container_name: fullnode
    environment:
      - BITSHARESD_PLUGINS=witness elasticsearch market_history
      - BITSHARESD_ES_NODE_URL=http://elasticsearch:9200/
      - BITSHARESD_RPC_ENDPOINT=0.0.0.0:8090
      - BITSHARESD_P2P_ENDPOINT=0.0.0.0:9090
      - BITSHARESD_WITNESS_ID="1.6.122"
      - BITSHARESD_PRIVATE_KEY=["BTS...","5..."]
    networks:
      stack:
    ports:
      - 9090:9090
      - 8090:8090
    volumes:
      - fullnode:/var/lib/bitshares
    depends_on:
      - elasticsearch
volumes:
  fullnode:
  esdata:
networks:
  stack:
Next question:
Is it possible to run multiple witness_nodes, that's sharing the same ElasticSearch or will it cause conflicts such as double inserts / race conditions or anything else like that? Basically, I'd like to host multiple witness_nodes across the globe to ensure high availability and low latency.