def generate_docker_compose(self, vespa_version: str):
        """
        Create docker compose file for multinode vespa with 3 config nodes.
        Generates (number_of_replicas + 1) * number_of shards content nodes.
        """
        services = {}

        logger.info(
            f"Creating `docker-compose.yml` with {self.number_of_shards} shards and {self.number_of_replicas} replicas.")

        BASE_CONFIG_PORT_A = 19071  # configserver (deploy here)
        BASE_SLOBROK_PORT = 19100  # slobrok
        BASE_CLUSTER_CONTROLLER_PORT = 19050  # cluster-controller
        BASE_ZOOKEEPER_PORT = 2181  # zookeeper
        BASE_METRICS_PROXY_PORT = 20092  # metrics-proxy (every node has it)

        BASE_API_PORT_A = 8080  # document/query API
        BASE_DEBUG_PORT = 5005  # debugging port

        BASE_CONTENT_PORT_A = 19107

        TOTAL_CONTENT_NODES = (self.number_of_replicas + 1) * self.number_of_shards
        TOTAL_API_NODES = max(MINIMUM_API_NODES, math.ceil(TOTAL_CONTENT_NODES / 4))
        logger.info(f"Total content nodes: {TOTAL_CONTENT_NODES}, Total API nodes: {TOTAL_API_NODES}")

        # Config Nodes (3)
        nodes_created = 0
        urls_to_health_check = []  # List all API and content node URLs here
        TOTAL_CONFIG_NODES = 3
        for config_node in range(TOTAL_CONFIG_NODES):
            services[f'config-{config_node}'] = {
                'image': f"vespaengine/vespa:{vespa_version or 'latest'}",
                'container_name': f'config-{config_node}',
                'hostname': f'config-{config_node}.vespanet',
                'environment': {
                    'VESPA_CONFIGSERVERS': 'config-0.vespanet,config-1.vespanet,config-2.vespanet',
                    'VESPA_CONFIGSERVER_JVMARGS': '-Xms32M -Xmx128M',
                    'VESPA_CONFIGPROXY_JVMARGS': '-Xms32M -Xmx128M'
                },
                'networks': [
                    'vespanet'
                ],
                'ports': [
                    f'{BASE_CONFIG_PORT_A + config_node}:19071',
                    f'{BASE_SLOBROK_PORT + config_node}:19100',
                    f'{BASE_CLUSTER_CONTROLLER_PORT + config_node}:19050',
                    f'{BASE_ZOOKEEPER_PORT + config_node}:2181',
                    f'{BASE_METRICS_PROXY_PORT + nodes_created}:19092'
                ],
                'command': 'configserver,services',
                'healthcheck': {
                    'test': "curl http://localhost:19071/state/v1/health",
                    'timeout': '10s',
                    'retries': 3,
                    'start_period': '40s'
                }
            }
            # Add additional ports to adminserver
            if config_node == 0:
                services[f'config-{config_node}']['ports'].append('19098:19098')

            nodes_created += 1

        # API Nodes
        for api_node in range(TOTAL_API_NODES):
            services[f'api-{api_node}'] = {
                'image': f"vespaengine/vespa:{vespa_version or 'latest'}",
                'container_name': f'api-{api_node}',
                'hostname': f'api-{api_node}.vespanet',
                'environment': [
                    'VESPA_CONFIGSERVERS=config-0.vespanet,config-1.vespanet,config-2.vespanet'
                ],
                'networks': [
                    'vespanet'
                ],
                'ports': [
                    f'{BASE_API_PORT_A + api_node}:8080',
                    f'{BASE_DEBUG_PORT + api_node}:5005',
                    f'{BASE_METRICS_PROXY_PORT + nodes_created}:19092'
                ],
                'command': 'services',
                'depends_on': {
                    'config-0': {'condition': 'service_healthy'},
                    'config-1': {'condition': 'service_healthy'},
                    'config-2': {'condition': 'service_healthy'}
                }
            }
            urls_to_health_check.append(f"http://localhost:{BASE_API_PORT_A + api_node}/state/v1/health")
            nodes_created += 1

        # Content Nodes
        i = 0  # counter of content nodes generated
        for group in range(self.number_of_replicas + 1):
            for shard in range(self.number_of_shards):
                node_name = f'content-{group}-{shard}'
                host_ports = [
                    f'{BASE_CONTENT_PORT_A + i}:19107',
                    f'{BASE_METRICS_PROXY_PORT + nodes_created}:19092'
                ]
                services[node_name] = {
                    'image': f'vespaengine/vespa:{vespa_version or "latest"}',
                    'container_name': node_name,
                    'hostname': f'{node_name}.vespanet',
                    'environment': [
                        'VESPA_CONFIGSERVERS=config-0.vespanet,config-1.vespanet,config-2.vespanet'
                    ],
                    'networks': [
                        'vespanet'
                    ],
                    'ports': host_ports,
                    'command': 'services',
                    'depends_on': {
                        'config-0': {'condition': 'service_healthy'},
                        'config-1': {'condition': 'service_healthy'},
                        'config-2': {'condition': 'service_healthy'}
                    }
                }
                urls_to_health_check.append(f"http://localhost:{BASE_CONTENT_PORT_A + i}/state/v1/health")
                i += 1
                nodes_created += 1

        # Define Networks
        networks = {
            'vespanet': {
                'driver': 'bridge'
            }
        }

        # Combine into final docker-compose structure
        docker_compose = {
            'services': services,
            'networks': networks
        }

        with open('docker-compose.yml', 'w') as f:
            yaml.dump(docker_compose, f, sort_keys=False)
        logger.info(f"Generated `docker-compose.yml` successfully.")

        logger.info("Health check URLs:")
        for url in urls_to_health_check:
            logger.info(url)

        Create docker compose file for multinode vespa with 3 config nodes.
        Generates (number_of_replicas + 1) * number_of shards content nodes.
        
scripts/vespa_local/vespa_local.py